git ssb

0+

Zach! / local-gossip-zine



Tree: 1721af4ce8e5508c633c4f6b2731dbf3e6d6f66b

Files: 1721af4ce8e5508c633c4f6b2731dbf3e6d6f66b / gossip-zine.org

30716 bytesRaw
1#+NAME: Local Gossip Zine
2#+AUTHOR: Zach Mandeville
3#+EMAIL: webmaster@coolguy.website
4
5* Introduction
6
7 This is a hypertextual origami frog of a write-up for a scrycast zine in the chorus. This page goes over the inspirations for the zine, what we trying to do and where we going, and includes the code for the zine itself. Our aim is to help teach how to build one of these zines yrself using the tools we like, and to give the reason for whyt he code be the way it is.
8
9 BUT! this here page also transforms directly into a scrycast zine. just run the scripts in your setup heading, type the magic keys, and watch the whole thing blossom.
10
11* Intentions
12
13 Put simply this will be a zine that holds an audio player that will play the mp3 of our scrycast. The zine template is meant to be easy to reproduce but also, importantly, easy to collaborate on. I want the file structure to be easy enough to follow on something like git-ssb or gitlab, so people can put in their own bios or transcriptions or anything else.
14
15 My dream is for Dan or Glyph to say, "New podcast coming up. the link for it is here: feel free to add a trasncription or, if yr one of the peers, yr bio and image.
16
17 In the future, I wanna get even more ridiculous and have minute by minute annotations possible. So as yr listening to the show, a small note pops up with additional info. These notes, then, can be collaborated upon by others.
18
19 The site is a pleasant and minimal looking player but holds a pleasantly surprising amount of functionality.
20*** [40%]Cool Parts:
21 - [X] The Site details are all taken from a text file in the dat folder. In this way, you can just fork and replace the file and you'll have a new dat site.
22 - [ ] The 'audio' part of the info.txt file is a link to the url which can be local or remote. In this way, people don't //have// to host the audio if they don't want to.
23 - [X] There's also just a 'show notes' section you can use to put in add'l details.
24 - [ ] The file includes 'annotations' that are named after specific minute'second counters. Then, when it hits that part of the track the specific annotation shows up on the screen (like pop-up video).
25 - [ ] The bottom of the screen shows the show-notes plus the annotations (if they there) plus a button for the full transcript (if available.) When you click on either you get a bunch more details. (again, taken from a text file.)
26
27* Setup
28** Download Font
29 We only want ttf and woff, so we unzip and delete the rest!
30 #+NAME: Download Font
31 #+BEGIN_SRC shell :results output verbatim drawer :dir ./
32 mkdir -p aesthetic/fonts/mononoki
33 wget -O aesthetic/fonts/mononoki/mononoki.zip 'https://github.com/madmalik/mononoki/releases/download/1.2/mononoki.zip'
34 cd aesthetic/fonts/mononoki
35 unzip mononoki.zip
36 rm *.eot
37 rm *.woff2
38 rm *.zip
39 tree
40 #+END_SRC
41
42 #+RESULTS: Download Font
43 :RESULTS:
44 Archive: mononoki.zip
45 inflating: mononoki-Bold.eot
46 inflating: mononoki-Bold.ttf
47 inflating: mononoki-Bold.woff
48 inflating: mononoki-Bold.woff2
49 inflating: mononoki-BoldItalic.eot
50 inflating: mononoki-BoldItalic.ttf
51 inflating: mononoki-BoldItalic.woff
52 inflating: mononoki-BoldItalic.woff2
53 inflating: mononoki-Italic.eot
54 inflating: mononoki-Italic.ttf
55 inflating: mononoki-Italic.woff
56 inflating: mononoki-Italic.woff2
57 inflating: mononoki-Regular.eot
58 inflating: mononoki-Regular.ttf
59 inflating: mononoki-Regular.woff
60 inflating: mononoki-Regular.woff2
61 .
62 ├── mononoki-Bold.ttf
63 ├── mononoki-Bold.woff
64 ├── mononoki-BoldItalic.ttf
65 ├── mononoki-BoldItalic.woff
66 ├── mononoki-Italic.ttf
67 ├── mononoki-Italic.woff
68 ├── mononoki-Regular.ttf
69 └── mononoki-Regular.woff
70
71 0 directories, 8 files
72 :END:
73
74* Parts
75** Bedrock
76*** languages
77 This template is made with:
78 -[[https://choo.io][ Choo]]
79 - [[https://github.com/jondashkyle/smarkt][smarkt]]
80 - html
81 - css
82 - javascript
83 - love
84
85 Choo handles the front-end modular design and is chosen cos it's small, easy to reason with, and cute.
86
87 Smarkt is 'hyper-readable markup'. It's a way of writing content for pages that looks super clean, but then parses nicely into JSON. So what we want is to have files that people can update from the backend(or through github) that gets translated magichooly into a well-designed page!
88
89*** File Structure
90 The overall structure looks like so:
91 #+BEGIN_SRC sh :dir ./ :results output list
92 tree -I 'node_modules' .
93 #+END_SRC
94
95 #+RESULTS:
96 #+begin_example
97 - .
98 - ├── bundle.js
99 - ├── dat.json
100 - ├── gossip-zine.org
101 - ├── index.html
102 - ├── index.js
103 - ├── package-lock.json
104 - ├── package.json
105 - ├── show
106 - │   ├── bios
107 - │   │   ├── angelica-blevins.txt
108 - │   │   └── zach.txt
109 - │   ├── episode.txt
110 - │   ├── show-audio.mp3
111 - │   ├── show.txt
112 - │   └── solarpunk-couple.jpg
113 - ├── stores
114 - │   └── core.js
115 - └── views
116 - ├── audioPlayer.js
117 - ├── cast.js
118 - ├── episode.js
119 - ├── header.js
120 - ├── peerList.js
121 - ├── title.js
122 - └── transcription.js
123 - 4 directories, 21 files
124 #+end_example
125
126**** Initiatory Files
127 The basic choo app is made up of an index.html page that has a bundle.js page linekd into it. This bundle speaks of an index.js page, and it is from that index.js page that the rest of the site blossoms. The rest of the folders are helpful conventions, intended to make the site easy to reason about.
128
129 The show folder holds text files, mp3's, and pictures. This is the main content and, importantly, requires no coding. A person should be able to edit a text file knowing nothing but how to click an edit pencil and use a keyboard. This is actually a lot harder than it'd appear: to make the rest of the template sturdy enough that these files can be //anything.// and a person can't accidentally break the zine.
130 #+NAME: index.js
131 #+BEGIN_SRC js js :tangle index.js
132 const choo = require('choo')
133 const devtools = require('choo-devtools')
134
135 const cast = require('./views/cast')
136
137 // Initialize choo and bring along it's console helper.
138 var app = choo()
139 app.use(devtools())
140
141 // Our Stores
142 app.use(require('./stores/core'))
143
144 // Our Routes
145 app.route('/', cast)
146
147 //Plant that seed.
148 app.mount('body')
149 #+END_SRC
150
151 #+NAME: index.html
152 #+BEGIN_SRC html :tangle index.html
153 <!doctype html>
154 <html>
155 <head>
156 <title>Scrycast!</title>
157 <link rel='stylesheet' href='aesthetic/colors-and-fonts.css' type='text/css'>
158 <link rel='stylesheet' href='aesthetic/main.css' type='text/css'>
159 </head>
160 <body>
161 <h1>Loading...</h1>
162 <script src='bundle.js' type='application/javascript'></script>
163 </body>
164 </html>
165 #+END_SRC
166
167**** Text Files for Content
168 We are using Smarkt to handle the text files. It's awesome because it makes things super readable-- you have a name, a colon, some text and separate each part with four dashes (----). But it is also particular with indentations, and if you try to fit too much the indentations will be off somewhere and you'll screw up the parsing.
169
170 The choice I made was to break up the show into different text files, each organized around some concern. So there's the basic show info--title, license, description--then there's general info about the episode, and then there's bios for all the guests. I originally had the bios included in the episode file, but it became super hard to read and work on without knowing how smarkt works---and I dont' want that.
171
172 I also want the files to be easy enough to name. So the show info shoudl probably be changed to just 'info.txt', as show and episode seem too similar. The bios should be able to be any name...they are in the bios folder, which connects them, and they have a name portion in the file. As long as both of those are true it shouldn't matter if someone puts 'angelica.txt' 'angblev.txt' or 'ab.txt'. They all point to Angelica.
173**** Choo Style Zine Template
174 Choo lets you build out a whole page in javascript. I'm still kinda conflicted on having this site be javascript driven. Static pages would be faster and allow folks who have javascript turned off to still be able to see our zines. At the same time, there isn't a way to turn off js within beaker, so it's really just folks who are intentionally using a browser that can read dat but can't take js---and i think that's a niche market that doesn't represent disenfranchised people.
175
176 Also, being JS driven lets us do the magic of 'update a text file and it's auto-updated in the zine'. It lets you not worry about the code and still be able to make stuff your own. To do this with a static site would require you to 'rebuild' the page after every chagne. This would require the zinester to know how to install npm and run build scripts. This is a great idea in the future, but shouldn't be the beginning requirement.
177
178 Lastly, I think learning code is important and I see these zines as serving two purposes: sharing your work as easily and quickly as possible, and introducing you to the world of webmastering and code. If the site is just html and css, then the zinester is learning declartive languages only. In this template setup they can add their own content and style their own things--but as soon as they want to change the struture and behavior of the zine then we introduce them to the terminal, npm, and a super accessible javascript framework.
179
180 Choo works with the notion of Stores and Views. Stores hold the data and behavior of the zine. It's kinda the brains of the template. Views hold the different presentational parts--the components or parts of the page. We could name these whatever we want (and this is something I play with in other zine templates), but since this one is intended to be far more collaborative I wanted these folders to match the Choo documentation.
181
182** The Show Files
183 The real heart of the zine. These hold all the various information about the specific scrycast. They are intended so that someone can fork a zine and, without any code knowledge, be able to make it their own with their own episode simply by editing these files.
184
185 I am riding a conceptual line between 'many files' or 'one big file that could get kinda complicated. I want to include all the information on the existing template though.
186*** info.txt
187 Deals with the basic information about the show
188 #+BEGIN_SRC org :tangle show/info.txt
189 scrycast: The Local Gossip
190 ----
191 tagline: an experiment in decentralized, collaborative audio shows ~ scrycasting
192 ----
193 notes: Who is responsible for producing The Local Gossip? You are! Localhosts throughout The Chorus are collaborating to deepen community relationships while exploring stories, weaving tales and finding new metaphors to understand the terrains and potentials of cypherspace from their subjective vantage points. If you want to contribute to this particular zine, you can do so here! https://gitlab.com/dat-zines/scrycast-zine-template
194 ----
195 license: All materials are free to share Creative Commons (BY-NC-SA 3.0) but happiest in cypherspace.
196 ----
197 contribute:
198 gitlab: https://gitlab.com/dat-zines/scrycast-template
199 git-ssb:
200
201
202
203 #+END_SRC
204*** Episode.txt
205 Handles information about the specific episode, its description, hosts, dates, and so on. the ssbKey is a bit tricky cos it neeeeeeds to be in quotes other wise it isn't parsed correctly.
206 #+BEGIN_SRC org :tangle show/episode.txt
207 title: solarpunk, travel, and metaphors
208 ----
209 number: 02
210 ----
211 seed date: 14 September 2018
212 ----
213 localHost:
214 name: Dan Hassan
215 ssbKey: '@NeB4q4Hy9IiMxs5L08oevEhivxW+/aDu/s/0SkNayi0=.ed25519'
216 ----
217 audio: the-local-gossip-episode-2.opus
218 ----
219 image:
220 src: solarpunk-couple.jpg
221 caption: 'The two peers at the Solarpunk Magic Computer Club in Queens'
222 ----
223 peers:
224 - name: Angelica Blevins
225 ssbKey: '@eANNuLfzX/9rlGODXHYV8WJb+zw2h+d7YsT4vpYPvD0=.ed25519'
226 - name: Zach Mandeville
227 ssbKey: '@ZqH7Mctu/7DNInxuwl12ECjfrAKUX2tBLq1rOldNhg0=.ed25519'
228 #+END_SRC
229*** Bios
230 I wanted to be able to have links and nice things for each of the guests, while keeping freedom open for how the links are rpresented (like maybe none at all), and for them to be optional as. So one thing we could do is have a bios/ folder and put in whatever bios we want per person. So for example:
231
232 #+NAME: Angelica Bio
233 #+BEGIN_SRC org :tangle ./show/bios/angelica-blevins.txt
234 name: Angelica Blevins
235 ----
236 bio:
237
238 Cartoonist, zinester, yogi, and kitchen witch. Angelica has provided a unique visual element to our scuttlepelago through her ssb emojis and the art she's shared throughout the Chorus.
239
240 You can find an example of her yoga zines here: [Kundalini Winter Workshop](dat://81f40a285e2e7706cae59db182a4f4753df24f9c033cd1aa67e743a5f52f9008/). And check out her homepage at [angblev.com](https://angblev.com)
241
242 #+END_SRC
243
244 #+NAME: Zach Bio
245 #+BEGIN_SRC org :tangle ./show/bios/zach.txt
246 name: Zach Mandeville
247 ----
248 bio:
249 Writer, Coder, Barber, Tarotologist, and potential friend. In this episode, Dan dubbed him Scuttlebutt's poet laureate, which made Zach make a weird mouth sound and his face turned such a deep red you can hear it through yr speakers.
250
251 Here's some more of Zach's work in the Chorus:
252 - [The Future Will be Technical](dat://coolguy.website/writing/the-future-will-be-technical/)
253 - [A Praise Chorus](dat://2295a89c2cdfb57ed91b135608627119199d5d834fbaede70a8713b2cedf6fe1/)
254 - [Dat Zine Library](dat://coolguy.website/projects/dat-zine-library/)
255 - [His Home online](dat://coolguy.website)
256
257 #+END_SRC
258
259** Stores
260*** Core
261 :PROPERTIES:
262 :header-args: :noweb yes
263 :END:
264 Our core store brings in all the show files and adds them to state, so they can be displayed by our components.
265
266 If we ever got to a spot where we were trying to do things in this template /beyond/ bring in show files, we could create another store for that. In our index.js field we just need to do an ~app.use(store)~ to both and they'll be added to our zine's state.
267
268 #+NAME: core store
269 #+BEGIN_SRC js :tangle stores/core.js
270 const smarkt = require('smarkt')
271 const _ = require('lodash')
272 var archive = new DatArchive(window.location)
273
274 module.exports = (state, emitter) => {
275 state.info = {}
276 state.bios = []
277 state.episode = {}
278
279 emitter.on('DOMContentLoaded', () => {
280 grabTxtsFromDir('show')
281 checkForBios('show/bios')
282 })
283
284 function grabTxtsFromDir (dir) {
285 archive.readdir(dir)
286 .then(files => {
287 var txts = onlyTxts(files)
288 emitter.emit('Texts Found', txts)
289 })
290 }
291
292 emitter.on('Texts Found', (texts) => {
293 for (var text of texts) {
294 emitter.emit('Map Text To State', text)
295 }
296 })
297 emitter.on('Bios Found!', () => {
298 archive.readdir('show/bios')
299 .then(files => {
300 var bios = onlyTxts(files)
301 for (var bio of bios) {
302 mapBioToState(bio)
303 }
304 })
305 })
306
307 emitter.on('Map Text To State', (text) => {
308 mapTextToState(text)
309 })
310
311 function mapTextToState (text) {
312 var textName = text.split('.txt')[0]
313 archive.readFile(`show/${text}`)
314 .then((contents) => {
315 state[textName] = smarkt.parse(contents)
316 emitter.emit('render')
317 })
318 }
319
320
321 function checkForBios (dir) {
322 archive.stat(dir)
323 .then(success => emitter.emit('Bios Found!'))
324 .catch(data => emitter.emit('no bio'))
325 }
326
327 function mapBioToState (bio) {
328 archive.readFile(`show/bios/${bio}`)
329 .then(content => {
330 var bioJSON = smarkt.parse(content)
331 state.bios = [...state.bios, bioJSON]
332 emitter.emit('render')
333 })
334 }
335
336 function onlyTxts(dir) {
337 return dir.filter(file => file.includes('.txt'))
338 }
339 }
340 #+END_SRC
341 #+RESULTS: core store
342
343 This will read our different text files, if they there, and make them available to our components!
344** Views (or Components)
345 :PROPERTIES:
346 :header-args: :dir views
347 :END:
348*** Main component (the Cast)
349
350 This is a view that holds all the others inside of it. Essentially the body of the main route.
351 each subcomponent is added in using template literal strings, like so: ~${componentName(state, emit)}~
352
353 #+NAME: cast view
354 #+BEGIN_SRC js :tangle views/cast.js
355 const html = require('nanohtml')
356
357 const Title = require('./title')
358 const Episode = require('./episode')
359 const Transcription = require('./transcription')
360
361
362 module.exports = (state, emit) => {
363 return html`
364 <body>
365 <div class='wrapper'>
366 ${Title(state,emit)}
367 ${Episode(state, emit)}
368 ${Transcription(state, emit)}
369 </div>
370 </body>
371 `
372 }
373 #+END_SRC
374
375 #+NAME: Main Component Styling
376 #+BEGIN_SRC css :tangle no
377 .wrapper{
378 padding: 1em;
379 }
380
381 #+END_SRC
382
383 These are small fragments of html that make up our page, and can be dynamic (pulling from the state of the app to decide what to display.)
384
385*** Show title.
386 :PROPERTIES:
387 :header-args: :tangle ./views/title.js
388 :END:
389 I'm basing this all on the original site, and so we want to have the title and its tagline and a little note to our readers.
390
391 #+NAME: title
392 #+BEGIN_SRC js
393 const html = require('nanohtml')
394 const u = require('../utilities')
395
396 module.exports = (state, emit) => {
397 if (u.hasContent(state.info)) {
398 var info = state.info
399 return html`
400 <div id='Title'>
401 <h1>${info.scrycast}</h1>
402 <h2>${info.tagline}</h2>
403 <p>${info.notes}</p>
404 </div>
405 `
406 }
407 }
408 #+END_SRC
409
410 #+NAME: Title Styling
411 #+BEGIN_SRC css :tangle no
412 /* Title!
413 The scrycast name, tagline, and description.
414 ,*/
415
416 #Title {
417 width: 80%;
418 margin-bottom: 0.5em;
419
420 }
421
422 #Title h1{
423 margin-bottom: 0;
424 }
425
426
427 #Title h2{
428 margin-top: 0.25em;
429 font-style: italic;
430 }
431
432
433 #+END_SRC
434*** Episode
435 :PROPERTIES:
436 :header-args: :noweb yes :tangle ./views/episode.js
437 :END:
438
439 I was going to just pilfer the code from the original cast, but it didn't fully match my style of zine design. There was a lot of inline style, while I want to keep a fully external stylesheet. This is so people do not need to run npm or look through the html code to be able to adjust the style. I want them to have an easy variables page for most things, and clearly laid out CSS for the rest.
440
441 It also used h1 tags, when I want there to only be a single h1 tag on the page. This is to help with accessibility, and the screen readers parsing over the page.
442
443 So I'll do a redesign with these intentions in mind.
444
445 #+NAME: episode
446 #+BEGIN_SRC js
447 const html = require('nanohtml')
448 const PeerList = require('./peerList.js')
449 const AudioPlayer = require('./audioPlayer')
450 const u = require('../utilities')
451
452 module.exports = (state, emit) => {
453 if (u.hasContent(state.episode)) {
454 var episode = state.episode
455 return html`
456 <section id='Episode'>
457 <h2>Episode ${episode.number}: <span id='episode-title'>${episode.title}</span></h2>
458 ${AudioPlayer(episode.audio)}
459 <p>Initial Seeding Date: ${episode['seed date']}</p>
460 <img src='show/${episode.image.src}' alt='${episode.image.caption}' width='800px' />
461 <p>${episode.image.caption}</p>
462 <h3 id='localHost'>Localhost</h3>
463 <p>${episode.localHost.name} // ( ${episode.localHost.ssbKey} )</p>
464 <h3 id='guests'>Guests</h3>
465 <ul>
466 ${PeerList(state)}
467 </ul>
468 </section>
469 `
470 }
471 }
472 #+END_SRC
473
474 #+NAME: Episode Styling
475 #+BEGIN_SRC css :tangle no
476 #Episode {
477 background: var(--secondary-bg);
478 padding: 1em;
479 width: 90%;
480 margin: auto;
481 }
482
483 #+END_SRC
484*** Audio Player
485 :PROPERTIES:
486 :header-args: :noweb yes :tangle ./views/audioPlayer.js
487 :END:
488
489 I'ma just use the one from destroy with science and the original scrycast page. I feel it is now the aesthetic choice for chorus audio.
490
491 #+NAME: audioPlayer
492 #+BEGIN_SRC js
493 const html = require('nanohtml')
494
495 module.exports = (audio) => {
496 return html`
497 <audio class='Player' style='width: 400px' controls src='show/${audio}'></audio>
498 `
499 }
500
501
502 #+END_SRC
503
504*** Peer List
505 :PROPERTIES:
506 :header-args: :noweb yes :tangle ./views/peerList.js
507 :END:
508 For each episode there'll be, likely, one to many peers. We don't know how many and so they get added to our episode sheet as an array.
509
510We'll make a component that displays a stylable list element for each peer.
511
512We wanted to not be bound to bios or links or contact info or anything like that. a peer may not wanna give it, or it may not be ready by the time the episode comes out. And so, we will load up the peers and then check if they have bio files. If so, we'll add the bio to their card.list.
513
514#+NAME: PeerList
515#+BEGIN_SRC js
516 const html = require('nanohtml')
517 const md = require('markdown-it')()
518 const raw = require('nanohtml/raw')
519
520 const u = require('../utilities')
521 const displayBioIfAvailable = require('./peerBio')
522
523 module.exports = function peerList (state) {
524 if(u.hasContent(state.episode.peers)) {
525 const peers = state.episode.peers
526 return peers.map(peer => {
527 return html`
528 <li class='peerCard'>
529 <h4>${peer.name} // (${peer.ssbKey}</h4>
530 ${checkForBio(state, peer)}
531 </li>
532 `
533 })
534 }
535
536 function checkForBio (state, peer) {
537 if (u.hasContent(state.bios)) {
538 return displayBioIfAvailable(state.bios, peer)
539 }
540 }
541 }
542
543#+END_SRC
544
545*** Peer Bio
546 :PROPERTIES:
547 :header-args: :noweb yes :tangle ./views/peerBio.js
548 :END:
549#+NAME: PeerBio
550#+BEGIN_SRC js
551 const html = require('nanohtml')
552 const md = require('markdown-it')()
553 const raw = require('nanohtml/raw')
554
555 const u = require('../utilities')
556
557 module.exports = (bios, peer) => {
558 if(hasBio(bios, peer)) {
559 var bio = grabBio(bios, peer)
560 return html`
561 ${raw(md.render(bio.bio))}
562 `
563 }
564
565 function hasBio (bios, peer) {
566 return bios.some(bio => {
567 var bioName = bio.name.toLowerCase()
568 var peerName = peer.name.toLowerCase()
569 return peerName === bioName
570 })
571 }
572
573 function grabBio (bios, peer) {
574 return bios.find(bio => {
575 var bioName = bio.name.toLowerCase()
576 var peerName = peer.name.toLowerCase()
577 return peerName === bioName
578 })
579 }
580 }
581
582#+END_SRC
583
584#+RESULTS: PeerBio
585
586*** Transcription
587 :PROPERTIES:
588 :header-args: :noweb yes :tangle ./views/transcription.js
589 :END:
590
591 This is the coolest part to me. By making our zine in this way, we can have people contribute without needing to give them access to the dat or work with some multi-person CMS or whatev's. Instead, if we are missing a file we can have the site render "this hasn't been transcribed yet, but we'd love it to be. If you'd like to help, send us a pull request at...". So then people could just upload a markdown transcript to the git page, we'd pull it in, and the scrycast page gets updated. Beauty!!
592
593I know we won't have a trasncript from this one, so I'ma just fake it for right now.
594#+NAME: Transcription
595#+BEGIN_SRC js
596 const html = require('nanohtml')
597
598 module.exports = (state, emit) => {
599 if (state.transcript) {
600 return html`
601 <div>
602 <h2>Transcription</h2>
603 ${state.transript}
604 </div>
605 `
606 } else {
607 return html`
608 <div>
609 <h2>Transcription</h2>
610 <p>This show hasn't been transcribed yet, but we'd love it to be! If you'd like to help with this, add a transcript file to our show folder on our [gitlab page](https://gitlab.com/zachmandeville/scrycast-zine)</p>
611 </div>
612 `
613 }
614 }
615
616#+END_SRC
617
618#+RESULTS: Transcription
619** Utilities
620 :PROPERTIES:
621 :header-args: :noweb yes :tangle ./utilities/index.js
622 :END:
623 There are a couple general tricks I find myself always using, that could be shortened into functions. In some cases lodash helps solve these common problems, and when that doesn't work I call upon my own custom made utils! All are stored in ~utilities/index.js~ as there shouldn't be that many of them.
624*** Check if State has content
625 When a component renders, it renders the stuff given to it by the state. If that bit of state is empty, then an error is thrown...but it's not useful error (saying 'such and such is not a function' or some such.) What would be better is to tell the component to only render if it has content to show. So this function checks to make sure that part of state exists and that it has something inside of it.
626#+NAME: State Has Content
627#+BEGIN_SRC js
628 function hasContent (state) {
629 return state !== null && Object.keys(state).length !== 0
630 }
631#+END_SRC
632
633*** Export them Modules
634 #+NAME: modules.export
635 #+BEGIN_SRC js
636 module.exports = {hasContent}
637
638 #+END_SRC
639
640
641
642
643
644 #+NAME:
645** Aesthetic
646 This contains the stylesheets for the whole app. I think it is best to keep it to 2, maybe 3, stylesheets. One is just color and font variables and the other is the main stylesheet.
647
648Each concern in the zine is commented to its own part of the stylesheet so its easier to find, but I wanted people to be able to look at one long scroll of things and learn from them. This is part of my path to making the template yr own by getting into the code. Try changing some colors, and when that goes well try changing the styles themselves.
649
650I also wanna move away from adding a bunch of unnecessary classes or divs. I would like the finished page to be as semantic as possible for accessibility, and for the classes to be as minimal as possible for maintenance. There's so much you can do with pseudoelements and css selectors that we should just use those!
651
652I've included style sections in each of the components up above, so its easier to manage the style when you looking at/working with a single component--but they all tangle into a single file in the end. The big default stuff I'm including here.
653*** Colors and Fonts
654 :PROPERTIES:
655 :header-args: :noweb yes :tangle ./aesthetic/colors-and-fonts.css
656 :END:
657 #+NAME: Colors
658 #+BEGIN_SRC css
659 /*
660 The Colors! Change any of the values here to whichever color you like.
661 bg stands for 'background', 'text' stands for the color of the text.
662 So 'main-bg' would be the body background
663 and 'main-text' would be the default color of the text on the site.
664 ,*/
665 :root {
666 --main-bg: #E8FDF5;
667 --secondary-bg: #FBF1A9;
668 --main-text: #A463F2;
669 }
670 #+END_SRC
671
672 #+NAME: Fonts
673 #+BEGIN_SRC css
674 /*
675 Fonts! You can change the font-family being used or the default text of the site!
676 ,*/
677 :root {
678 --default-size: 18px;
679 --primary-font: mononoki;
680 }
681 /* This is Code added to get custom fonts working.
682 Add yr own here if you wanna use a custom font
683 --------------------------------------------------*/
684
685
686 @font-face {
687 font-family: 'mononoki';
688 src: url('./fonts/mononoki/mononoki-Regular.woff') format('woff'), /* Pretty Modern Browsers */
689 font-weight: normal;
690 font-style: normal;
691 }
692
693 @font-face {
694 font-family: 'mononoki';
695 src: url('./fonts/mononoki/mononoki-Bold.woff') format('woff'), /* Pretty Modern Browsers */
696 url('./fonts/mononoki/mononoki-Bold.ttf') format('truetype'); /* Safari, Android, iOS */
697 font-weight: bold;
698 font-style: normal;
699 }
700
701 @font-face {
702 font-family: 'mononoki';
703 src: url('./fonts/mononoki/mononoki-Italic.woff') format('woff'), /* Pretty Modern Browsers */
704 url('./fonts/mononoki/mononoki-Italic.ttf') format('truetype'); /* Safari, Android, iOS */
705 font-weight: normal;
706 font-style: italic;
707
708 }
709
710 @font-face {
711 font-family: 'mononoki';
712 src: url('./fonts/mononoki/mononoki-BoldItalic.woff') format('woff'), /* Pretty Modern Browsers */
713 url('./fonts/mononoki/mononoki-BoldItalic.ttf') format('truetype'); /* Safari, Android, iOS */
714 font-weight: bold;
715 font-style: italic;
716 }
717 #+END_SRC
718*** Main Stylesheet
719 :PROPERTIES:
720 :header-args: :noweb yes :tangle ./aesthetic/main.css
721 :END:
722 #+NAME: Main Stylesheet
723 #+BEGIN_SRC css
724 body, html {
725 margin: 0;
726 paddding: 0;
727 font-size: var(--default-size);
728 }
729
730 body {
731 background: var(--main-bg);
732 font-family: var(--primary-font);
733 color: var(--main-text);
734 }
735
736 <<Main Component Styling>>
737 <<Title Styling>>
738 <<Episode Styling>>
739 #+END_SRC
740
741* Process
742** TODO Peer Bios show up in the store.
743** TODO Peer Bios added to PeerCard view, but only show up if there is a bio available.
744** TODO Font Added to Zine
745** TODO Zine styled to workable degree.
746** TODO Zine shared with crew.
747** TODO Transcription Component added as optional view.
748
749
750
751

Built with git-ssb-web