git ssb

2+

mixmix / ticktack



Commit bd8064b6ef447f00a6709b42bfe0881145a51ad8

working muiti person private messages (cap 7)

mix committed on 2/6/2018, 9:49:48 AM
Parent: 2f46470aad18da0d76890f9f0f30c34ada88472b

Files changed

app/page/threadNew.jschanged
app/page/threadShow.jschanged
app/page/threadShow.mcsschanged
translations/en.jschanged
app/page/threadNew.jsView
@@ -1,17 +1,20 @@
11 const nest = require('depnest')
2-const { h, Struct, Value, Array: MutantArray, computed, map } = require('mutant')
2+const { h, Struct, Value, Array: MutantArray, computed, map, resolve } = require('mutant')
3+const suggestBox = require('suggest-box')
34
45 exports.gives = nest('app.page.threadNew')
56
67 exports.needs = nest({
8+ 'about.async.suggest': 'first',
79 'about.html.avatar': 'first',
810 'about.obs.name': 'first',
911 'app.html.sideNav': 'first',
1012 'app.html.thread': 'first',
1113 'history.sync.push': 'first',
1214 'keys.sync.id': 'first',
1315 'message.html.compose': 'first',
16+ 'message.sync.unbox': 'first',
1417 'translations.sync.strings': 'first',
1518 })
1619
1720 exports.create = (api) => {
@@ -28,37 +31,27 @@
2831 const strings = api.translations.sync.strings()
2932 const myId = api.keys.sync.id()
3033
3134 const { feed } = location
32- const name = api.about.obs.name
3335
34- const searchInput = Value()
3536 const meta = Struct({
3637 type: 'post',
3738 recps: MutantArray ([
3839 myId,
39- { link: feed, name: name(feed) }
40+ { link: feed, name: resolve(api.about.obs.name(feed)) }
4041 ]),
4142 subject: Value()
4243 })
4344
44- const composer = api.message.html.compose(
45- { meta, shrink: false },
46- (err, msg) => api.history.sync.push(err ? err : Object.assign(msg, { feed })) // TODO check this
47- )
48-
4945 return h('Page -threadNew', {title: strings.threadNew.pageTitle}, [
5046 api.app.html.sideNav(location),
5147 h('div.content', [
5248 h('div.container', [
5349 h('div.field -to', [
5450 h('div.label', strings.threadNew.field.to),
5551 h('div.recps', [
5652 map(meta.recps, Recipient),
57- h('input', {
58- 'ev-input': e => searchInput.set(e.target.value),
59- placeholder: strings.optionalField
60- }),
53+ RecipientInput(meta.recps)
6154 ])
6255 ]),
6356 h('div.field -subject', [
6457 h('div.label', strings.threadNew.field.subject),
@@ -66,9 +59,9 @@
6659 'ev-input': e => meta.subject.set(e.target.value),
6760 placeholder: strings.optionalField
6861 }),
6962 ]),
70- composer
63+ Composer(meta)
7164 ])
7265 ])
7366 ])
7467
@@ -79,8 +72,77 @@
7972 api.about.html.avatar(r.link, 'tiny'),
8073 h('div.name', r.name)
8174 ])
8275 }
76+
77+ function RecipientInput (recps) {
78+ const getRecpSuggestions = api.about.async.suggest()
79+ const input = h('input', {
80+ placeholder: strings.threadNew.action.addMoreRecps
81+ // 'ev-input': e => searchInput.set(e.target.value),
82+ })
83+
84+ var boxActive = false
85+ addSuggest()
86+
87+ input.addEventListener('suggestselect', (e) => {
88+ const { id, title: name } = e.detail
89+ if (!recps.find(r => r === id || r.link === id))
90+ recps.push({ link: id, name })
91+
92+ boxActive = false
93+ e.target.value = ''
94+ e.target.placeholder = ''
95+ })
96+
97+ input.addEventListener('keyup', (e) => {
98+ // don't pop the previous entry if still entering a name!
99+ if (boxActive) {
100+ // if you delete a name you were typing completely, mark box inactive
101+ // so that further deletes pop names
102+ if (e.target.value === '') boxActive = false
103+ return
104+ }
105+
106+ if (e.code === 'Backspace' || e.key === 'Backspace' || e.keyCode == 8) {
107+ if (recps.getLength() < 3) return // can only delete down to 2 recps (sender + 1 recp)
108+
109+ recps.pop()
110+ }
111+ })
112+
113+ return input
114+
115+ function addSuggest () {
116+ if (!input.parentElement) return setTimeout(addSuggest, 100)
117+
118+ suggestBox(input, (inputText, cb) => {
119+ if (recps.getLength() >= 7) return
120+ // TODO - tell the user they're only allowed 6 (or 7?!) people in a message
121+
122+ boxActive = true
123+ const suggestions = getRecpSuggestions(inputText)
124+ cb(null, suggestions)
125+ }, {cls: 'PatchSuggest'})
126+ }
127+ }
128+
129+ function Composer (meta) {
130+ return api.message.html.compose(
131+ { meta, shrink: false },
132+ (err, msg) => {
133+ if (err) return api.history.sync.push(err)
134+
135+ const someRecipient = meta.recps.get(1)
136+ if (!someRecipient) return
137+
138+ api.history.sync.push(Object.assign(
139+ api.message.sync.unbox(msg), // for consistency of message sideNav receives D:
140+ { feed: someRecipient.link }
141+ ))
142+ }
143+ )
144+ }
83145 }
84146
85147 }
86148
app/page/threadShow.jsView
@@ -5,8 +5,9 @@
55
66 exports.gives = nest('app.page.threadShow')
77
88 exports.needs = nest({
9+ 'about.html.avatar': 'first',
910 'app.html.sideNav': 'first',
1011 'app.html.thread': 'first',
1112 'message.html.compose': 'first',
1213 'unread.sync.markRead': 'first',
@@ -23,34 +24,38 @@
2324 const channel = get(value, 'content.channel')
2425
2526 //unread state is set in here...
2627 const thread = api.feed.obs.thread(root)
28+ const subject = get(location, 'value.content.subject')
29+ const recps = get(location, 'value.content.recps')
2730
2831 const meta = {
2932 type: 'post',
3033 root,
3134 branch: thread.lastId,
3235 channel,
33- recps: get(location, 'value.content.recps'),
36+ recps
3437 }
3538 const composer = api.message.html.compose({ meta, thread, shrink: false })
3639
3740 return h('Page -threadShow', [
3841 api.app.html.sideNav(location),
3942 h('div.content', [
40- when(thread.subject, h('h1', thread.subject)),
43+ h('header', [
44+ when(subject, h('h1', subject)),
45+ Recipients(recps),
46+ ]),
4147 api.app.html.thread(thread),
4248 composer
4349 ]),
4450 ])
4551 }
52+
53+ function Recipients (recps) {
54+ if (recps && recps.length > 2)
55+ return h('div.recps', recps.map(r => {
56+ const recp = typeof r === 'string' ? r : r.link
57+ return api.about.html.avatar(recp, 'tiny')
58+ }))
59+ }
4660 }
4761
48-
49-
50-
51-
52-
53-
54-
55-
56-
app/page/threadShow.mcssView
@@ -1,7 +1,22 @@
11 Page -threadShow {
22 div.content {
3+ header {
4+ display: flex
5+ align-items: center
6+ flex-wrap: wrap
37
8+ h1 {
9+ margin-right: 1rem
10+ }
11+
12+ div.recps {
13+ img.Avatar {
14+ margin-right: .6rem
15+ }
16+ }
17+ }
18+
419 div.Thread {}
520
621 div.Compose {
722 margin: 0 auto
translations/en.jsView
@@ -86,9 +86,10 @@
8686 to: 'To',
8787 subject: 'Subject',
8888 },
8989 action: {
90- new: 'New Message'
90+ new: 'New Message',
91+ addMoreRecps: 'add more recipients (optional)'
9192 }
9293 },
9394 threadShow: 'Direct Messages',
9495 userEdit: {

Built with git-ssb-web