Commit a289f670e3c164407deae3baa673d2f9d1ab03ee
tidy up meta-summary files and code
Matt McKegg committed on 7/6/2018, 7:14:33 AMParent: 907e87521ce87db66a62d443aa9c0d5bc4e4815e
Files changed
modules/feed/html/rollup.js | changed |
modules/feed/html/meta-summary.js | added |
styles/dark/follow-graph.mcss | deleted |
styles/dark/feed-meta-summary.mcss | added |
modules/feed/html/rollup.js | ||
---|---|---|
@@ -6,9 +6,8 @@ | ||
6 | 6 | var nextStepper = require('../../../lib/next-stepper') |
7 | 7 | var extend = require('xtend') |
8 | 8 | var paramap = require('pull-paramap') |
9 | 9 | var Group = require('pull-group') |
10 | -var ref = require('ssb-ref') | |
11 | 10 | |
12 | 11 | var bumpMessages = { |
13 | 12 | 'vote': 'liked this message', |
14 | 13 | 'post': 'replied to this message', |
@@ -40,9 +39,10 @@ | ||
40 | 39 | 'sbot.async.get': 'first', |
41 | 40 | 'keys.sync.id': 'first', |
42 | 41 | 'intl.sync.i18n': 'first', |
43 | 42 | 'intl.sync.i18n_n': 'first', |
44 | - 'message.html.missing': 'first' | |
43 | + 'message.html.missing': 'first', | |
44 | + 'feed.html.metaSummary': 'first' | |
45 | 45 | }) |
46 | 46 | |
47 | 47 | exports.gives = nest({ |
48 | 48 | 'feed.html.rollup': true |
@@ -215,50 +215,11 @@ | ||
215 | 215 | ) |
216 | 216 | }) |
217 | 217 | } |
218 | 218 | |
219 | - function renderGroup (item, opts) { | |
220 | - var expanded = Value(false) | |
221 | - var actions = getContactActions(item.msgs) | |
222 | - var counts = getContactActionCounts(actions) | |
223 | - var reduced = reduceActions(counts) | |
224 | - | |
225 | - var contentSummary = h('FollowGraph', [ | |
226 | - reduced.map(action => actionSummary(action, id => { | |
227 | - if (id.startsWith('#')) { | |
228 | - return h('a -channel', {href: id}, `#${ref.normalizeChannel(id)}`) | |
229 | - } else { | |
230 | - return h('a', {href: id}, api.about.html.image(id)) | |
231 | - } | |
232 | - }, i18n)) | |
233 | - ]) | |
234 | - | |
235 | - return h('FeedEvent -group', { | |
236 | - classList: [ when(expanded, '-expanded') ] | |
237 | - }, [ | |
238 | - contentSummary, | |
239 | - when(expanded, h('div.items', item.msgs.map(msg => renderItem(msg, opts)))), | |
240 | - h('a.expand', { | |
241 | - 'tab-index': 0, | |
242 | - 'ev-click': {handleEvent: toggleValue, value: expanded} | |
243 | - }, [ | |
244 | - when(expanded, | |
245 | - [i18n('Hide details')], | |
246 | - [i18n('Show details') + ' (', item.msgs.length, ')'] | |
247 | - ) | |
248 | - ]) | |
249 | - ]) | |
250 | - } | |
251 | - | |
252 | 219 | function renderItem (item, opts) { |
253 | 220 | if (item.group) { |
254 | - // if (item.msgs.length === 1) { | |
255 | - // // fallback to standard item rendering if group only contains 1 item | |
256 | - // item = item.msgs[0] | |
257 | - // } else { | |
258 | - // return renderGroup(item, opts) | |
259 | - // } | |
260 | - return renderGroup(item, opts) | |
221 | + return api.feed.html.metaSummary(item, renderItem, opts) | |
261 | 222 | } |
262 | 223 | var partial = opts && opts.partial |
263 | 224 | var meta = null |
264 | 225 | var previousId = item.key |
@@ -483,206 +444,20 @@ | ||
483 | 444 | return array |
484 | 445 | } |
485 | 446 | } |
486 | 447 | |
487 | -function actionSummary (item, avatarFormatter, i18n) { | |
488 | - var actionName = null | |
489 | - var from = [] | |
490 | - var to = [] | |
491 | - if (item.action === 'followedBy' || item.action === 'subscribedBy') { | |
492 | - actionName = 'followed' | |
493 | - from = item.targets | |
494 | - to = [item.id] | |
495 | - } else if (item.action === 'unfollowedBy' || item.action === 'unsubscribedBy') { | |
496 | - actionName = 'unfollowed' | |
497 | - from = item.targets | |
498 | - to = [item.id] | |
499 | - } else if (item.action === 'following' || item.action === 'subscribing') { | |
500 | - actionName = 'followed' | |
501 | - from = [item.id] | |
502 | - to = item.targets | |
503 | - } else if (item.action === 'unfollowing' || item.action === 'unsubscribing') { | |
504 | - actionName = 'unfollowed' | |
505 | - from = [item.id] | |
506 | - to = item.targets | |
507 | - } else if (item.action === 'blockedBy') { | |
508 | - actionName = 'blocked' | |
509 | - from = item.targets | |
510 | - to = [item.id] | |
511 | - } else if (item.action === 'unblockedBy') { | |
512 | - actionName = 'unblocked' | |
513 | - from = item.targets | |
514 | - to = [item.id] | |
515 | - } else if (item.action === 'blocking') { | |
516 | - actionName = 'blocked' | |
517 | - from = [item.id] | |
518 | - to = item.targets | |
519 | - } else if (item.action === 'unblocking') { | |
520 | - actionName = 'unblocked' | |
521 | - from = [item.id] | |
522 | - to = item.targets | |
523 | - } else if (item.action === 'identifying') { | |
524 | - actionName = 'identify' | |
525 | - from = [item.id] | |
526 | - to = item.targets | |
527 | - } else if (item.action === 'identifiedBy') { | |
528 | - actionName = 'identify' | |
529 | - from = item.targets | |
530 | - to = [item.id] | |
531 | - } | |
532 | - | |
533 | - return h('div -' + actionName, [h('div -left', from.slice(0, 10).map(avatarFormatter)), h('span.action'), h('div -right', to.slice(0, 10).map(avatarFormatter))]) | |
534 | -} | |
535 | - | |
536 | -function getContactActions (msgs) { | |
537 | - var actions = {} | |
538 | - | |
539 | - // reduce down actions for each contact change (de-duplicate, remove redundency) | |
540 | - // e.g. if a person follows someone then unfollows, ignore both actions | |
541 | - msgs.forEach(msg => { | |
542 | - var content = msg.value.content | |
543 | - let from = msg.value.author | |
544 | - if (content.type === 'contact') { | |
545 | - if (ref.isFeed(content.contact)) { | |
546 | - let to = content.contact | |
547 | - let key = `${from}:${to}` | |
548 | - if (content.following === true) { | |
549 | - if (actions[key] === 'unfollow') { | |
550 | - delete actions[key] | |
551 | - } else { | |
552 | - actions[key] = 'follow' | |
553 | - } | |
554 | - } else if (content.blocking === true) { | |
555 | - if (actions[key] === 'unblock') { | |
556 | - delete actions[key] | |
557 | - } else { | |
558 | - actions[key] = 'block' | |
559 | - } | |
560 | - } else if (content.blocking === false) { | |
561 | - if (actions[key] === 'block') { | |
562 | - delete actions[key] | |
563 | - } else { | |
564 | - actions[key] = 'unblock' | |
565 | - } | |
566 | - } else if (content.following === false) { | |
567 | - if (actions[key] === 'follow') { | |
568 | - delete actions[key] | |
569 | - } else { | |
570 | - actions[key] = 'unfollow' | |
571 | - } | |
572 | - } | |
573 | - } | |
574 | - } else if (content.type === 'channel') { | |
575 | - if (typeof content.channel === 'string') { // TODO: better channel check | |
576 | - let to = '#' + content.channel | |
577 | - let key = `${from}:${to}` | |
578 | - if (content.subscribed === true) { | |
579 | - if (actions[key] === 'unfollow') { | |
580 | - delete actions[key] | |
581 | - } else { | |
582 | - actions[key] = 'subscribe' | |
583 | - } | |
584 | - } else if (content.subscribed === false) { | |
585 | - if (actions[key] === 'follow') { | |
586 | - delete actions[key] | |
587 | - } else { | |
588 | - actions[key] = 'unsubscribe' | |
589 | - } | |
590 | - } | |
591 | - } | |
592 | - } else if (content.type === 'about') { | |
593 | - if (ref.isFeed(content.about)) { | |
594 | - let to = content.about | |
595 | - let key = `${from}:${to}` | |
596 | - actions[key] = 'identify' | |
597 | - } | |
598 | - } | |
599 | - }) | |
600 | - | |
601 | - return actions | |
602 | -} | |
603 | - | |
604 | -function getContactActionCounts (actions) { | |
605 | - var actionCounts = {} | |
606 | - | |
607 | - // get actions performed on and by profiles | |
608 | - // collect who did what and has what done on them | |
609 | - for (var key in actions) { | |
610 | - var action = actions[key] | |
611 | - var {from, to} = splitKey(key) | |
612 | - actionCounts[from] = actionCounts[from] || ContactActionTracker() | |
613 | - actionCounts[to] = actionCounts[to] || ContactActionTracker() | |
614 | - | |
615 | - if (action === 'follow') { | |
616 | - actionCounts[from].following.push(to) | |
617 | - actionCounts[to].followedBy.push(from) | |
618 | - } else if (action === 'unfollow') { | |
619 | - actionCounts[from].unfollowing.push(to) | |
620 | - actionCounts[to].unfollowedBy.push(from) | |
621 | - } else if (action === 'subscribe') { | |
622 | - actionCounts[from].subscribing.push(to) | |
623 | - actionCounts[to].subscribedBy.push(from) | |
624 | - } else if (action === 'unsubscribe') { | |
625 | - actionCounts[from].unsubscribing.push(to) | |
626 | - actionCounts[to].unsubscribedBy.push(from) | |
627 | - } else if (action === 'block') { | |
628 | - actionCounts[from].blocking.push(to) | |
629 | - actionCounts[to].blockedBy.push(from) | |
630 | - } else if (action === 'unblock') { | |
631 | - actionCounts[from].unblocking.push(to) | |
632 | - actionCounts[to].unblockedBy.push(from) | |
633 | - } else if (action === 'identify') { | |
634 | - actionCounts[from].identifying.push(to) | |
635 | - actionCounts[to].identifiedBy.push(from) | |
636 | - } | |
637 | - } | |
638 | - | |
639 | - return actionCounts | |
640 | -} | |
641 | - | |
642 | -function reduceActions (actionCounts) { | |
643 | - var actions = [] | |
644 | - | |
645 | - for (let key in actionCounts) { | |
646 | - var value = actionCounts[key] | |
647 | - for (let action in value) { | |
648 | - actions.push({id: key, action, targets: value[action]}) | |
649 | - } | |
650 | - } | |
651 | - | |
652 | - // sort desc by most targets per action | |
653 | - actions.sort((a, b) => b.targets.length - a.targets.length) | |
654 | - | |
655 | - // remove duplicate actions, and return! | |
656 | - var used = new Set() | |
657 | - return actions.filter(action => { | |
658 | - let targets = action.targets.filter(target => { | |
659 | - return !used.has(`${action.id}:${target}`) && !used.has(`${target}:${action.id}`) | |
660 | - }) | |
661 | - action.targets = targets | |
662 | - | |
663 | - targets.forEach(target => { | |
664 | - used.add(`${action.id}:${target}`) | |
665 | - used.add(`${target}:${action.id}`) | |
666 | - }) | |
667 | - | |
668 | - // only return if has targets | |
669 | - return !!targets.length | |
670 | - }) | |
671 | -} | |
672 | - | |
673 | 448 | function GroupSimilar (windowSize, ungroupFilter) { |
674 | 449 | return pull( |
675 | 450 | Group(windowSize), |
676 | 451 | pull.map(function (msgs) { |
677 | 452 | var result = [] |
678 | 453 | var groups = {} |
679 | 454 | |
680 | - var typeGroups = ['about', 'channel', 'contact'] | |
455 | + var metaSummaryTypes = ['about', 'channel', 'contact'] | |
681 | 456 | |
682 | 457 | msgs.forEach(msg => { |
683 | - var type = 'group' // msg.value.content.type | |
684 | - if (typeGroups.includes(msg.value.content.type) && !hasReply(msg) && !ungroupFilter(msg)) { | |
458 | + var type = 'metaSummary' // msg.value.content.type | |
459 | + if (metaSummaryTypes.includes(msg.value.content.type) && !hasReply(msg) && !ungroupFilter(msg)) { | |
685 | 460 | if (!groups[type]) { |
686 | 461 | groups[type] = {group: type, msgs: []} |
687 | 462 | result.push(groups[type]) |
688 | 463 | } |
@@ -700,35 +475,4 @@ | ||
700 | 475 | |
701 | 476 | function hasReply (msg) { |
702 | 477 | return msg.replies && msg.replies.some(msg => msg.value.content.type === 'post') |
703 | 478 | } |
704 | - | |
705 | -function ContactActionTracker () { | |
706 | - return { | |
707 | - followedBy: [], | |
708 | - following: [], | |
709 | - unfollowedBy: [], | |
710 | - unfollowing: [], | |
711 | - blockedBy: [], | |
712 | - blocking: [], | |
713 | - unblockedBy: [], | |
714 | - unblocking: [], | |
715 | - subscribedBy: [], | |
716 | - subscribing: [], | |
717 | - unsubscribedBy: [], | |
718 | - unsubscribing: [], | |
719 | - identifiedBy: [], | |
720 | - identifying: [] | |
721 | - } | |
722 | -} | |
723 | - | |
724 | -function toggleValue () { | |
725 | - this.value.set(!this.value()) | |
726 | -} | |
727 | - | |
728 | -function splitKey (key) { | |
729 | - var mid = key.indexOf(':') | |
730 | - return { | |
731 | - from: key.slice(0, mid), | |
732 | - to: key.slice(mid + 1) | |
733 | - } | |
734 | -} |
modules/feed/html/meta-summary.js | ||
---|---|---|
@@ -1,0 +1,196 @@ | ||
1 | +var nest = require('depnest') | |
2 | +var ref = require('ssb-ref') | |
3 | +var { when, h, Value } = require('mutant') | |
4 | + | |
5 | +exports.needs = nest({ | |
6 | + 'intl.sync.i18n': 'first', | |
7 | + 'about.html.image': 'first' | |
8 | +}) | |
9 | + | |
10 | +exports.gives = nest({ | |
11 | + 'feed.html.metaSummary': true | |
12 | +}) | |
13 | + | |
14 | +exports.create = function (api) { | |
15 | + const i18n = api.intl.sync.i18n | |
16 | + return nest('feed.html', {metaSummary}) | |
17 | + | |
18 | + function metaSummary (group, renderItem, opts) { | |
19 | + var expanded = Value(false) | |
20 | + var actions = getActions(group.msgs) | |
21 | + var counts = getActionCounts(actions) | |
22 | + var reduced = reduceActions(counts) | |
23 | + | |
24 | + var contentSummary = h('FeedMetaSummary', [ | |
25 | + reduced.map(item => { | |
26 | + return h('div -' + item.action, [ | |
27 | + h('div -left', item.from.slice(0, 10).map(avatarFormatter)), | |
28 | + h('span.action'), | |
29 | + h('div -right', item.to.slice(0, 10).map(avatarFormatter)) | |
30 | + ]) | |
31 | + }) | |
32 | + ]) | |
33 | + | |
34 | + return h('FeedEvent -group', { | |
35 | + classList: [ when(expanded, '-expanded') ] | |
36 | + }, [ | |
37 | + contentSummary, | |
38 | + when(expanded, h('div.items', group.msgs.map(msg => renderItem(msg, opts)))), | |
39 | + h('a.expand', { | |
40 | + 'tab-index': 0, | |
41 | + 'ev-click': {handleEvent: toggleValue, value: expanded} | |
42 | + }, [ | |
43 | + when(expanded, | |
44 | + [i18n('Hide details')], | |
45 | + [i18n('Show details') + ' (', group.msgs.length, ')'] | |
46 | + ) | |
47 | + ]) | |
48 | + ]) | |
49 | + } | |
50 | + | |
51 | + function avatarFormatter (id) { | |
52 | + if (id.startsWith('#')) { | |
53 | + return h('a -channel', {href: id}, `#${ref.normalizeChannel(id)}`) | |
54 | + } else { | |
55 | + return h('a', {href: id}, api.about.html.image(id)) | |
56 | + } | |
57 | + } | |
58 | +} | |
59 | + | |
60 | +function getActions (msgs) { | |
61 | + var actions = {} | |
62 | + | |
63 | + // reduce down actions for each contact change (de-duplicate, remove redundency) | |
64 | + // e.g. if a person follows someone then unfollows, ignore both actions | |
65 | + msgs.forEach(msg => { | |
66 | + var content = msg.value.content | |
67 | + let from = msg.value.author | |
68 | + if (content.type === 'contact') { | |
69 | + if (ref.isFeed(content.contact)) { | |
70 | + let to = content.contact | |
71 | + let key = `${from}:${to}` | |
72 | + if (content.following === true) { | |
73 | + if (actions[key] === 'unfollowed') { | |
74 | + delete actions[key] | |
75 | + } else { | |
76 | + actions[key] = 'followed' | |
77 | + } | |
78 | + } else if (content.blocking === true) { | |
79 | + if (actions[key] === 'unblocked') { | |
80 | + delete actions[key] | |
81 | + } else { | |
82 | + actions[key] = 'blocked' | |
83 | + } | |
84 | + } else if (content.blocking === false) { | |
85 | + if (actions[key] === 'blocked') { | |
86 | + delete actions[key] | |
87 | + } else { | |
88 | + actions[key] = 'unblocked' | |
89 | + } | |
90 | + } else if (content.following === false) { | |
91 | + if (actions[key] === 'followed') { | |
92 | + delete actions[key] | |
93 | + } else { | |
94 | + actions[key] = 'unfollowed' | |
95 | + } | |
96 | + } | |
97 | + } | |
98 | + } else if (content.type === 'channel') { | |
99 | + if (typeof content.channel === 'string') { // TODO: better channel check | |
100 | + let to = '#' + content.channel | |
101 | + let key = `${from}:${to}` | |
102 | + if (content.subscribed === true) { | |
103 | + if (actions[key] === 'unsubscribed') { | |
104 | + delete actions[key] | |
105 | + } else { | |
106 | + actions[key] = 'subscribed' | |
107 | + } | |
108 | + } else if (content.subscribed === false) { | |
109 | + if (actions[key] === 'subscribed') { | |
110 | + delete actions[key] | |
111 | + } else { | |
112 | + actions[key] = 'unsubscribed' | |
113 | + } | |
114 | + } | |
115 | + } | |
116 | + } else if (content.type === 'about') { | |
117 | + if (ref.isFeed(content.about)) { | |
118 | + let to = content.about | |
119 | + let key = `${from}:${to}` | |
120 | + actions[key] = 'identified' | |
121 | + } | |
122 | + } | |
123 | + }) | |
124 | + | |
125 | + return actions | |
126 | +} | |
127 | + | |
128 | +function getActionCounts (actions) { | |
129 | + var actionCounts = {} | |
130 | + | |
131 | + // get actions performed on and by profiles | |
132 | + // collect who did what and has what done on them | |
133 | + for (var key in actions) { | |
134 | + var action = actions[key] | |
135 | + var {from, to} = splitKey(key) | |
136 | + actionCounts[from] = actionCounts[from] || {from: {}, to: {}} | |
137 | + actionCounts[to] = actionCounts[to] || {from: {}, to: {}} | |
138 | + | |
139 | + actionCounts[from].from[action] = actionCounts[from].from[action] || [] | |
140 | + actionCounts[to].to[action] = actionCounts[to].to[action] || [] | |
141 | + | |
142 | + actionCounts[from].from[action].push(to) | |
143 | + actionCounts[to].to[action].push(from) | |
144 | + } | |
145 | + | |
146 | + return actionCounts | |
147 | +} | |
148 | + | |
149 | +function reduceActions (actionCounts) { | |
150 | + var actions = [] | |
151 | + | |
152 | + for (let key in actionCounts) { | |
153 | + var value = actionCounts[key] | |
154 | + for (let action in value.from) { | |
155 | + actions.push({from: [key], action, to: value.from[action], rank: value.from[action].length}) | |
156 | + } | |
157 | + for (let action in value.to) { | |
158 | + actions.push({from: value.to[action], action, to: [key], rank: value.to[action].length}) | |
159 | + } | |
160 | + } | |
161 | + | |
162 | + // sort desc by most targets per action | |
163 | + actions.sort((a, b) => Math.max(b.rank - a.rank)) | |
164 | + | |
165 | + // remove duplicate actions, and return! | |
166 | + var used = new Set() | |
167 | + return actions.filter(action => { | |
168 | + // only add a particular action once! | |
169 | + if (action.from.length > action.to.length) { | |
170 | + action.from = action.from.filter(from => action.to.some(to => !used.has(`${from}:${to}`))) | |
171 | + } else { | |
172 | + action.to = action.to.filter(to => action.from.some(from => !used.has(`${from}:${to}`))) | |
173 | + } | |
174 | + | |
175 | + action.from.forEach(from => { | |
176 | + action.to.forEach(to => { | |
177 | + used.add(`${from}:${to}`) | |
178 | + }) | |
179 | + }) | |
180 | + | |
181 | + // // only return if has targets | |
182 | + return action.from.length && action.to.length | |
183 | + }) | |
184 | +} | |
185 | + | |
186 | +function toggleValue () { | |
187 | + this.value.set(!this.value()) | |
188 | +} | |
189 | + | |
190 | +function splitKey (key) { | |
191 | + var mid = key.indexOf(':') | |
192 | + return { | |
193 | + from: key.slice(0, mid), | |
194 | + to: key.slice(mid + 1) | |
195 | + } | |
196 | +} |
styles/dark/follow-graph.mcss | ||
---|---|---|
@@ -1,128 +1,0 @@ | ||
1 | -FollowGraph { | |
2 | - position: relative | |
3 | - display: flex | |
4 | - flex-wrap: wrap | |
5 | - justify-content: center | |
6 | - margin: 10px | |
7 | - | |
8 | - | |
9 | - div { | |
10 | - display: flex | |
11 | - align-items: center; | |
12 | - border-radius: 3px | |
13 | - padding: 5px | |
14 | - background: #353535 | |
15 | - margin: 5px | |
16 | - white-space: nowrap | |
17 | - overflow: hidden | |
18 | - | |
19 | - div { | |
20 | - display: flex; | |
21 | - align-items: center; | |
22 | - flex-wrap: wrap; | |
23 | - | |
24 | - -left { | |
25 | - background: #111; | |
26 | - padding: 5px; | |
27 | - margin: -5px; | |
28 | - border-radius: 3px | |
29 | - } | |
30 | - | |
31 | - a { | |
32 | - vertical-align: middle | |
33 | - display: inline-block | |
34 | - img { | |
35 | - display: block | |
36 | - width: 45px; | |
37 | - border-radius: 3px; | |
38 | - } | |
39 | - | |
40 | - -channel { | |
41 | - font-size: 20px; | |
42 | - color: #91c1ec; | |
43 | - border-bottom: 1px dotted #91c1ec; | |
44 | - margin: 5px; | |
45 | - } | |
46 | - } | |
47 | - | |
48 | - a + a { | |
49 | - margin-left: 3px | |
50 | - } | |
51 | - } | |
52 | - | |
53 | - -blocked { | |
54 | - background-color: #382c01 | |
55 | - span { | |
56 | - :after { | |
57 | - content: '⚠️' | |
58 | - color: #ffa603 | |
59 | - } | |
60 | - } | |
61 | - div { | |
62 | - -right { | |
63 | - opacity: 0.7 | |
64 | - :hover { | |
65 | - opacity: 1 | |
66 | - } | |
67 | - } | |
68 | - } | |
69 | - } | |
70 | - | |
71 | - -unblocked { | |
72 | - background-color: #39434c | |
73 | - span { :after { | |
74 | - content: '?' | |
75 | - }} | |
76 | - } | |
77 | - | |
78 | - -followed { | |
79 | - span { :after { | |
80 | - content: '✓' | |
81 | - }} | |
82 | - } | |
83 | - | |
84 | - -unfollowed { | |
85 | - background-color: #39434c | |
86 | - span { :after { | |
87 | - content: '⊗' | |
88 | - }} | |
89 | - } | |
90 | - | |
91 | - -identify { | |
92 | - background-color: #afafaf | |
93 | - span { :after { | |
94 | - content: '👤' | |
95 | - }} | |
96 | - } | |
97 | - | |
98 | - | |
99 | - span { | |
100 | - vertical-align: middle; | |
101 | - position: relative; | |
102 | - display: inline-flex; | |
103 | - align-items: center; | |
104 | - background: svg(arrow) no-repeat right | |
105 | - background-size: cover; | |
106 | - height: 45px; | |
107 | - margin-right: 3px; | |
108 | - padding-left: 8px; | |
109 | - padding-right: 15px; | |
110 | - | |
111 | - :after { | |
112 | - color: white; | |
113 | - font-size: 15px; | |
114 | - vertical-align: middle; | |
115 | - display: inline-block; | |
116 | - } | |
117 | - | |
118 | - @svg arrow { | |
119 | - width: 64px | |
120 | - height: 64px | |
121 | - path { | |
122 | - fill: #111 | |
123 | - } | |
124 | - content: "<path d='M40 54 L64 32 L40 10 L28 10 L16 0 L0 0 L0 64 L16 64 L28 54 Z' />" | |
125 | - } | |
126 | - } | |
127 | - } | |
128 | -} |
styles/dark/feed-meta-summary.mcss | ||
---|---|---|
@@ -1,0 +1,136 @@ | ||
1 | +FeedMetaSummary { | |
2 | + position: relative | |
3 | + display: flex | |
4 | + flex-wrap: wrap | |
5 | + justify-content: center | |
6 | + margin: 10px | |
7 | + | |
8 | + div { | |
9 | + display: flex | |
10 | + align-items: center; | |
11 | + border-radius: 3px | |
12 | + padding: 5px | |
13 | + background: #353535 | |
14 | + margin: 5px | |
15 | + white-space: nowrap | |
16 | + overflow: hidden | |
17 | + | |
18 | + div { | |
19 | + display: flex; | |
20 | + align-items: center; | |
21 | + flex-wrap: wrap; | |
22 | + | |
23 | + -left { | |
24 | + background: #111; | |
25 | + padding: 5px; | |
26 | + margin: -5px; | |
27 | + border-radius: 3px | |
28 | + } | |
29 | + | |
30 | + a { | |
31 | + vertical-align: middle | |
32 | + display: inline-block | |
33 | + img { | |
34 | + display: block | |
35 | + width: 45px; | |
36 | + min-height: 30px | |
37 | + border-radius: 3px; | |
38 | + } | |
39 | + | |
40 | + -channel { | |
41 | + font-size: 20px; | |
42 | + color: #91c1ec; | |
43 | + border-bottom: 1px dotted #91c1ec; | |
44 | + margin: 5px; | |
45 | + } | |
46 | + } | |
47 | + | |
48 | + a + a { | |
49 | + margin-left: 3px | |
50 | + } | |
51 | + } | |
52 | + | |
53 | + -blocked { | |
54 | + background-color: #382c01 | |
55 | + span { | |
56 | + :after { | |
57 | + content: '⚠️' | |
58 | + color: #ffa603 | |
59 | + } | |
60 | + } | |
61 | + div { | |
62 | + -right { | |
63 | + opacity: 0.7 | |
64 | + :hover { | |
65 | + opacity: 1 | |
66 | + } | |
67 | + } | |
68 | + } | |
69 | + } | |
70 | + | |
71 | + -unblocked { | |
72 | + background-color: #39434c | |
73 | + span { :after { | |
74 | + content: '?' | |
75 | + }} | |
76 | + } | |
77 | + | |
78 | + -followed, -subscribed { | |
79 | + span { :after { | |
80 | + content: '✓' | |
81 | + }} | |
82 | + } | |
83 | + | |
84 | + -unfollowed, -unsubscribed { | |
85 | + background-color: #39434c | |
86 | + span { :after { | |
87 | + content: '⊗' | |
88 | + }} | |
89 | + div { | |
90 | + -right { | |
91 | + opacity: 0.7 | |
92 | + :hover { | |
93 | + opacity: 1 | |
94 | + } | |
95 | + } | |
96 | + } | |
97 | + } | |
98 | + | |
99 | + -identified { | |
100 | + background-color: #afafaf | |
101 | + span { :after { | |
102 | + content: '👤' | |
103 | + }} | |
104 | + } | |
105 | + | |
106 | + | |
107 | + span { | |
108 | + vertical-align: middle; | |
109 | + position: relative; | |
110 | + display: inline-flex; | |
111 | + align-items: center; | |
112 | + background: svg(arrow) no-repeat right | |
113 | + background-size: cover; | |
114 | + height: 45px; | |
115 | + margin-right: 3px; | |
116 | + padding-left: 8px; | |
117 | + padding-right: 15px; | |
118 | + | |
119 | + :after { | |
120 | + color: white; | |
121 | + font-size: 15px; | |
122 | + vertical-align: middle; | |
123 | + display: inline-block; | |
124 | + } | |
125 | + | |
126 | + @svg arrow { | |
127 | + width: 64px | |
128 | + height: 64px | |
129 | + path { | |
130 | + fill: #111 | |
131 | + } | |
132 | + content: "<path d='M40 54 L64 32 L40 10 L28 10 L16 0 L0 0 L0 64 L16 64 L28 54 Z' />" | |
133 | + } | |
134 | + } | |
135 | + } | |
136 | +} |
Built with git-ssb-web