Change source to use shorter lines and keep linter happy
This commit is contained in:
parent
6de454e36f
commit
5242640bce
3
index.js
3
index.js
|
@ -45,7 +45,8 @@ if (config.debug) {
|
|||
const app = require('./src/app')
|
||||
|
||||
const start = async () => {
|
||||
config.readme = await fs.readFile(path.join(__dirname, 'README.md'), 'utf8')
|
||||
const filePath = path.join(__dirname, 'README.md')
|
||||
config.readme = await fs.readFile(filePath, 'utf8')
|
||||
app(config)
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,8 @@ module.exports = (config) => {
|
|||
router
|
||||
.param('imageSize', (imageSize, ctx, next) => {
|
||||
const size = Number(imageSize)
|
||||
ctx.assert(typeof size === 'number' && size % 1 === 0 && size > 2 && size < 1e10, 'Invalid image size')
|
||||
const isInteger = size % 1 === 0
|
||||
ctx.assert(isInteger && size > 2 && size < 1e10, 'Invalid image size')
|
||||
return next()
|
||||
})
|
||||
.param('blobId', (blobId, ctx, next) => {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
const post = require('./models/post')
|
||||
const listView = require('./views/list')
|
||||
|
||||
module.exports = async function hashtag (channel) {
|
||||
module.exports = async function mentionsPage () {
|
||||
const messages = await post.mentionsMe()
|
||||
|
||||
return listView({ messages })
|
||||
|
|
|
@ -6,4 +6,5 @@ const defaultOptions = {
|
|||
meta: true
|
||||
}
|
||||
|
||||
module.exports = (...customOptions) => Object.assign({}, defaultOptions, ...customOptions)
|
||||
module.exports = (...customOptions) =>
|
||||
Object.assign({}, defaultOptions, ...customOptions)
|
||||
|
|
|
@ -49,7 +49,7 @@ const db = {
|
|||
})
|
||||
},
|
||||
read (method, ...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise((resolve) => {
|
||||
resolve(method(...args))
|
||||
})
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ const db = {
|
|||
|
||||
debug.enabled = true
|
||||
|
||||
const handle = new Promise((resolve, reject) => {
|
||||
const handle = new Promise((resolve) => {
|
||||
rawConnect().then((ssb) => {
|
||||
debug('Using pre-existing Scuttlebutt server instead of starting one')
|
||||
resolve(ssb)
|
||||
|
|
|
@ -14,7 +14,7 @@ const toUrl = (mentions = []) => {
|
|||
}
|
||||
})
|
||||
|
||||
return (ref, isImage) => {
|
||||
return (ref) => {
|
||||
// @mentions
|
||||
if (ref in mentionNames) {
|
||||
return `/author/${encodeURIComponent(mentionNames[ref])}`
|
||||
|
|
|
@ -36,110 +36,117 @@ const getMessages = async ({ myFeedId, customOptions, ssb, query }) => {
|
|||
})
|
||||
}
|
||||
|
||||
const transform = (ssb, messages, myFeedId) => Promise.all(messages.map(async (msg) => {
|
||||
debug('transforming %s', msg.key)
|
||||
const transform = (ssb, messages, myFeedId) =>
|
||||
Promise.all(messages.map(async (msg) => {
|
||||
debug('transforming %s', msg.key)
|
||||
|
||||
if (msg == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
lodash.set(msg, 'value.meta.md.block', () => markdown(msg.value.content.text, msg.value.content.mentions))
|
||||
|
||||
const filterQuery = {
|
||||
$filter: {
|
||||
dest: msg.key
|
||||
if (msg == null) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const referenceStream = await cooler.read(ssb.backlinks.read, {
|
||||
query: [filterQuery],
|
||||
index: 'DTA', // use asserted timestamps
|
||||
private: true,
|
||||
meta: true
|
||||
})
|
||||
|
||||
const rawVotes = await new Promise((resolve, reject) => {
|
||||
pull(
|
||||
referenceStream,
|
||||
pull.filter((ref) => typeof ref.value.content !== 'string' &&
|
||||
ref.value.content.type === 'vote' &&
|
||||
ref.value.content.vote &&
|
||||
typeof ref.value.content.vote.value === 'number' &&
|
||||
ref.value.content.vote.value >= 0 &&
|
||||
ref.value.content.vote.link === msg.key),
|
||||
pull.collect((err, collectedMessages) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
} else {
|
||||
resolve(collectedMessages)
|
||||
}
|
||||
})
|
||||
lodash.set(msg, 'value.meta.md.block', () =>
|
||||
markdown(msg.value.content.text, msg.value.content.mentions)
|
||||
)
|
||||
})
|
||||
|
||||
// { @key: 1, @key2: 0, @key3: 1 }
|
||||
//
|
||||
// only one vote per person!
|
||||
const reducedVotes = rawVotes.reduce((acc, vote) => {
|
||||
acc[vote.value.author] = vote.value.content.vote.value
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
// gets *only* the people who voted 1
|
||||
// [ @key, @key, @key ]
|
||||
const voters = Object.entries(reducedVotes).filter((e) => e[1] === 1).map((e) => e[0])
|
||||
|
||||
const pendingName = cooler.get(
|
||||
ssb.about.socialValue, {
|
||||
key: 'name',
|
||||
dest: msg.value.author
|
||||
const filterQuery = {
|
||||
$filter: {
|
||||
dest: msg.key
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const pendingAvatarMsg = cooler.get(
|
||||
ssb.about.socialValue, {
|
||||
key: 'image',
|
||||
dest: msg.value.author
|
||||
const referenceStream = await cooler.read(ssb.backlinks.read, {
|
||||
query: [filterQuery],
|
||||
index: 'DTA', // use asserted timestamps
|
||||
private: true,
|
||||
meta: true
|
||||
})
|
||||
|
||||
const rawVotes = await new Promise((resolve, reject) => {
|
||||
pull(
|
||||
referenceStream,
|
||||
pull.filter((ref) => typeof ref.value.content !== 'string' &&
|
||||
ref.value.content.type === 'vote' &&
|
||||
ref.value.content.vote &&
|
||||
typeof ref.value.content.vote.value === 'number' &&
|
||||
ref.value.content.vote.value >= 0 &&
|
||||
ref.value.content.vote.link === msg.key),
|
||||
pull.collect((err, collectedMessages) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
} else {
|
||||
resolve(collectedMessages)
|
||||
}
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
// { @key: 1, @key2: 0, @key3: 1 }
|
||||
//
|
||||
// only one vote per person!
|
||||
const reducedVotes = rawVotes.reduce((acc, vote) => {
|
||||
acc[vote.value.author] = vote.value.content.vote.value
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
// gets *only* the people who voted 1
|
||||
// [ @key, @key, @key ]
|
||||
const voters = Object
|
||||
.entries(reducedVotes)
|
||||
.filter(([key, value]) => value === 1)
|
||||
.map(([key]) => key)
|
||||
|
||||
const pendingName = cooler.get(
|
||||
ssb.about.socialValue, {
|
||||
key: 'name',
|
||||
dest: msg.value.author
|
||||
}
|
||||
)
|
||||
|
||||
const pendingAvatarMsg = cooler.get(
|
||||
ssb.about.socialValue, {
|
||||
key: 'image',
|
||||
dest: msg.value.author
|
||||
}
|
||||
)
|
||||
|
||||
const pending = [pendingName, pendingAvatarMsg]
|
||||
const [name, avatarMsg] = await Promise.all(pending)
|
||||
|
||||
const nullImage = `&${'0'.repeat(43)}=.sha256`
|
||||
const avatarId = avatarMsg != null && typeof avatarMsg.link === 'string'
|
||||
? avatarMsg.link || nullImage
|
||||
: avatarMsg || nullImage
|
||||
|
||||
const avatarUrl = `/image/32/${encodeURIComponent(avatarId)}`
|
||||
|
||||
const ts = new Date(msg.value.timestamp)
|
||||
let isoTs
|
||||
|
||||
try {
|
||||
isoTs = ts.toISOString()
|
||||
} catch (e) {
|
||||
// Just in case it's an invalid date. :(
|
||||
debug(e)
|
||||
const receivedTs = new Date(msg.timestamp)
|
||||
isoTs = receivedTs.toISOString()
|
||||
}
|
||||
)
|
||||
|
||||
const pending = [pendingName, pendingAvatarMsg]
|
||||
const [name, avatarMsg] = await Promise.all(pending)
|
||||
lodash.set(msg, 'value.meta.timestamp.received.iso8601', isoTs)
|
||||
|
||||
const nullImage = `&${'0'.repeat(43)}=.sha256`
|
||||
const avatarId = avatarMsg != null && typeof avatarMsg.link === 'string'
|
||||
? avatarMsg.link || nullImage
|
||||
: avatarMsg || nullImage
|
||||
const ago = Date.now() - Number(ts)
|
||||
const prettyAgo = prettyMs(ago, { compact: true })
|
||||
lodash.set(msg, 'value.meta.timestamp.received.since', prettyAgo)
|
||||
lodash.set(msg, 'value.meta.author.name', name)
|
||||
lodash.set(msg, 'value.meta.author.avatar', {
|
||||
id: avatarId,
|
||||
url: avatarUrl
|
||||
})
|
||||
|
||||
const avatarUrl = `/image/32/${encodeURIComponent(avatarId)}`
|
||||
lodash.set(msg, 'value.meta.votes', voters)
|
||||
lodash.set(msg, 'value.meta.voted', voters.includes(myFeedId))
|
||||
|
||||
const ts = new Date(msg.value.timestamp)
|
||||
let isoTs
|
||||
|
||||
try {
|
||||
isoTs = ts.toISOString()
|
||||
} catch (e) {
|
||||
// Just in case it's an invalid date. :(
|
||||
debug(e)
|
||||
const receivedTs = new Date(msg.timestamp)
|
||||
isoTs = receivedTs.toISOString()
|
||||
}
|
||||
|
||||
lodash.set(msg, 'value.meta.timestamp.received.iso8601', isoTs)
|
||||
|
||||
const ago = Date.now() - Number(ts)
|
||||
lodash.set(msg, 'value.meta.timestamp.received.since', prettyMs(ago, { compact: true }))
|
||||
lodash.set(msg, 'value.meta.author.name', name)
|
||||
lodash.set(msg, 'value.meta.author.avatar', {
|
||||
id: avatarId,
|
||||
url: avatarUrl
|
||||
})
|
||||
|
||||
lodash.set(msg, 'value.meta.votes', voters)
|
||||
lodash.set(msg, 'value.meta.voted', voters.includes(myFeedId))
|
||||
|
||||
return msg
|
||||
}))
|
||||
return msg
|
||||
}))
|
||||
|
||||
module.exports = {
|
||||
fromFeed: async (feedId, customOptions = {}) => {
|
||||
|
@ -346,7 +353,11 @@ module.exports = {
|
|||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat
|
||||
const flattenDeep = (arr1) => arr1.reduce(
|
||||
(acc, val) => (Array.isArray(val) ? acc.concat(flattenDeep(val)) : acc.concat(val)), []
|
||||
(acc, val) => (Array.isArray(val)
|
||||
? acc.concat(flattenDeep(val))
|
||||
: acc.concat(val)
|
||||
),
|
||||
[]
|
||||
)
|
||||
|
||||
const getDeepReplies = (key) => new Promise((resolve, reject) => {
|
||||
|
|
|
@ -16,7 +16,8 @@ const template = require('./components/template')
|
|||
module.exports = ({
|
||||
avatarUrl, name, description, messages, feedId
|
||||
}) => {
|
||||
const markdownMention = highlightJs.highlight('markdown', `[@${name}](${feedId})`).value
|
||||
const mention = `[@${name}](${feedId})`
|
||||
const markdownMention = highlightJs.highlight('markdown', mention).value
|
||||
|
||||
const prefix = section({ class: 'message' },
|
||||
header({ class: 'profile' },
|
||||
|
|
|
@ -38,7 +38,11 @@ module.exports = ({ msg }) => {
|
|||
}
|
||||
|
||||
const isPrivate = Boolean(msg.value.meta.private)
|
||||
const isThreadTarget = Boolean(lodash.get(msg, 'value.meta.thread.target', false))
|
||||
const isThreadTarget = Boolean(lodash.get(
|
||||
msg,
|
||||
'value.meta.thread.target',
|
||||
false
|
||||
))
|
||||
|
||||
const { name } = msg.value.meta.author
|
||||
const timeAgo = msg.value.meta.timestamp.received.since
|
||||
|
@ -76,7 +80,10 @@ module.exports = ({ msg }) => {
|
|||
const emptyContent = '<p>undefined</p>\n'
|
||||
const articleElement = markdownContent === emptyContent
|
||||
? article({ class: 'content' }, pre({
|
||||
innerHTML: highlightJs.highlight('json', JSON.stringify(msg, null, 2)).value
|
||||
innerHTML: highlightJs.highlight(
|
||||
'json',
|
||||
JSON.stringify(msg, null, 2)
|
||||
).value
|
||||
}))
|
||||
: article({ class: 'content', innerHTML: markdownContent })
|
||||
|
||||
|
|
|
@ -16,7 +16,8 @@ const {
|
|||
|
||||
const doctypeString = '<!DOCTYPE html>'
|
||||
|
||||
const toAttributes = (obj) => Object.entries(obj).map(([key, val]) => `${key}=${val}`).join(', ')
|
||||
const toAttributes = (obj) =>
|
||||
Object.entries(obj).map(([key, val]) => `${key}=${val}`).join(', ')
|
||||
|
||||
module.exports = (...elements) => {
|
||||
const nodes =
|
||||
|
@ -25,8 +26,14 @@ module.exports = (...elements) => {
|
|||
title('🏝️ Oasis'),
|
||||
link({ rel: 'stylesheet', href: '/assets/style.css' }),
|
||||
link({ rel: 'stylesheet', href: '/highlight/github.css' }),
|
||||
meta({ name: 'description', content: 'friendly neighborhood scuttlebutt interface' }),
|
||||
meta({ name: 'viewport', content: toAttributes({ width: 'device-width', 'initial-scale': 1 }) })
|
||||
meta({
|
||||
name: 'description',
|
||||
content: 'friendly neighborhood scuttlebutt interface'
|
||||
}),
|
||||
meta({
|
||||
name: 'viewport',
|
||||
content: toAttributes({ width: 'device-width', 'initial-scale': 1 })
|
||||
})
|
||||
),
|
||||
body(
|
||||
nav(
|
||||
|
|
|
@ -19,7 +19,11 @@ module.exports = ({ message }) => {
|
|||
return template(
|
||||
post({ msg: message }),
|
||||
form({ action: likeForm, method: 'post' },
|
||||
textarea({ autofocus: true, required: true, name: 'text' }, markdownMention),
|
||||
textarea({
|
||||
autofocus: true,
|
||||
required: true,
|
||||
name: 'text'
|
||||
}, markdownMention),
|
||||
button({
|
||||
type: 'submit'
|
||||
}, 'reply'))
|
||||
|
|
Loading…
Reference in New Issue