git ssb

2+

mixmix / ticktack



Commit 3287f6b02c40d45d8b653ff1fbbc5f699072519c

Merge remote-tracking branch 'origin/master' into _master3

Dominic Tarr committed on 8/16/2017, 7:34:00 AM
Parent: 9bf270081d898c0ec622f792b7f8e6e340f7a102
Parent: ec8cfe66cd3dbfa8ddc119bae4546fb25f8c8fd5

Files changed

app/html/link.jschanged
app/html/link.mcsschanged
app/html/thread-card.jschanged
app/html/thread-card.mcssadded
app/page/channel.jschanged
app/page/error.jschanged
app/page/groupFind.jschanged
app/page/groupIndex.jschanged
app/page/groupNew.jschanged
app/page/groupShow.jschanged
app/page/home.jschanged
app/page/home.mcsschanged
app/page/settings.jschanged
app/page/threadNew.jschanged
app/page/threadShow.jschanged
app/page/userFind.jschanged
app/page/userShow.jschanged
app/page/userShow.mcssadded
styles/global.mcsschanged
styles/button.mcssadded
styles/markdown.mcssadded
translations/sync.jschanged
app/html/link.jsView
@@ -9,9 +9,10 @@
99
1010 exports.create = (api) => {
1111 return nest('app.html.link', (location, body) => {
1212 return h('Link', {
13- 'ev-click': () => api.history.sync.push(location)
13+ 'ev-click': () => api.history.sync.push(location),
14+ className: typeof body === 'string' ? '-string' : ''
1415 }, body)
1516 })
1617 }
1718
app/html/link.mcssView
@@ -1,6 +1,10 @@
11 Link {
22 color: blue
3- :hover {
4- text-decoration: underline
3+
4+ -string {
5+ :hover {
6+ text-decoration: underline
7+ }
58 }
69 }
10+
app/html/thread-card.jsView
@@ -88,9 +88,9 @@
8888 const onClick = opts.onClick || function () { api.history.sync.push(thread) }
8989 const id = `${thread.key}-${JSON.stringify(opts)}`
9090 // id is only here to help morphdom morph accurately
9191
92- return h('div.thread', { 'ev-click': onClick, id }, [
92+ return h('ThreadCard', { 'ev-click': onClick, id }, [
9393 h('div.context', threadIcon(thread)),
9494 h('div.content', [
9595 subjectEl,
9696 replySample ? h('div.reply', [
app/html/thread-card.mcssView
@@ -1,0 +1,42 @@
1+ThreadCard {
2+ display: flex
3+ align-items: center
4+
5+ margin-bottom: .5rem
6+
7+ div.context {
8+ display: flex
9+ margin-right: 1rem
10+
11+ img {
12+ $smallAvatar
13+ margin-right: .5rem
14+ }
15+ }
16+
17+ div.content {
18+ flex-grow: 1
19+ background: #fff
20+ padding: 1rem
21+ border: 1px solid #ddd
22+ border-radius: 2px
23+
24+ div.subject {
25+ font-size: 1.2rem
26+ margin-bottom: .3rem
27+
28+ $largeMarkdown
29+ }
30+ div.reply {
31+ display: flex
32+ color: #444
33+
34+ div.replySymbol {
35+ margin-left: .7rem
36+ margin-right: .3rem
37+ }
38+
39+ $smallMarkdown
40+ }
41+ }
42+}
app/page/channel.jsView
@@ -5,9 +5,8 @@
55
66 exports.gives = nest('app.page.channel')
77
88 exports.needs = nest({
9- 'app.html.nav': 'first',
109 'app.html.threadCard': 'first',
1110 'history.sync.push': 'first',
1211 'state.obs.channel': 'first',
1312 'translations.sync.strings': 'first',
@@ -73,4 +72,5 @@
7372 })
7473 }
7574
7675
76+
app/page/error.jsView
@@ -3,10 +3,9 @@
33
44 exports.gives = nest('app.page.error')
55
66 exports.needs = nest({
7- 'translations.sync.strings': 'first',
8- 'app.html.nav': 'first'
7+ 'translations.sync.strings': 'first'
98 })
109
1110 exports.create = (api) => {
1211 var strings = api.translations.sync.strings()
@@ -15,11 +14,12 @@
1514
1615 function error (location) {
1716 return h('Page -error', {title: strings.error}, [
1817 strings.errorNotFound,
19- location.error
18+ h('pre', [JSON.stringify(location, null, 2)])
2019 ])
2120 }
2221 }
2322
2423
2524
25+
app/page/groupFind.jsView
@@ -4,9 +4,8 @@
44 exports.gives = nest('app.page.groupFind')
55
66 exports.needs = nest({
77 'translations.sync.strings': 'first',
8- 'app.html.nav': 'first'
98 })
109
1110 exports.create = (api) => {
1211 var strings = api.translations.sync.strings()
@@ -19,4 +18,5 @@
1918 }
2019 }
2120
2221
22+
app/page/groupIndex.jsView
@@ -3,10 +3,9 @@
33
44 exports.gives = nest('app.page.groupIndex')
55
66 exports.needs = nest({
7- 'translations.sync.strings': 'first',
8- 'app.html.nav': 'first'
7+ 'translations.sync.strings': 'first'
98 })
109
1110 exports.create = (api) => {
1211 var strings = api.translations.sync.strings()
@@ -20,4 +19,5 @@
2019 }
2120
2221
2322
23+
app/page/groupNew.jsView
@@ -3,9 +3,8 @@
33
44 exports.gives = nest('app.page.groupNew')
55
66 exports.needs = nest({
7- 'app.html.nav': 'first',
87 'translations.sync.strings': 'first'
98 })
109
1110 exports.create = (api) => {
@@ -18,4 +17,5 @@
1817 }
1918 }
2019
2120
21+
app/page/groupShow.jsView
@@ -4,9 +4,8 @@
44 exports.gives = nest('app.page.groupShow')
55
66 exports.needs = nest({
77 'translations.sync.strings': 'first',
8- 'app.html.nav': 'first'
98 })
109
1110 exports.create = (api) => {
1211 var strings = api.translations.sync.strings()
@@ -24,4 +23,5 @@
2423
2524
2625
2726
27+
app/page/home.jsView
@@ -7,9 +7,8 @@
77
88 exports.gives = nest('app.page.home')
99
1010 exports.needs = nest({
11- 'app.html.nav': 'first',
1211 'history.sync.push': 'first',
1312 'keys.sync.id': 'first',
1413 'translations.sync.strings': 'first',
1514 'state.obs.threads': 'first',
@@ -30,9 +29,8 @@
3029 return nest('app.page.home', function (location) {
3130 // location here can expected to be: { page: 'home'}
3231 var strings = api.translations.sync.strings()
3332
34- var container = h('div.container', [])
3533
3634 // function filterForThread (thread) {
3735 // if(thread.value.private)
3836 // return {private: toRecpGroup(thread)}
@@ -69,8 +67,9 @@
6967 morePlease = true
7068 requestIdleCallback(threadsObs.more)
7169 }
7270
71+ var container = h('div.container', [])
7372 var threadsHtmlObs = More(
7473 threadsObsDebounced,
7574 function render (threads) {
7675
@@ -106,21 +105,19 @@
106105 h('div.container', [
107106 //private section
108107 h('section.updates -directMessage', [
109108 h('div.threads',
110- groupedThreads
111- .map(function (thread) {
109+ groupedThreads.map(thread => {
110+ const channel = thread.value.content.channel
111+ const onClick = channel
112+ ? (ev) => api.history.sync.push({ channel })
113+ : null // threadCard will install default onClick
112114
113- const channel = thread.value.content.channel
114- const onClick = channel
115- ? (ev) => api.history.sync.push({ channel })
116- : null // threadCard will install default onClick
117-
118- return api.app.html.threadCard(thread, { onClick })
115+ return api.app.html.threadCard(thread, { onClick })
119116 })
120117 )
121- ]),
122- ])
118+ ])
119+ ])
123120 )
124121
125122 return container
126123 }
@@ -132,4 +129,5 @@
132129 })
133130 }
134131
135132
133+
app/page/home.mcssView
@@ -9,9 +9,9 @@
99 -directMessage {
1010 $homePageSection
1111
1212 div.threads {
13- div.thread {
13+ div.ThreadCard {
1414 div.content {
1515 div.subject {
1616 display: flex
1717
@@ -33,9 +33,9 @@
3333 -channel {
3434 $homePageSection
3535
3636 div.threads {
37- div.thread {
37+ div.ThreadCard {
3838 div.context {
3939 background: #fff
4040 min-width: 8rem
4141 padding: .1rem .3rem
@@ -73,48 +73,7 @@
7373 margin-bottom: .4rem
7474 }
7575
7676 div.threads {
77- div.thread {
78- display: flex
79- align-items: center
80-
81- margin-bottom: .5rem
82-
83- div.context {
84- display: flex
85- margin-right: 1rem
86-
87- img {
88- $smallAvatar
89- margin-right: .5rem
90- }
91- }
92-
93- div.content {
94- flex-grow: 1
95- background: #fff
96- padding: 1rem
97- border: 1px solid #ddd
98- border-radius: 2px
99-
100- div.subject {
101- font-size: 1.2rem
102- margin-bottom: .3rem
103-
104- $largeMarkdown
105- }
106- div.reply {
107- display: flex
108- color: #444
109-
110- div.replySymbol {
111- margin-left: .7rem
112- margin-right: .3rem
113- }
114-
115- $smallMarkdown
116- }
117- }
118- }
77+ div.ThreadCard {}
11978 }
12079 }
app/page/settings.jsView
@@ -4,9 +4,8 @@
44 exports.gives = nest('app.page.settings')
55
66 exports.needs = nest({
77 'translations.sync.strings': 'first',
8- 'app.html.nav': 'first'
98 })
109
1110 exports.create = (api) => {
1211 return nest('app.page.settings', settings)
@@ -19,4 +18,5 @@
1918 }
2019 }
2120
2221
22+
app/page/threadNew.jsView
@@ -6,9 +6,8 @@
66 exports.needs = nest({
77 'translations.sync.strings': 'first',
88 'about.html.image': 'first',
99 'about.obs.name': 'first',
10- 'app.html.nav': 'first',
1110 'app.html.thread': 'first',
1211 })
1312
1413 exports.create = (api) => {
@@ -28,4 +27,5 @@
2827 }
2928
3029
3130
31+
app/page/threadShow.jsView
@@ -6,9 +6,8 @@
66 exports.gives = nest('app.page.threadShow')
77
88 exports.needs = nest({
99 'translations.sync.strings': 'first',
10- 'app.html.nav': 'first',
1110 'app.html.thread': 'first',
1211 'message.html.compose': 'first'
1312 })
1413
@@ -41,4 +40,5 @@
4140 ])
4241 }
4342 }
4443
44+
app/page/userFind.jsView
@@ -4,9 +4,8 @@
44 exports.gives = nest('app.page.userFind')
55
66 exports.needs = nest({
77 'translations.sync.strings': 'first',
8- 'app.html.nav': 'first'
98 })
109
1110 exports.create = (api) => {
1211 var strings = api.translations.sync.strings()
@@ -21,4 +20,5 @@
2120 }
2221
2322
2423
24+
app/page/userShow.jsView
@@ -1,16 +1,25 @@
11 const nest = require('depnest')
2-const { h } = require('mutant')
2+const { h, Array: MutantArray, computed, when, map } = require('mutant')
3+const pull = require('pull-stream')
4+const get = require('lodash/get')
35
46 exports.gives = nest('app.page.userShow')
57
68 exports.needs = nest({
79 'translations.sync.strings': 'first',
810 'app.html.link': 'first',
9- 'app.html.nav': 'first',
11+ 'app.html.threadCard': 'first',
1012 'about.html.image': 'first',
1113 'about.obs.name': 'first',
14+ 'contact.async.follow': 'first',
15+ 'contact.async.unfollow': 'first',
16+ 'contact.obs.followers': 'first',
17+ 'feed.pull.private': 'first',
18+ 'feed.pull.rollup': 'first',
1219 'keys.sync.id': 'first',
20+ 'state.obs.threads': 'first',
21+ 'translations.sync.strings': 'first',
1322 })
1423
1524 exports.create = (api) => {
1625 var strings = api.translations.sync.strings()
@@ -19,23 +28,79 @@
1928
2029 function userShow (location) {
2130
2231 const { feed } = location
23- const Link = api.app.html.link
2432 const myId = api.keys.sync.id()
2533 var name = api.about.html.name(feed)
2634
27- return h('Page -userShow', {title: api.about.obs.name(feed)}, [
28- api.about.html.image(feed),
29- h('div', strings.followButton),
30- h('div', strings.friendsInCommon),
31- feed !== myId
32- ? Link({ page: 'threadNew', feed }, strings.newThread)
33- : '',
34- h('div', strings.userConvesationsWith, name),
35- h('div', name, strings.userIsInGroups),
35+ const strings = api.translations.sync.strings()
36+
37+ const { followers } = api.contact.obs
38+
39+ const youFollowThem = computed(followers(feed), followers => followers.has(myId))
40+ const theyFollowYou = computed(followers(myId), followers => followers.has(feed))
41+ const youAreFriends = computed([youFollowThem, theyFollowYou], (a, b) => a && b)
42+
43+ const ourRelationship = computed(
44+ [youAreFriends, youFollowThem, theyFollowYou],
45+ (youAreFriends, youFollowThem, theyFollowYou) => {
46+ if (youAreFriends) return strings.userShow.state.friends
47+ if (theyFollowYou) return strings.userShow.state.theyFollow
48+ if (youFollowThem) return strings.userShow.state.youFollow
49+ }
50+ )
51+ const { unfollow, follow } = api.contact.async
52+ const followButton = when(followers(myId).sync,
53+ when(youFollowThem,
54+ h('Button -subtle', { 'ev-click': () => unfollow(feed) }, strings.userShow.action.unfollow),
55+ h('Button -primary', { 'ev-click': () => follow(feed) }, strings.userShow.action.follow)
56+ ),
57+ h('Button', { disabled: 'disabled' }, strings.loading )
58+ )
59+
60+
61+ const threads = MutantArray()
62+ pull(
63+ // next(api.feed.pull.private, {reverse: true, limit: 100, live: false}, ['value', 'timestamp']),
64+ // api.feed.pull.private({reverse: true, limit: 100, live: false}),
65+ api.feed.pull.private({reverse: true, live: false}),
66+ pull.filter(msg => {
67+ const recps = get(msg, 'value.content.recps')
68+ if (!recps) return
69+
70+ return recps
71+ .map(r => typeof r === 'object' ? r.link : r)
72+ .includes(feed)
73+ }),
74+ api.feed.pull.rollup(),
75+ pull.drain(threads.push)
76+ // Scroller(container, content, render, false, false)
77+ )
78+
79+ const Link = api.app.html.link
80+
81+ return h('Page -userShow', {title: strings.userShow}, [
82+ h('div.container', [
83+ api.about.html.image(feed),
84+ feed !== myId
85+ ? h('div.friendship', [
86+ h('div.state', ourRelationship),
87+ followButton
88+ ]) : '',
89+ h('div', '...friends in common'),
90+ h('div', '...groups this person is in'),
91+ feed !== myId
92+ ? Link({ page: 'threadNew', feed }, h('Button -primary', strings.userShow.action.directMessage))
93+ : '',
94+ h('div.threads', map(threads, api.app.html.threadCard))
95+ ])
3696 ])
3797 }
3898 }
3999
40100
41101
102+
103+
104+
105+
106+
app/page/userShow.mcssView
@@ -1,0 +1,17 @@
1+Page -userShow {
2+ div.container {
3+
4+ div.friendship {
5+ display: flex
6+ align-items: center
7+
8+ margin-bottom: 1rem
9+
10+ div.state { flex-basis: 12rem }
11+ div.Button {}
12+ }
13+
14+
15+ }
16+}
17+
styles/global.mcssView
@@ -17,16 +17,7 @@
1717 img {
1818 max-width: 100%
1919 }
2020
21-Markdown {
22- word-break: break-word
23-
24- (img) {
25- margin: .5rem 0
26- border-radius: .5rem
27- }
28-}
29-
3021 button {
3122 width: 100%
3223 }
styles/button.mcssView
@@ -1,0 +1,27 @@
1+Button {
2+ font-family: arial
3+ text-align: center
4+
5+ cursor: pointer
6+
7+ padding: .2rem 2rem
8+ min-width: 4rem
9+ border: 1px #b9b9b9 solid
10+
11+ -subtle {
12+ color: #b9b9b9
13+ :hover {
14+ color: #222
15+ }
16+ }
17+ -primary {
18+ $primaryColor
19+
20+ :hover {
21+ opacity: .9
22+ }
23+
24+ border: none
25+ }
26+}
27+
styles/markdown.mcssView
@@ -1,0 +1,10 @@
1+Markdown {
2+ word-break: break-word
3+
4+ (img) {
5+ margin: .5rem 0
6+ border-radius: .5rem
7+ }
8+}
9+
10+
translations/sync.jsView
@@ -1,31 +1,57 @@
1+const nest = require('depnest')
12
2-exports.gives = {translations: {sync: {strings: true}}}
3+exports.gives = nest('translations.sync.strings')
34
4-exports.create = function () {
5- return {translations: {sync: {strings: function () {
6- return {
7- showMore: "Show More",
8- channels: "Channels",
9- home: "Home",
10- directMessages: "Direct Messages",
11- replySymbol: "> ",
12- error: "Error",
13- errorNotFound: "The page wasn't found",
14- groupNew: "New Group",
15- groupFind: 'Find Group',
16- groupIndex: "Group Index",
17- //stub: should not be shown on released software!
18- stub: "this page is a stub",
19- settings: "Settings",
20- threadNew: 'New Thread',
21- threadShow: "Direct Messages",
5+exports.create = (api) => {
6+ return nest('translations.sync.strings', () => en)
7+}
8+
9+const en = {
10+ loading: 'Loading...',
11+ showMore: 'Show More',
12+ channels: 'Channels',
13+ directMessages: 'Direct Messages',
14+ replySymbol: '> ',
15+ home: "Home",
16+ error: "Error",
17+ errorNotFound: "The page wasn't found",
18+ groupNew: "New Group",
19+ groupFind: 'Find Group',
20+ groupIndex: "Group Index",
21+ //stub: should not be shown on released software!
22+ stub: "this page is a stub",
23+ settings: "Settings",
24+ threadNew: 'New Thread',
25+ threadShow: "Direct Messages",
26+ userShow: {
27+ action: {
28+ follow: 'Follow',
29+ unfollow: 'Unfollow',
30+ directMessage: 'New Direct Message'
31+ },
32+ state: {
33+ friends: 'You are friends',
34+ youFollow: 'You follow them',
35+ theyFollow: 'They follow you',
2236 userFind: "Find User",
2337 userIsInGroups: "is in groups:",
2438 userConversationsWith: 'conversations you\'ve had with',
2539 follow: "Follow",
2640 friendsInCommon: 'friends in common'
2741 }
28- }}}}
42+ }
2943 }
3044
3145
46+
47+
48+
49+
50+
51+
52+
53+
54+
55+
56+
57+

Built with git-ssb-web