chore: update standard to v13 (#1370)
This commit is contained in:
parent
b034b60145
commit
00945a3608
|
@ -13,9 +13,9 @@ const writeFile = promisify(fs.writeFile)
|
|||
const themeColors = fromPairs(themes.map(_ => ([_.name, _.color])))
|
||||
|
||||
export async function buildInlineScript () {
|
||||
let inlineScriptPath = path.join(__dirname, '../src/inline-script/inline-script.js')
|
||||
const inlineScriptPath = path.join(__dirname, '../src/inline-script/inline-script.js')
|
||||
|
||||
let bundle = await rollup({
|
||||
const bundle = await rollup({
|
||||
input: inlineScriptPath,
|
||||
plugins: [
|
||||
replace({
|
||||
|
@ -28,15 +28,15 @@ export async function buildInlineScript () {
|
|||
})
|
||||
]
|
||||
})
|
||||
let { output } = await bundle.generate({
|
||||
const { output } = await bundle.generate({
|
||||
format: 'iife',
|
||||
sourcemap: true
|
||||
})
|
||||
|
||||
let { code, map } = output[0]
|
||||
const { code, map } = output[0]
|
||||
|
||||
let fullCode = `${code}//# sourceMappingURL=/inline-script.js.map`
|
||||
let checksum = crypto.createHash('sha256').update(fullCode).digest('base64')
|
||||
const fullCode = `${code}//# sourceMappingURL=/inline-script.js.map`
|
||||
const checksum = crypto.createHash('sha256').update(fullCode).digest('base64')
|
||||
|
||||
await writeFile(path.resolve(__dirname, '../src/inline-script/checksum.js'),
|
||||
`module.exports = ${JSON.stringify(checksum)}`, 'utf8')
|
||||
|
|
|
@ -13,42 +13,42 @@ import { sapperInlineScriptChecksums } from '../src/server/sapperInlineScriptChe
|
|||
const writeFile = promisify(fs.writeFile)
|
||||
|
||||
const JSON_TEMPLATE = {
|
||||
'version': 2,
|
||||
'env': {
|
||||
'NODE_ENV': 'production'
|
||||
version: 2,
|
||||
env: {
|
||||
NODE_ENV: 'production'
|
||||
},
|
||||
'builds': [
|
||||
builds: [
|
||||
{
|
||||
'src': 'package.json',
|
||||
'use': '@now/static-build',
|
||||
'config': {
|
||||
'distDir': '__sapper__/export'
|
||||
src: 'package.json',
|
||||
use: '@now/static-build',
|
||||
config: {
|
||||
distDir: '__sapper__/export'
|
||||
}
|
||||
}
|
||||
],
|
||||
'routes': [
|
||||
routes: [
|
||||
{
|
||||
'src': '^/service-worker\\.js$',
|
||||
'headers': {
|
||||
src: '^/service-worker\\.js$',
|
||||
headers: {
|
||||
'cache-control': 'public,max-age=0'
|
||||
}
|
||||
},
|
||||
{
|
||||
'src': '^/(report\\.html|stats\\.json)$',
|
||||
'headers': {
|
||||
src: '^/(report\\.html|stats\\.json)$',
|
||||
headers: {
|
||||
'cache-control': 'public,max-age=3600'
|
||||
},
|
||||
'dest': 'client/$1'
|
||||
dest: 'client/$1'
|
||||
},
|
||||
{
|
||||
'src': '^/client/.*\\.(js|css|map)$',
|
||||
'headers': {
|
||||
src: '^/client/.*\\.(js|css|map)$',
|
||||
headers: {
|
||||
'cache-control': 'public,max-age=31536000,immutable'
|
||||
}
|
||||
},
|
||||
{
|
||||
'src': '^/.*\\.(png|css|json|svg|jpe?g|map|txt)$',
|
||||
'headers': {
|
||||
src: '^/.*\\.(png|css|json|svg|jpe?g|map|txt)$',
|
||||
headers: {
|
||||
'cache-control': 'public,max-age=3600'
|
||||
}
|
||||
}
|
||||
|
@ -69,21 +69,21 @@ const HTML_HEADERS = {
|
|||
}
|
||||
|
||||
async function main () {
|
||||
let json = cloneDeep(JSON_TEMPLATE)
|
||||
const json = cloneDeep(JSON_TEMPLATE)
|
||||
|
||||
let exportDir = path.resolve(__dirname, '../__sapper__/export')
|
||||
const exportDir = path.resolve(__dirname, '../__sapper__/export')
|
||||
|
||||
for (let { pattern } of routes) {
|
||||
let route = {
|
||||
for (const { pattern } of routes) {
|
||||
const route = {
|
||||
src: pattern.source,
|
||||
headers: cloneDeep(HTML_HEADERS)
|
||||
}
|
||||
|
||||
// remove all the regexy stuff in the regex
|
||||
let filename = pattern.source.replace(/^\^\\\//, '').replace(/(\\\/)?\?\$$/, '').replace(/\\\//g, '/')
|
||||
const filename = pattern.source.replace(/^\^\\\//, '').replace(/(\\\/)?\?\$$/, '').replace(/\\\//g, '/')
|
||||
|
||||
// try two different possible paths
|
||||
let filePath = [
|
||||
const filePath = [
|
||||
`${filename}.html`,
|
||||
path.join(filename, 'index.html')
|
||||
].map(_ => path.resolve(exportDir, _)).find(_ => fs.existsSync(_))
|
||||
|
|
|
@ -20,24 +20,24 @@ async function renderCss (file) {
|
|||
}
|
||||
|
||||
async function compileGlobalSass () {
|
||||
let mainStyle = (await Promise.all([defaultThemeScss, globalScss].map(renderCss))).join('')
|
||||
let scrollbarStyle = (await renderCss(customScrollbarScss))
|
||||
const mainStyle = (await Promise.all([defaultThemeScss, globalScss].map(renderCss))).join('')
|
||||
const scrollbarStyle = (await renderCss(customScrollbarScss))
|
||||
|
||||
return `<style>\n${mainStyle}</style>\n` +
|
||||
`<style media="all" id="theScrollbarStyle">\n${scrollbarStyle}</style>\n`
|
||||
}
|
||||
|
||||
async function compileThemesSass () {
|
||||
let files = (await readdir(themesScssDir)).filter(file => !path.basename(file).startsWith('_'))
|
||||
const files = (await readdir(themesScssDir)).filter(file => !path.basename(file).startsWith('_'))
|
||||
await Promise.all(files.map(async file => {
|
||||
let css = await renderCss(path.join(themesScssDir, file))
|
||||
css = cssDedoupe(new TextDecoder('utf-8').decode(css)) // remove duplicate custom properties
|
||||
let outputFilename = 'theme-' + path.basename(file).replace(/\.scss$/, '.css')
|
||||
const outputFilename = 'theme-' + path.basename(file).replace(/\.scss$/, '.css')
|
||||
await writeFile(path.join(assetsDir, outputFilename), css, 'utf8')
|
||||
}))
|
||||
}
|
||||
|
||||
export async function buildSass () {
|
||||
let [ result ] = await Promise.all([compileGlobalSass(), compileThemesSass()])
|
||||
const [result] = await Promise.all([compileGlobalSass(), compileThemesSass()])
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -10,12 +10,12 @@ const readFile = promisify(fs.readFile)
|
|||
const writeFile = promisify(fs.writeFile)
|
||||
|
||||
async function readSvg (svg) {
|
||||
let filepath = path.join(__dirname, '../', svg.src)
|
||||
let content = await readFile(filepath, 'utf8')
|
||||
let optimized = (await svgo.optimize(content))
|
||||
let $optimized = $(optimized.data)
|
||||
let $path = $optimized.find('path').removeAttr('fill')
|
||||
let $symbol = $('<symbol></symbol>')
|
||||
const filepath = path.join(__dirname, '../', svg.src)
|
||||
const content = await readFile(filepath, 'utf8')
|
||||
const optimized = (await svgo.optimize(content))
|
||||
const $optimized = $(optimized.data)
|
||||
const $path = $optimized.find('path').removeAttr('fill')
|
||||
const $symbol = $('<symbol></symbol>')
|
||||
.attr('id', svg.id)
|
||||
.attr('viewBox', `0 0 ${optimized.info.width} ${optimized.info.height}`)
|
||||
.append($path)
|
||||
|
@ -23,14 +23,14 @@ async function readSvg (svg) {
|
|||
}
|
||||
|
||||
export async function buildSvg () {
|
||||
let inlineSvgs = svgs.filter(_ => _.inline)
|
||||
let regularSvgs = svgs.filter(_ => !_.inline)
|
||||
const inlineSvgs = svgs.filter(_ => _.inline)
|
||||
const regularSvgs = svgs.filter(_ => !_.inline)
|
||||
|
||||
let inlineSvgStrings = (await Promise.all(inlineSvgs.map(readSvg))).join('')
|
||||
let regularSvgStrings = (await Promise.all(regularSvgs.map(readSvg))).join('')
|
||||
const inlineSvgStrings = (await Promise.all(inlineSvgs.map(readSvg))).join('')
|
||||
const regularSvgStrings = (await Promise.all(regularSvgs.map(readSvg))).join('')
|
||||
|
||||
let inlineOutput = `<svg xmlns="http://www.w3.org/2000/svg" style="display:none">${inlineSvgStrings}</svg>`
|
||||
let regularOutput = `<svg xmlns="http://www.w3.org/2000/svg">${regularSvgStrings}</svg>`
|
||||
const inlineOutput = `<svg xmlns="http://www.w3.org/2000/svg" style="display:none">${inlineSvgStrings}</svg>`
|
||||
const regularOutput = `<svg xmlns="http://www.w3.org/2000/svg">${regularSvgStrings}</svg>`
|
||||
|
||||
await writeFile(path.resolve(__dirname, '../static/icons.svg'), regularOutput, 'utf8')
|
||||
|
||||
|
|
|
@ -34,17 +34,17 @@ const builders = [
|
|||
const partials = buildPartials()
|
||||
|
||||
function buildPartials () {
|
||||
let rawTemplate = fs.readFileSync(path.resolve(__dirname, '../src/build/template.html'), 'utf8')
|
||||
const rawTemplate = fs.readFileSync(path.resolve(__dirname, '../src/build/template.html'), 'utf8')
|
||||
|
||||
let partials = [rawTemplate]
|
||||
const partials = [rawTemplate]
|
||||
|
||||
builders.forEach(builder => {
|
||||
for (let i = 0; i < partials.length; i++) {
|
||||
let partial = partials[i]
|
||||
const partial = partials[i]
|
||||
if (typeof partial !== 'string') {
|
||||
continue
|
||||
}
|
||||
let idx = partial.indexOf(builder.comment)
|
||||
const idx = partial.indexOf(builder.comment)
|
||||
if (idx !== -1) {
|
||||
partials.splice(
|
||||
i,
|
||||
|
@ -77,8 +77,8 @@ function doWatch () {
|
|||
}
|
||||
|
||||
async function buildAll () {
|
||||
let start = now()
|
||||
let html = (await Promise.all(partials.map(async partial => {
|
||||
const start = now()
|
||||
const html = (await Promise.all(partials.map(async partial => {
|
||||
if (typeof partial === 'string') {
|
||||
return partial
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ async function buildAll () {
|
|||
}))).join('')
|
||||
|
||||
await writeFile(path.resolve(__dirname, '../src/template.html'), html, 'utf8')
|
||||
let end = now()
|
||||
const end = now()
|
||||
console.log(`Built template.html in ${(end - start).toFixed(2)}ms`)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import times from 'lodash-es/times'
|
||||
|
||||
function unrollThread (user, prefix, privacy, thread) {
|
||||
let res = []
|
||||
const res = []
|
||||
|
||||
function unroll (node, parentKey) {
|
||||
if (!node) {
|
||||
return
|
||||
}
|
||||
for (let key of Object.keys(node)) {
|
||||
for (const key of Object.keys(node)) {
|
||||
res.push({
|
||||
user: user,
|
||||
post: {
|
||||
|
|
|
@ -15,24 +15,24 @@ global.fetch = fetch
|
|||
|
||||
export async function restoreMastodonData () {
|
||||
console.log('Restoring mastodon data...')
|
||||
let internalIdsToIds = {}
|
||||
for (let action of actions) {
|
||||
const internalIdsToIds = {}
|
||||
for (const action of actions) {
|
||||
if (!action.post) {
|
||||
// If the action is a boost, favorite, etc., then it needs to
|
||||
// be delayed, otherwise it may appear in an unpredictable order and break the tests.
|
||||
await new Promise(resolve => setTimeout(resolve, 1000))
|
||||
}
|
||||
console.log(JSON.stringify(action))
|
||||
let accessToken = users[action.user].accessToken
|
||||
const accessToken = users[action.user].accessToken
|
||||
|
||||
if (action.post) {
|
||||
let { text, media, sensitive, spoiler, privacy, inReplyTo, internalId } = action.post
|
||||
let mediaIds = media && await Promise.all(media.map(async mediaItem => {
|
||||
let mediaResponse = await submitMedia(accessToken, mediaItem, 'kitten')
|
||||
const { text, media, sensitive, spoiler, privacy, inReplyTo, internalId } = action.post
|
||||
const mediaIds = media && await Promise.all(media.map(async mediaItem => {
|
||||
const mediaResponse = await submitMedia(accessToken, mediaItem, 'kitten')
|
||||
return mediaResponse.id
|
||||
}))
|
||||
let inReplyToId = inReplyTo && internalIdsToIds[inReplyTo]
|
||||
let status = await postStatus('localhost:3000', accessToken, text, inReplyToId, mediaIds,
|
||||
const inReplyToId = inReplyTo && internalIdsToIds[inReplyTo]
|
||||
const status = await postStatus('localhost:3000', accessToken, text, inReplyToId, mediaIds,
|
||||
sensitive, spoiler, privacy || 'public')
|
||||
if (typeof internalId !== 'undefined') {
|
||||
internalIdsToIds[internalId] = status.id
|
||||
|
|
|
@ -66,21 +66,21 @@ async function setupMastodonDatabase () {
|
|||
env: Object.assign({ PGPASSWORD: DB_PASS }, process.env)
|
||||
})
|
||||
|
||||
let dumpFile = path.join(dir, '../tests/fixtures/dump.sql')
|
||||
const dumpFile = path.join(dir, '../tests/fixtures/dump.sql')
|
||||
await exec(`psql -h 127.0.0.1 -U ${DB_USER} -w -d ${DB_NAME} -f "${dumpFile}"`, {
|
||||
cwd: mastodonDir,
|
||||
env: Object.assign({ PGPASSWORD: DB_PASS }, process.env)
|
||||
})
|
||||
|
||||
let tgzFile = path.join(dir, '../tests/fixtures/system.tgz')
|
||||
let systemDir = path.join(mastodonDir, 'public/system')
|
||||
const tgzFile = path.join(dir, '../tests/fixtures/system.tgz')
|
||||
const systemDir = path.join(mastodonDir, 'public/system')
|
||||
await mkdirp(systemDir)
|
||||
await exec(`tar -xzf "${tgzFile}"`, { cwd: systemDir })
|
||||
}
|
||||
|
||||
async function runMastodon () {
|
||||
console.log('Running mastodon...')
|
||||
let env = Object.assign({}, process.env, {
|
||||
const env = Object.assign({}, process.env, {
|
||||
RAILS_ENV: 'development',
|
||||
NODE_ENV: 'development',
|
||||
DB_NAME,
|
||||
|
@ -89,8 +89,8 @@ async function runMastodon () {
|
|||
DB_HOST,
|
||||
DB_PORT
|
||||
})
|
||||
let cwd = mastodonDir
|
||||
let cmds = [
|
||||
const cwd = mastodonDir
|
||||
const cmds = [
|
||||
'gem install bundler foreman',
|
||||
'bundle install',
|
||||
'bundle exec rails db:migrate',
|
||||
|
@ -103,7 +103,7 @@ async function runMastodon () {
|
|||
console.log('Already installed Mastodon')
|
||||
} catch (e) {
|
||||
console.log('Installing Mastodon...')
|
||||
for (let cmd of cmds) {
|
||||
for (const cmd of cmds) {
|
||||
console.log(cmd)
|
||||
await exec(cmd, { cwd, env })
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ const numStatuses = actions
|
|||
async function waitForMastodonData () {
|
||||
while (true) {
|
||||
try {
|
||||
let json = await ((await fetch('http://127.0.0.1:3000/api/v1/instance')).json())
|
||||
const json = await ((await fetch('http://127.0.0.1:3000/api/v1/instance')).json())
|
||||
if (json.stats.status_count === numStatuses) {
|
||||
break
|
||||
} else {
|
||||
|
|
|
@ -3,7 +3,7 @@ import fetch from 'node-fetch'
|
|||
export async function waitForMastodonUiToStart () {
|
||||
while (true) {
|
||||
try {
|
||||
let html = await ((await fetch('http://127.0.0.1:3035/packs/common.js')).text())
|
||||
const html = await ((await fetch('http://127.0.0.1:3035/packs/common.js')).text())
|
||||
if (html) {
|
||||
break
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ export async function waitForMastodonUiToStart () {
|
|||
export async function waitForMastodonApiToStart () {
|
||||
while (true) {
|
||||
try {
|
||||
let json = await ((await fetch('http://127.0.0.1:3000/api/v1/instance')).json())
|
||||
const json = await ((await fetch('http://127.0.0.1:3000/api/v1/instance')).json())
|
||||
if (json.uri) {
|
||||
break
|
||||
}
|
||||
|
|
|
@ -109,7 +109,7 @@
|
|||
"fake-indexeddb": "^2.1.1",
|
||||
"mocha": "^6.1.4",
|
||||
"now": "^15.7.0",
|
||||
"standard": "^12.0.1",
|
||||
"standard": "^13.1.0",
|
||||
"testcafe": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
|
|
|
@ -19,8 +19,8 @@ app.use(compression({ threshold: 0 }))
|
|||
|
||||
app.use(express.static(exportDir, {
|
||||
setHeaders (res, thisPath) {
|
||||
let localPath = '/' + path.relative(exportDir, thisPath)
|
||||
for (let { regex, headers } of routes) {
|
||||
const localPath = '/' + path.relative(exportDir, thisPath)
|
||||
for (const { regex, headers } of routes) {
|
||||
if (regex.test(localPath)) {
|
||||
res.set(headers)
|
||||
return
|
||||
|
|
|
@ -23,7 +23,7 @@ const theme = (instanceThemes && instanceThemes[currentInstance]) || DEFAULT_THE
|
|||
|
||||
if (currentInstance) {
|
||||
// Do preconnect if we're logged in, so we can connect faster to the other origin.
|
||||
let link = document.createElement('link')
|
||||
const link = document.createElement('link')
|
||||
link.setAttribute('rel', 'preconnect')
|
||||
link.setAttribute('href', basename(currentInstance))
|
||||
link.setAttribute('crossorigin', 'anonymous')
|
||||
|
|
|
@ -5,7 +5,7 @@ function getNotificationText (notification, omitEmojiInDisplayNames) {
|
|||
if (!notification) {
|
||||
return
|
||||
}
|
||||
let notificationAccountDisplayName = getAccountAccessibleName(notification.account, omitEmojiInDisplayNames)
|
||||
const notificationAccountDisplayName = getAccountAccessibleName(notification.account, omitEmojiInDisplayNames)
|
||||
if (notification.type === 'reblog') {
|
||||
return `${notificationAccountDisplayName} boosted your status`
|
||||
} else if (notification.type === 'favourite') {
|
||||
|
@ -14,7 +14,7 @@ function getNotificationText (notification, omitEmojiInDisplayNames) {
|
|||
}
|
||||
|
||||
function getPrivacyText (visibility) {
|
||||
for (let option of POST_PRIVACY_OPTIONS) {
|
||||
for (const option of POST_PRIVACY_OPTIONS) {
|
||||
if (option.key === visibility) {
|
||||
return option.label
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ function getReblogText (reblog, account, omitEmojiInDisplayNames) {
|
|||
if (!reblog) {
|
||||
return
|
||||
}
|
||||
let accountDisplayName = getAccountAccessibleName(account, omitEmojiInDisplayNames)
|
||||
const accountDisplayName = getAccountAccessibleName(account, omitEmojiInDisplayNames)
|
||||
return `Boosted by ${accountDisplayName}`
|
||||
}
|
||||
|
||||
|
@ -37,11 +37,11 @@ export function getAccessibleLabelForStatus (originalAccount, account, plainText
|
|||
timeagoFormattedDate, spoilerText, showContent,
|
||||
reblog, notification, visibility, omitEmojiInDisplayNames,
|
||||
disableLongAriaLabels) {
|
||||
let originalAccountDisplayName = getAccountAccessibleName(originalAccount, omitEmojiInDisplayNames)
|
||||
let contentTextToShow = (showContent || !spoilerText)
|
||||
const originalAccountDisplayName = getAccountAccessibleName(originalAccount, omitEmojiInDisplayNames)
|
||||
const contentTextToShow = (showContent || !spoilerText)
|
||||
? cleanupText(plainTextContent)
|
||||
: `Content warning: ${cleanupText(spoilerText)}`
|
||||
let privacyText = getPrivacyText(visibility)
|
||||
const privacyText = getPrivacyText(visibility)
|
||||
|
||||
if (disableLongAriaLabels) {
|
||||
// Long text can crash NVDA; allow users to shorten it like we had it before.
|
||||
|
@ -49,7 +49,7 @@ export function getAccessibleLabelForStatus (originalAccount, account, plainText
|
|||
return `${privacyText} status by ${originalAccountDisplayName}`
|
||||
}
|
||||
|
||||
let values = [
|
||||
const values = [
|
||||
getNotificationText(notification, omitEmojiInDisplayNames),
|
||||
originalAccountDisplayName,
|
||||
contentTextToShow,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { removeEmoji } from '../_utils/removeEmoji'
|
||||
|
||||
export function getAccountAccessibleName (account, omitEmojiInDisplayNames) {
|
||||
let emojis = account.emojis
|
||||
const emojis = account.emojis
|
||||
let displayName = account.display_name || account.username
|
||||
if (omitEmojiInDisplayNames) {
|
||||
displayName = removeEmoji(displayName, emojis) || displayName
|
||||
|
|
|
@ -4,8 +4,8 @@ import { database } from '../_database/database'
|
|||
import { store } from '../_store/store'
|
||||
|
||||
async function _updateAccount (accountId, instanceName, accessToken) {
|
||||
let localPromise = database.getAccount(instanceName, accountId)
|
||||
let remotePromise = getAccount(instanceName, accessToken, accountId).then(account => {
|
||||
const localPromise = database.getAccount(instanceName, accountId)
|
||||
const remotePromise = getAccount(instanceName, accessToken, accountId).then(account => {
|
||||
/* no await */ database.setAccount(instanceName, account)
|
||||
return account
|
||||
})
|
||||
|
@ -23,8 +23,8 @@ async function _updateAccount (accountId, instanceName, accessToken) {
|
|||
}
|
||||
|
||||
async function _updateRelationship (accountId, instanceName, accessToken) {
|
||||
let localPromise = database.getRelationship(instanceName, accountId)
|
||||
let remotePromise = getRelationship(instanceName, accessToken, accountId).then(relationship => {
|
||||
const localPromise = database.getRelationship(instanceName, accountId)
|
||||
const remotePromise = getRelationship(instanceName, accessToken, accountId).then(relationship => {
|
||||
/* no await */ database.setRelationship(instanceName, relationship)
|
||||
return relationship
|
||||
})
|
||||
|
@ -57,7 +57,7 @@ export async function clearProfileAndRelationship () {
|
|||
}
|
||||
|
||||
export async function updateProfileAndRelationship (accountId) {
|
||||
let { currentInstance, accessToken } = store.get()
|
||||
const { currentInstance, accessToken } = store.get()
|
||||
|
||||
await Promise.all([
|
||||
_updateAccount(accountId, currentInstance, accessToken),
|
||||
|
@ -66,7 +66,7 @@ export async function updateProfileAndRelationship (accountId) {
|
|||
}
|
||||
|
||||
export async function updateRelationship (accountId) {
|
||||
let { currentInstance, accessToken } = store.get()
|
||||
const { currentInstance, accessToken } = store.get()
|
||||
|
||||
await _updateRelationship(accountId, currentInstance, accessToken)
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ const REDIRECT_URI = (typeof location !== 'undefined'
|
|||
? location.origin : 'https://pinafore.social') + '/settings/instances/add'
|
||||
|
||||
function createKnownError (message) {
|
||||
let err = new Error(message)
|
||||
const err = new Error(message)
|
||||
err.knownError = true
|
||||
return err
|
||||
}
|
||||
|
@ -23,20 +23,20 @@ async function redirectToOauth () {
|
|||
if (Object.keys(loggedInInstances).includes(instanceNameInSearch)) {
|
||||
throw createKnownError(`You've already logged in to ${instanceNameInSearch}`)
|
||||
}
|
||||
let instanceHostname = new URL(`http://${instanceNameInSearch}`).hostname
|
||||
const instanceHostname = new URL(`http://${instanceNameInSearch}`).hostname
|
||||
if (DOMAIN_BLOCKS.some(domain => new RegExp(`(?:\\.|^)${domain}$`, 'i').test(instanceHostname))) {
|
||||
throw createKnownError('This service is blocked')
|
||||
}
|
||||
let registrationPromise = registerApplication(instanceNameInSearch, REDIRECT_URI)
|
||||
let instanceInfo = await getInstanceInfo(instanceNameInSearch)
|
||||
const registrationPromise = registerApplication(instanceNameInSearch, REDIRECT_URI)
|
||||
const instanceInfo = await getInstanceInfo(instanceNameInSearch)
|
||||
await database.setInstanceInfo(instanceNameInSearch, instanceInfo) // cache for later
|
||||
let instanceData = await registrationPromise
|
||||
const instanceData = await registrationPromise
|
||||
store.set({
|
||||
currentRegisteredInstanceName: instanceNameInSearch,
|
||||
currentRegisteredInstance: instanceData
|
||||
})
|
||||
store.save()
|
||||
let oauthUrl = generateAuthLink(
|
||||
const oauthUrl = generateAuthLink(
|
||||
instanceNameInSearch,
|
||||
instanceData.client_id,
|
||||
REDIRECT_URI
|
||||
|
@ -53,12 +53,12 @@ export async function logInToInstance () {
|
|||
await redirectToOauth()
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
let error = `${err.message || err.name}. ` +
|
||||
const error = `${err.message || err.name}. ` +
|
||||
(err.knownError ? '' : (navigator.onLine
|
||||
? `Is this a valid Mastodon instance? Is a browser extension
|
||||
blocking the request? Are you in private browsing mode?`
|
||||
: `Are you offline?`))
|
||||
let { instanceNameInSearch } = store.get()
|
||||
const { instanceNameInSearch } = store.get()
|
||||
store.set({
|
||||
logInToInstanceError: error,
|
||||
logInToInstanceErrorForText: instanceNameInSearch
|
||||
|
@ -69,15 +69,15 @@ export async function logInToInstance () {
|
|||
}
|
||||
|
||||
async function registerNewInstance (code) {
|
||||
let { currentRegisteredInstanceName, currentRegisteredInstance } = store.get()
|
||||
let instanceData = await getAccessTokenFromAuthCode(
|
||||
const { currentRegisteredInstanceName, currentRegisteredInstance } = store.get()
|
||||
const instanceData = await getAccessTokenFromAuthCode(
|
||||
currentRegisteredInstanceName,
|
||||
currentRegisteredInstance.client_id,
|
||||
currentRegisteredInstance.client_secret,
|
||||
code,
|
||||
REDIRECT_URI
|
||||
)
|
||||
let { loggedInInstances, loggedInInstancesInOrder, instanceThemes } = store.get()
|
||||
const { loggedInInstances, loggedInInstancesInOrder, instanceThemes } = store.get()
|
||||
instanceThemes[currentRegisteredInstanceName] = DEFAULT_THEME
|
||||
loggedInInstances[currentRegisteredInstanceName] = instanceData
|
||||
if (!loggedInInstancesInOrder.includes(currentRegisteredInstanceName)) {
|
||||
|
@ -93,7 +93,7 @@ async function registerNewInstance (code) {
|
|||
instanceThemes: instanceThemes
|
||||
})
|
||||
store.save()
|
||||
let { enableGrayscale } = store.get()
|
||||
const { enableGrayscale } = store.get()
|
||||
switchToTheme(DEFAULT_THEME, enableGrayscale)
|
||||
// fire off these requests so they're cached
|
||||
/* no await */ updateVerifyCredentialsForInstance(currentRegisteredInstanceName)
|
||||
|
|
|
@ -8,13 +8,13 @@ import { scheduleIdleTask } from '../_utils/scheduleIdleTask'
|
|||
import { timelineItemToSummary } from '../_utils/timelineItemToSummary'
|
||||
|
||||
function getExistingItemIdsSet (instanceName, timelineName) {
|
||||
let timelineItemSummaries = store.getForTimeline(instanceName, timelineName, 'timelineItemSummaries') || []
|
||||
const timelineItemSummaries = store.getForTimeline(instanceName, timelineName, 'timelineItemSummaries') || []
|
||||
return new Set(timelineItemSummaries.map(_ => _.id))
|
||||
}
|
||||
|
||||
function removeDuplicates (instanceName, timelineName, updates) {
|
||||
// remove duplicates, including duplicates due to reblogs
|
||||
let existingItemIds = getExistingItemIdsSet(instanceName, timelineName)
|
||||
const existingItemIds = getExistingItemIdsSet(instanceName, timelineName)
|
||||
return updates.filter(update => !existingItemIds.has(update.id))
|
||||
}
|
||||
|
||||
|
@ -27,12 +27,12 @@ async function insertUpdatesIntoTimeline (instanceName, timelineName, updates) {
|
|||
|
||||
await database.insertTimelineItems(instanceName, timelineName, updates)
|
||||
|
||||
let itemSummariesToAdd = store.getForTimeline(instanceName, timelineName, 'timelineItemSummariesToAdd') || []
|
||||
const itemSummariesToAdd = store.getForTimeline(instanceName, timelineName, 'timelineItemSummariesToAdd') || []
|
||||
console.log('itemSummariesToAdd', JSON.parse(JSON.stringify(itemSummariesToAdd)))
|
||||
console.log('updates.map(timelineItemToSummary)', JSON.parse(JSON.stringify(updates.map(timelineItemToSummary))))
|
||||
console.log('concat(itemSummariesToAdd, updates.map(timelineItemToSummary))',
|
||||
JSON.parse(JSON.stringify(concat(itemSummariesToAdd, updates.map(timelineItemToSummary)))))
|
||||
let newItemSummariesToAdd = uniqBy(
|
||||
const newItemSummariesToAdd = uniqBy(
|
||||
concat(itemSummariesToAdd, updates.map(timelineItemToSummary)),
|
||||
_ => _.id
|
||||
)
|
||||
|
@ -44,12 +44,12 @@ async function insertUpdatesIntoTimeline (instanceName, timelineName, updates) {
|
|||
}
|
||||
|
||||
function isValidStatusForThread (thread, timelineName, itemSummariesToAdd) {
|
||||
let itemSummariesToAddIdSet = new Set(itemSummariesToAdd.map(_ => _.id))
|
||||
let threadIdSet = new Set(thread.map(_ => _.id))
|
||||
let focusedStatusId = timelineName.split('/')[1] // e.g. "status/123456"
|
||||
let focusedStatusIdx = thread.findIndex(_ => _.id === focusedStatusId)
|
||||
const itemSummariesToAddIdSet = new Set(itemSummariesToAdd.map(_ => _.id))
|
||||
const threadIdSet = new Set(thread.map(_ => _.id))
|
||||
const focusedStatusId = timelineName.split('/')[1] // e.g. "status/123456"
|
||||
const focusedStatusIdx = thread.findIndex(_ => _.id === focusedStatusId)
|
||||
return status => {
|
||||
let repliedToStatusIdx = thread.findIndex(_ => _.id === status.in_reply_to_id)
|
||||
const repliedToStatusIdx = thread.findIndex(_ => _.id === status.in_reply_to_id)
|
||||
return (
|
||||
// A reply to an ancestor status is not valid for this thread, but for the focused status
|
||||
// itself or any of its descendents, it is valid.
|
||||
|
@ -67,17 +67,17 @@ async function insertUpdatesIntoThreads (instanceName, updates) {
|
|||
return
|
||||
}
|
||||
|
||||
let threads = store.getThreads(instanceName)
|
||||
let timelineNames = Object.keys(threads)
|
||||
for (let timelineName of timelineNames) {
|
||||
let thread = threads[timelineName]
|
||||
const threads = store.getThreads(instanceName)
|
||||
const timelineNames = Object.keys(threads)
|
||||
for (const timelineName of timelineNames) {
|
||||
const thread = threads[timelineName]
|
||||
|
||||
let itemSummariesToAdd = store.getForTimeline(instanceName, timelineName, 'timelineItemSummariesToAdd') || []
|
||||
let validUpdates = updates.filter(isValidStatusForThread(thread, timelineName, itemSummariesToAdd))
|
||||
const itemSummariesToAdd = store.getForTimeline(instanceName, timelineName, 'timelineItemSummariesToAdd') || []
|
||||
const validUpdates = updates.filter(isValidStatusForThread(thread, timelineName, itemSummariesToAdd))
|
||||
if (!validUpdates.length) {
|
||||
continue
|
||||
}
|
||||
let newItemSummariesToAdd = uniqBy(
|
||||
const newItemSummariesToAdd = uniqBy(
|
||||
concat(itemSummariesToAdd, validUpdates.map(timelineItemToSummary)),
|
||||
_ => _.id
|
||||
)
|
||||
|
@ -91,9 +91,9 @@ async function insertUpdatesIntoThreads (instanceName, updates) {
|
|||
|
||||
async function processFreshUpdates (instanceName, timelineName) {
|
||||
mark('processFreshUpdates')
|
||||
let freshUpdates = store.getForTimeline(instanceName, timelineName, 'freshUpdates')
|
||||
const freshUpdates = store.getForTimeline(instanceName, timelineName, 'freshUpdates')
|
||||
if (freshUpdates && freshUpdates.length) {
|
||||
let updates = freshUpdates.slice()
|
||||
const updates = freshUpdates.slice()
|
||||
store.setForTimeline(instanceName, timelineName, { freshUpdates: [] })
|
||||
|
||||
await Promise.all([
|
||||
|
|
|
@ -1,59 +1,59 @@
|
|||
import { store } from '../_store/store'
|
||||
|
||||
export async function insertUsername (realm, username, startIndex, endIndex) {
|
||||
let { currentInstance } = store.get()
|
||||
let oldText = store.getComposeData(realm, 'text')
|
||||
let pre = oldText.substring(0, startIndex)
|
||||
let post = oldText.substring(endIndex)
|
||||
let newText = `${pre}@${username} ${post}`
|
||||
const { currentInstance } = store.get()
|
||||
const oldText = store.getComposeData(realm, 'text')
|
||||
const pre = oldText.substring(0, startIndex)
|
||||
const post = oldText.substring(endIndex)
|
||||
const newText = `${pre}@${username} ${post}`
|
||||
store.setComposeData(realm, { text: newText })
|
||||
store.setForAutosuggest(currentInstance, realm, { autosuggestSearchResults: [] })
|
||||
}
|
||||
|
||||
export async function clickSelectedAutosuggestionUsername (realm) {
|
||||
let {
|
||||
const {
|
||||
composeSelectionStart,
|
||||
autosuggestSearchText,
|
||||
autosuggestSelected,
|
||||
autosuggestSearchResults
|
||||
} = store.get()
|
||||
let account = autosuggestSearchResults[autosuggestSelected]
|
||||
let startIndex = composeSelectionStart - autosuggestSearchText.length
|
||||
let endIndex = composeSelectionStart
|
||||
const account = autosuggestSearchResults[autosuggestSelected]
|
||||
const startIndex = composeSelectionStart - autosuggestSearchText.length
|
||||
const endIndex = composeSelectionStart
|
||||
await insertUsername(realm, account.acct, startIndex, endIndex)
|
||||
}
|
||||
|
||||
export function insertEmojiAtPosition (realm, emoji, startIndex, endIndex) {
|
||||
let { currentInstance } = store.get()
|
||||
let oldText = store.getComposeData(realm, 'text') || ''
|
||||
let pre = oldText.substring(0, startIndex)
|
||||
let post = oldText.substring(endIndex)
|
||||
let newText = `${pre}:${emoji.shortcode}: ${post}`
|
||||
const { currentInstance } = store.get()
|
||||
const oldText = store.getComposeData(realm, 'text') || ''
|
||||
const pre = oldText.substring(0, startIndex)
|
||||
const post = oldText.substring(endIndex)
|
||||
const newText = `${pre}:${emoji.shortcode}: ${post}`
|
||||
store.setComposeData(realm, { text: newText })
|
||||
store.setForAutosuggest(currentInstance, realm, { autosuggestSearchResults: [] })
|
||||
}
|
||||
|
||||
export async function clickSelectedAutosuggestionEmoji (realm) {
|
||||
let {
|
||||
const {
|
||||
composeSelectionStart,
|
||||
autosuggestSearchText,
|
||||
autosuggestSelected,
|
||||
autosuggestSearchResults
|
||||
} = store.get()
|
||||
let emoji = autosuggestSearchResults[autosuggestSelected]
|
||||
let startIndex = composeSelectionStart - autosuggestSearchText.length
|
||||
let endIndex = composeSelectionStart
|
||||
const emoji = autosuggestSearchResults[autosuggestSelected]
|
||||
const startIndex = composeSelectionStart - autosuggestSearchText.length
|
||||
const endIndex = composeSelectionStart
|
||||
await insertEmojiAtPosition(realm, emoji, startIndex, endIndex)
|
||||
}
|
||||
|
||||
export function selectAutosuggestItem (item) {
|
||||
let {
|
||||
const {
|
||||
currentComposeRealm,
|
||||
composeSelectionStart,
|
||||
autosuggestSearchText
|
||||
} = store.get()
|
||||
let startIndex = composeSelectionStart - autosuggestSearchText.length
|
||||
let endIndex = composeSelectionStart
|
||||
const startIndex = composeSelectionStart - autosuggestSearchText.length
|
||||
const endIndex = composeSelectionStart
|
||||
if (item.acct) {
|
||||
/* no await */ insertUsername(currentComposeRealm, item.acct, startIndex, endIndex)
|
||||
} else {
|
||||
|
|
|
@ -11,8 +11,8 @@ const DATABASE_SEARCH_RESULTS_LIMIT = 30
|
|||
const promiseThrottler = new PromiseThrottler(200) // Mastodon FE also uses 200ms
|
||||
|
||||
function byUsername (a, b) {
|
||||
let usernameA = a.acct.toLowerCase()
|
||||
let usernameB = b.acct.toLowerCase()
|
||||
const usernameA = a.acct.toLowerCase()
|
||||
const usernameB = b.acct.toLowerCase()
|
||||
|
||||
return usernameA < usernameB ? -1 : usernameA === usernameB ? 0 : 1
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ export function doAccountSearch (searchText) {
|
|||
let canceled = false
|
||||
let localResults
|
||||
let remoteResults
|
||||
let { currentInstance, accessToken } = store.get()
|
||||
const { currentInstance, accessToken } = store.get()
|
||||
let controller = typeof AbortController === 'function' && new AbortController()
|
||||
|
||||
function abortFetch () {
|
||||
|
@ -60,7 +60,7 @@ export function doAccountSearch (searchText) {
|
|||
.slice(0, SEARCH_RESULTS_LIMIT)
|
||||
|
||||
if (results.length < SEARCH_RESULTS_LIMIT) {
|
||||
let topRemoteResults = (remoteResults || [])
|
||||
const topRemoteResults = (remoteResults || [])
|
||||
.sort(byUsername)
|
||||
.slice(0, SEARCH_RESULTS_LIMIT - results.length)
|
||||
results = concat(results, topRemoteResults)
|
||||
|
@ -74,7 +74,7 @@ export function doAccountSearch (searchText) {
|
|||
if (canceled) {
|
||||
return
|
||||
}
|
||||
let results = mergeAndTruncateResults()
|
||||
const results = mergeAndTruncateResults()
|
||||
store.setForCurrentAutosuggest({
|
||||
autosuggestType: 'account',
|
||||
autosuggestSelected: 0,
|
||||
|
|
|
@ -4,8 +4,8 @@ import { scheduleIdleTask } from '../_utils/scheduleIdleTask'
|
|||
|
||||
function searchEmoji (searchText) {
|
||||
searchText = searchText.toLowerCase().substring(1)
|
||||
let { currentCustomEmoji } = store.get()
|
||||
let results = currentCustomEmoji.filter(emoji => emoji.shortcode.toLowerCase().startsWith(searchText))
|
||||
const { currentCustomEmoji } = store.get()
|
||||
const results = currentCustomEmoji.filter(emoji => emoji.shortcode.toLowerCase().startsWith(searchText))
|
||||
.sort((a, b) => a.shortcode.toLowerCase() < b.shortcode.toLowerCase() ? -1 : 1)
|
||||
.slice(0, SEARCH_RESULTS_LIMIT)
|
||||
return results
|
||||
|
@ -18,7 +18,7 @@ export function doEmojiSearch (searchText) {
|
|||
if (canceled) {
|
||||
return
|
||||
}
|
||||
let results = searchEmoji(searchText)
|
||||
const results = searchEmoji(searchText)
|
||||
store.setForCurrentAutosuggest({
|
||||
autosuggestType: 'emoji',
|
||||
autosuggestSelected: 0,
|
||||
|
|
|
@ -5,7 +5,7 @@ import { updateLocalRelationship } from './accounts'
|
|||
import { emit } from '../_utils/eventBus'
|
||||
|
||||
export async function setAccountBlocked (accountId, block, toastOnSuccess) {
|
||||
let { currentInstance, accessToken } = store.get()
|
||||
const { currentInstance, accessToken } = store.get()
|
||||
try {
|
||||
let relationship
|
||||
if (block) {
|
||||
|
|
|
@ -7,11 +7,11 @@ import { emit } from '../_utils/eventBus'
|
|||
import { putMediaMetadata } from '../_api/media'
|
||||
|
||||
export async function insertHandleForReply (statusId) {
|
||||
let { currentInstance } = store.get()
|
||||
let status = await database.getStatus(currentInstance, statusId)
|
||||
let { currentVerifyCredentials } = store.get()
|
||||
let originalStatus = status.reblog || status
|
||||
let accounts = [originalStatus.account].concat(originalStatus.mentions || [])
|
||||
const { currentInstance } = store.get()
|
||||
const status = await database.getStatus(currentInstance, statusId)
|
||||
const { currentVerifyCredentials } = store.get()
|
||||
const originalStatus = status.reblog || status
|
||||
const accounts = [originalStatus.account].concat(originalStatus.mentions || [])
|
||||
.filter(account => account.id !== currentVerifyCredentials.id)
|
||||
if (!store.getComposeData(statusId, 'text') && accounts.length) {
|
||||
store.setComposeData(statusId, {
|
||||
|
@ -23,7 +23,7 @@ export async function insertHandleForReply (statusId) {
|
|||
export async function postStatus (realm, text, inReplyToId, mediaIds,
|
||||
sensitive, spoilerText, visibility,
|
||||
mediaDescriptions, inReplyToUuid, poll, mediaFocalPoints) {
|
||||
let { currentInstance, accessToken, online } = store.get()
|
||||
const { currentInstance, accessToken, online } = store.get()
|
||||
|
||||
if (!online) {
|
||||
toast.say('You cannot post while offline')
|
||||
|
@ -32,7 +32,7 @@ export async function postStatus (realm, text, inReplyToId, mediaIds,
|
|||
|
||||
text = text || ''
|
||||
|
||||
let mediaMetadata = (mediaIds || []).map((mediaId, idx) => {
|
||||
const mediaMetadata = (mediaIds || []).map((mediaId, idx) => {
|
||||
return {
|
||||
description: mediaDescriptions && mediaDescriptions[idx],
|
||||
focalPoint: mediaFocalPoints && mediaFocalPoints[idx]
|
||||
|
@ -50,7 +50,7 @@ export async function postStatus (realm, text, inReplyToId, mediaIds,
|
|||
return putMediaMetadata(currentInstance, accessToken, mediaIds[i], description, focalPoint)
|
||||
}
|
||||
}))
|
||||
let status = await postStatusToServer(currentInstance, accessToken, text,
|
||||
const status = await postStatusToServer(currentInstance, accessToken, text,
|
||||
inReplyToId, mediaIds, sensitive, spoilerText, visibility, poll, mediaFocalPoints)
|
||||
addStatusOrNotification(currentInstance, 'home', status)
|
||||
store.clearComposeData(realm)
|
||||
|
@ -64,8 +64,8 @@ export async function postStatus (realm, text, inReplyToId, mediaIds,
|
|||
}
|
||||
|
||||
export function setReplySpoiler (realm, spoiler) {
|
||||
let contentWarning = store.getComposeData(realm, 'contentWarning')
|
||||
let contentWarningShown = store.getComposeData(realm, 'contentWarningShown')
|
||||
const contentWarning = store.getComposeData(realm, 'contentWarning')
|
||||
const contentWarningShown = store.getComposeData(realm, 'contentWarningShown')
|
||||
if (typeof contentWarningShown !== 'undefined' || contentWarning) {
|
||||
return // user has already interacted with the CW
|
||||
}
|
||||
|
@ -76,22 +76,22 @@ export function setReplySpoiler (realm, spoiler) {
|
|||
}
|
||||
|
||||
const PRIVACY_LEVEL = {
|
||||
'direct': 1,
|
||||
'private': 2,
|
||||
'unlisted': 3,
|
||||
'public': 4
|
||||
direct: 1,
|
||||
private: 2,
|
||||
unlisted: 3,
|
||||
public: 4
|
||||
}
|
||||
|
||||
export function setReplyVisibility (realm, replyVisibility) {
|
||||
// return the most private between the user's preferred default privacy
|
||||
// and the privacy of the status they're replying to
|
||||
let postPrivacy = store.getComposeData(realm, 'postPrivacy')
|
||||
const postPrivacy = store.getComposeData(realm, 'postPrivacy')
|
||||
if (typeof postPrivacy !== 'undefined') {
|
||||
return // user has already set the postPrivacy
|
||||
}
|
||||
let { currentVerifyCredentials } = store.get()
|
||||
let defaultVisibility = currentVerifyCredentials.source.privacy
|
||||
let visibility = PRIVACY_LEVEL[replyVisibility] < PRIVACY_LEVEL[defaultVisibility]
|
||||
const { currentVerifyCredentials } = store.get()
|
||||
const defaultVisibility = currentVerifyCredentials.source.privacy
|
||||
const visibility = PRIVACY_LEVEL[replyVisibility] < PRIVACY_LEVEL[defaultVisibility]
|
||||
? replyVisibility
|
||||
: defaultVisibility
|
||||
store.setComposeData(realm, { postPrivacy: visibility })
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { store } from '../_store/store'
|
||||
|
||||
export function toggleContentWarningShown (realm) {
|
||||
let shown = store.getComposeData(realm, 'contentWarningShown')
|
||||
let contentWarning = store.getComposeData(realm, 'contentWarning')
|
||||
let newShown = !shown
|
||||
const shown = store.getComposeData(realm, 'contentWarningShown')
|
||||
const contentWarning = store.getComposeData(realm, 'contentWarning')
|
||||
const newShown = !shown
|
||||
store.setComposeData(realm, {
|
||||
contentWarning: newShown ? contentWarning : '',
|
||||
contentWarningShown: newShown
|
||||
|
|
|
@ -12,6 +12,6 @@ export async function copyText (text) {
|
|||
}
|
||||
}
|
||||
|
||||
let showCopyDialog = await importShowCopyDialog()
|
||||
const showCopyDialog = await importShowCopyDialog()
|
||||
showCopyDialog(text)
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ export function createMakeProps (instanceName, timelineType, timelineValue) {
|
|||
|
||||
return (itemId) => {
|
||||
taskCount++
|
||||
let promise = timelineType === 'notifications'
|
||||
const promise = timelineType === 'notifications'
|
||||
? getNotification(instanceName, timelineType, timelineValue, itemId)
|
||||
: getStatus(instanceName, timelineType, timelineValue, itemId)
|
||||
|
||||
|
|
|
@ -4,9 +4,9 @@ import { toast } from '../_components/toast/toast'
|
|||
import { deleteStatus as deleteStatusLocally } from './deleteStatuses'
|
||||
|
||||
export async function doDeleteStatus (statusId) {
|
||||
let { currentInstance, accessToken } = store.get()
|
||||
const { currentInstance, accessToken } = store.get()
|
||||
try {
|
||||
let deletedStatus = await deleteStatus(currentInstance, accessToken, statusId)
|
||||
const deletedStatus = await deleteStatus(currentInstance, accessToken, statusId)
|
||||
deleteStatusLocally(currentInstance, statusId)
|
||||
toast.say('Status deleted.')
|
||||
return deletedStatus
|
||||
|
|
|
@ -4,9 +4,9 @@ import { doDeleteStatus } from './delete'
|
|||
import { store } from '../_store/store'
|
||||
|
||||
export async function deleteAndRedraft (status) {
|
||||
let deleteStatusPromise = doDeleteStatus(status.id)
|
||||
let dialogPromise = importShowComposeDialog()
|
||||
let deletedStatus = await deleteStatusPromise
|
||||
const deleteStatusPromise = doDeleteStatus(status.id)
|
||||
const dialogPromise = importShowComposeDialog()
|
||||
const deletedStatus = await deleteStatusPromise
|
||||
|
||||
store.setComposeData('dialog', {
|
||||
text: deletedStatus.text || statusHtmlToPlainText(status.content, status.mentions),
|
||||
|
@ -24,6 +24,6 @@ export async function deleteAndRedraft (status) {
|
|||
options: (status.poll.options || []).map(option => option.title)
|
||||
}
|
||||
})
|
||||
let showComposeDialog = await dialogPromise
|
||||
const showComposeDialog = await dialogPromise
|
||||
showComposeDialog()
|
||||
}
|
||||
|
|
|
@ -5,17 +5,17 @@ import { database } from '../_database/database'
|
|||
import { scheduleIdleTask } from '../_utils/scheduleIdleTask'
|
||||
|
||||
function filterItemIdsFromTimelines (instanceName, timelineFilter, idFilter) {
|
||||
let keys = ['timelineItemSummaries', 'timelineItemSummariesToAdd']
|
||||
let summaryFilter = _ => idFilter(_.id)
|
||||
const keys = ['timelineItemSummaries', 'timelineItemSummariesToAdd']
|
||||
const summaryFilter = _ => idFilter(_.id)
|
||||
|
||||
keys.forEach(key => {
|
||||
let timelineData = store.getAllTimelineData(instanceName, key)
|
||||
const timelineData = store.getAllTimelineData(instanceName, key)
|
||||
Object.keys(timelineData).forEach(timelineName => {
|
||||
let summaries = timelineData[timelineName]
|
||||
const summaries = timelineData[timelineName]
|
||||
if (!timelineFilter(timelineName)) {
|
||||
return
|
||||
}
|
||||
let filteredSummaries = summaries.filter(summaryFilter)
|
||||
const filteredSummaries = summaries.filter(summaryFilter)
|
||||
if (!isEqual(summaries, filteredSummaries)) {
|
||||
console.log('deleting an item from timelineName', timelineName, 'for key', key)
|
||||
store.setForTimeline(instanceName, timelineName, {
|
||||
|
@ -27,17 +27,17 @@ function filterItemIdsFromTimelines (instanceName, timelineFilter, idFilter) {
|
|||
}
|
||||
|
||||
function deleteStatusIdsFromStore (instanceName, idsToDelete) {
|
||||
let idsToDeleteSet = new Set(idsToDelete)
|
||||
let idWasNotDeleted = id => !idsToDeleteSet.has(id)
|
||||
let notNotificationTimeline = timelineName => timelineName !== 'notifications'
|
||||
const idsToDeleteSet = new Set(idsToDelete)
|
||||
const idWasNotDeleted = id => !idsToDeleteSet.has(id)
|
||||
const notNotificationTimeline = timelineName => timelineName !== 'notifications'
|
||||
|
||||
filterItemIdsFromTimelines(instanceName, notNotificationTimeline, idWasNotDeleted)
|
||||
}
|
||||
|
||||
function deleteNotificationIdsFromStore (instanceName, idsToDelete) {
|
||||
let idsToDeleteSet = new Set(idsToDelete)
|
||||
let idWasNotDeleted = id => !idsToDeleteSet.has(id)
|
||||
let isNotificationTimeline = timelineName => timelineName === 'notifications'
|
||||
const idsToDeleteSet = new Set(idsToDelete)
|
||||
const idWasNotDeleted = id => !idsToDeleteSet.has(id)
|
||||
const isNotificationTimeline = timelineName => timelineName === 'notifications'
|
||||
|
||||
filterItemIdsFromTimelines(instanceName, isNotificationTimeline, idWasNotDeleted)
|
||||
}
|
||||
|
@ -50,9 +50,9 @@ async function deleteStatusesAndNotifications (instanceName, statusIdsToDelete,
|
|||
|
||||
async function doDeleteStatus (instanceName, statusId) {
|
||||
console.log('deleting statusId', statusId)
|
||||
let rebloggedIds = await getIdsThatRebloggedThisStatus(instanceName, statusId)
|
||||
let statusIdsToDelete = Array.from(new Set([statusId].concat(rebloggedIds).filter(Boolean)))
|
||||
let notificationIdsToDelete = Array.from(new Set(await getNotificationIdsForStatuses(instanceName, statusIdsToDelete)))
|
||||
const rebloggedIds = await getIdsThatRebloggedThisStatus(instanceName, statusId)
|
||||
const statusIdsToDelete = Array.from(new Set([statusId].concat(rebloggedIds).filter(Boolean)))
|
||||
const notificationIdsToDelete = Array.from(new Set(await getNotificationIdsForStatuses(instanceName, statusIdsToDelete)))
|
||||
await deleteStatusesAndNotifications(instanceName, statusIdsToDelete, notificationIdsToDelete)
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ export async function updateCustomEmojiForInstance (instanceName) {
|
|||
() => database.getCustomEmoji(instanceName),
|
||||
emoji => database.setCustomEmoji(instanceName, emoji),
|
||||
emoji => {
|
||||
let { customEmoji } = store.get()
|
||||
const { customEmoji } = store.get()
|
||||
customEmoji[instanceName] = emoji
|
||||
store.set({ customEmoji: customEmoji })
|
||||
}
|
||||
|
@ -17,12 +17,12 @@ export async function updateCustomEmojiForInstance (instanceName) {
|
|||
}
|
||||
|
||||
export function insertEmoji (realm, emoji) {
|
||||
let emojiText = emoji.custom ? emoji.colons : emoji.native
|
||||
let { composeSelectionStart } = store.get()
|
||||
let idx = composeSelectionStart || 0
|
||||
let oldText = store.getComposeData(realm, 'text') || ''
|
||||
let pre = oldText.substring(0, idx)
|
||||
let post = oldText.substring(idx)
|
||||
let newText = `${pre}${emojiText} ${post}`
|
||||
const emojiText = emoji.custom ? emoji.colons : emoji.native
|
||||
const { composeSelectionStart } = store.get()
|
||||
const idx = composeSelectionStart || 0
|
||||
const oldText = store.getComposeData(realm, 'text') || ''
|
||||
const pre = oldText.substring(0, idx)
|
||||
const post = oldText.substring(idx)
|
||||
const newText = `${pre}${emojiText} ${post}`
|
||||
store.setComposeData(realm, { text: newText })
|
||||
}
|
||||
|
|
|
@ -4,13 +4,13 @@ import { toast } from '../_components/toast/toast'
|
|||
import { database } from '../_database/database'
|
||||
|
||||
export async function setFavorited (statusId, favorited) {
|
||||
let { online } = store.get()
|
||||
const { online } = store.get()
|
||||
if (!online) {
|
||||
toast.say(`You cannot ${favorited ? 'favorite' : 'unfavorite'} while offline.`)
|
||||
return
|
||||
}
|
||||
let { currentInstance, accessToken } = store.get()
|
||||
let networkPromise = favorited
|
||||
const { currentInstance, accessToken } = store.get()
|
||||
const networkPromise = favorited
|
||||
? favoriteStatus(currentInstance, accessToken, statusId)
|
||||
: unfavoriteStatus(currentInstance, accessToken, statusId)
|
||||
store.setStatusFavorited(currentInstance, statusId, favorited) // optimistic update
|
||||
|
|
|
@ -4,7 +4,7 @@ import { toast } from '../_components/toast/toast'
|
|||
import { updateLocalRelationship } from './accounts'
|
||||
|
||||
export async function setAccountFollowed (accountId, follow, toastOnSuccess) {
|
||||
let { currentInstance, accessToken } = store.get()
|
||||
const { currentInstance, accessToken } = store.get()
|
||||
try {
|
||||
let relationship
|
||||
if (follow) {
|
||||
|
|
|
@ -2,16 +2,16 @@ import { DEFAULT_TIMEOUT, get, post, WRITE_TIMEOUT } from '../_utils/ajax'
|
|||
import { auth, basename } from '../_api/utils'
|
||||
|
||||
export async function getFollowRequests (instanceName, accessToken) {
|
||||
let url = `${basename(instanceName)}/api/v1/follow_requests`
|
||||
const url = `${basename(instanceName)}/api/v1/follow_requests`
|
||||
return get(url, auth(accessToken), { timeout: DEFAULT_TIMEOUT })
|
||||
}
|
||||
|
||||
export async function authorizeFollowRequest (instanceName, accessToken, id) {
|
||||
let url = `${basename(instanceName)}/api/v1/follow_requests/${id}/authorize`
|
||||
const url = `${basename(instanceName)}/api/v1/follow_requests/${id}/authorize`
|
||||
return post(url, null, auth(accessToken), { timeout: WRITE_TIMEOUT })
|
||||
}
|
||||
|
||||
export async function rejectFollowRequest (instanceName, accessToken, id) {
|
||||
let url = `${basename(instanceName)}/api/v1/follow_requests/${id}/reject`
|
||||
const url = `${basename(instanceName)}/api/v1/follow_requests/${id}/reject`
|
||||
return post(url, null, auth(accessToken), { timeout: WRITE_TIMEOUT })
|
||||
}
|
||||
|
|
|
@ -8,31 +8,31 @@ import { getInstanceInfo } from '../_api/instance'
|
|||
import { database } from '../_database/database'
|
||||
|
||||
export function changeTheme (instanceName, newTheme) {
|
||||
let { instanceThemes } = store.get()
|
||||
const { instanceThemes } = store.get()
|
||||
instanceThemes[instanceName] = newTheme
|
||||
store.set({ instanceThemes: instanceThemes })
|
||||
store.save()
|
||||
let { currentInstance } = store.get()
|
||||
const { currentInstance } = store.get()
|
||||
if (instanceName === currentInstance) {
|
||||
let { enableGrayscale } = store.get()
|
||||
const { enableGrayscale } = store.get()
|
||||
switchToTheme(newTheme, enableGrayscale)
|
||||
}
|
||||
}
|
||||
|
||||
export function switchToInstance (instanceName) {
|
||||
let { instanceThemes } = store.get()
|
||||
const { instanceThemes } = store.get()
|
||||
store.set({
|
||||
currentInstance: instanceName,
|
||||
searchResults: null,
|
||||
queryInSearch: ''
|
||||
})
|
||||
store.save()
|
||||
let { enableGrayscale } = store.get()
|
||||
const { enableGrayscale } = store.get()
|
||||
switchToTheme(instanceThemes[instanceName], enableGrayscale)
|
||||
}
|
||||
|
||||
export async function logOutOfInstance (instanceName) {
|
||||
let {
|
||||
const {
|
||||
loggedInInstances,
|
||||
instanceThemes,
|
||||
loggedInInstancesInOrder,
|
||||
|
@ -40,7 +40,7 @@ export async function logOutOfInstance (instanceName) {
|
|||
currentInstance
|
||||
} = store.get()
|
||||
loggedInInstancesInOrder.splice(loggedInInstancesInOrder.indexOf(instanceName), 1)
|
||||
let newInstance = instanceName === currentInstance
|
||||
const newInstance = instanceName === currentInstance
|
||||
? loggedInInstancesInOrder[0]
|
||||
: currentInstance
|
||||
delete loggedInInstances[instanceName]
|
||||
|
@ -57,21 +57,21 @@ export async function logOutOfInstance (instanceName) {
|
|||
})
|
||||
store.save()
|
||||
toast.say(`Logged out of ${instanceName}`)
|
||||
let { enableGrayscale } = store.get()
|
||||
const { enableGrayscale } = store.get()
|
||||
switchToTheme(instanceThemes[newInstance], enableGrayscale)
|
||||
/* no await */ database.clearDatabaseForInstance(instanceName)
|
||||
goto('/settings/instances')
|
||||
}
|
||||
|
||||
function setStoreVerifyCredentials (instanceName, thisVerifyCredentials) {
|
||||
let { verifyCredentials } = store.get()
|
||||
const { verifyCredentials } = store.get()
|
||||
verifyCredentials[instanceName] = thisVerifyCredentials
|
||||
store.set({ verifyCredentials: verifyCredentials })
|
||||
}
|
||||
|
||||
export async function updateVerifyCredentialsForInstance (instanceName) {
|
||||
let { loggedInInstances } = store.get()
|
||||
let accessToken = loggedInInstances[instanceName].access_token
|
||||
const { loggedInInstances } = store.get()
|
||||
const accessToken = loggedInInstances[instanceName].access_token
|
||||
await cacheFirstUpdateAfter(
|
||||
() => getVerifyCredentials(instanceName, accessToken),
|
||||
() => database.getInstanceVerifyCredentials(instanceName),
|
||||
|
@ -81,7 +81,7 @@ export async function updateVerifyCredentialsForInstance (instanceName) {
|
|||
}
|
||||
|
||||
export async function updateVerifyCredentialsForCurrentInstance () {
|
||||
let { currentInstance } = store.get()
|
||||
const { currentInstance } = store.get()
|
||||
await updateVerifyCredentialsForInstance(currentInstance)
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ export async function updateInstanceInfo (instanceName) {
|
|||
() => database.getInstanceInfo(instanceName),
|
||||
info => database.setInstanceInfo(instanceName, info),
|
||||
info => {
|
||||
let { instanceInfos } = store.get()
|
||||
const { instanceInfos } = store.get()
|
||||
instanceInfos[instanceName] = info
|
||||
store.set({ instanceInfos: instanceInfos })
|
||||
}
|
||||
|
|
|
@ -4,15 +4,15 @@ import { cacheFirstUpdateAfter } from '../_utils/sync'
|
|||
import { database } from '../_database/database'
|
||||
|
||||
export async function updateListsForInstance (instanceName) {
|
||||
let { loggedInInstances } = store.get()
|
||||
let accessToken = loggedInInstances[instanceName].access_token
|
||||
const { loggedInInstances } = store.get()
|
||||
const accessToken = loggedInInstances[instanceName].access_token
|
||||
|
||||
await cacheFirstUpdateAfter(
|
||||
() => getLists(instanceName, accessToken),
|
||||
() => database.getLists(instanceName),
|
||||
lists => database.setLists(instanceName, lists),
|
||||
lists => {
|
||||
let { instanceLists } = store.get()
|
||||
const { instanceLists } = store.get()
|
||||
instanceLists[instanceName] = lists
|
||||
store.set({ instanceLists: instanceLists })
|
||||
}
|
||||
|
|
|
@ -4,11 +4,11 @@ import { toast } from '../_components/toast/toast'
|
|||
import { scheduleIdleTask } from '../_utils/scheduleIdleTask'
|
||||
|
||||
export async function doMediaUpload (realm, file) {
|
||||
let { currentInstance, accessToken } = store.get()
|
||||
const { currentInstance, accessToken } = store.get()
|
||||
store.set({ uploadingMedia: true })
|
||||
try {
|
||||
let response = await uploadMedia(currentInstance, accessToken, file)
|
||||
let composeMedia = store.getComposeData(realm, 'media') || []
|
||||
const response = await uploadMedia(currentInstance, accessToken, file)
|
||||
const composeMedia = store.getComposeData(realm, 'media') || []
|
||||
if (composeMedia.length === 4) {
|
||||
throw new Error('Only 4 media max are allowed')
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ export async function doMediaUpload (realm, file) {
|
|||
}
|
||||
|
||||
export function deleteMedia (realm, i) {
|
||||
let composeMedia = store.getComposeData(realm, 'media')
|
||||
const composeMedia = store.getComposeData(realm, 'media')
|
||||
composeMedia.splice(i, 1)
|
||||
|
||||
store.setComposeData(realm, {
|
||||
|
|
|
@ -3,6 +3,6 @@ import { store } from '../_store/store'
|
|||
|
||||
export async function composeNewStatusMentioning (account) {
|
||||
store.setComposeData('dialog', { text: `@${account.acct} ` })
|
||||
let showComposeDialog = await importShowComposeDialog()
|
||||
const showComposeDialog = await importShowComposeDialog()
|
||||
showComposeDialog()
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import { updateLocalRelationship } from './accounts'
|
|||
import { emit } from '../_utils/eventBus'
|
||||
|
||||
export async function setAccountMuted (accountId, mute, notifications, toastOnSuccess) {
|
||||
let { currentInstance, accessToken } = store.get()
|
||||
const { currentInstance, accessToken } = store.get()
|
||||
try {
|
||||
let relationship
|
||||
if (mute) {
|
||||
|
|
|
@ -4,7 +4,7 @@ import { toast } from '../_components/toast/toast'
|
|||
import { database } from '../_database/database'
|
||||
|
||||
export async function setConversationMuted (statusId, mute, toastOnSuccess) {
|
||||
let { currentInstance, accessToken } = store.get()
|
||||
const { currentInstance, accessToken } = store.get()
|
||||
try {
|
||||
if (mute) {
|
||||
await muteConversation(currentInstance, accessToken, statusId)
|
||||
|
|
|
@ -4,7 +4,7 @@ export function onUserIsLoggedOut () {
|
|||
if (document.getElementById('hiddenFromSsrStyle')) {
|
||||
return
|
||||
}
|
||||
let style = document.createElement('style')
|
||||
const style = document.createElement('style')
|
||||
style.setAttribute('id', 'hiddenFromSsrStyle')
|
||||
style.textContent = '.hidden-from-ssr { opacity: 1 !important; }'
|
||||
document.head.appendChild(style)
|
||||
|
|
|
@ -5,7 +5,7 @@ import { database } from '../_database/database'
|
|||
import { emit } from '../_utils/eventBus'
|
||||
|
||||
export async function setStatusPinnedOrUnpinned (statusId, pinned, toastOnSuccess) {
|
||||
let { currentInstance, accessToken } = store.get()
|
||||
const { currentInstance, accessToken } = store.get()
|
||||
try {
|
||||
if (pinned) {
|
||||
await pinStatus(currentInstance, accessToken, statusId)
|
||||
|
|
|
@ -6,12 +6,12 @@ import {
|
|||
} from '../_api/pinnedStatuses'
|
||||
|
||||
export async function updatePinnedStatusesForAccount (accountId) {
|
||||
let { currentInstance, accessToken } = store.get()
|
||||
const { currentInstance, accessToken } = store.get()
|
||||
|
||||
await cacheFirstUpdateAfter(
|
||||
() => getPinnedStatuses(currentInstance, accessToken, accountId),
|
||||
async () => {
|
||||
let pinnedStatuses = await database.getPinnedStatuses(currentInstance, accountId)
|
||||
const pinnedStatuses = await database.getPinnedStatuses(currentInstance, accountId)
|
||||
if (!pinnedStatuses || !pinnedStatuses.every(Boolean)) {
|
||||
throw new Error('missing pinned statuses in idb')
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ export async function updatePinnedStatusesForAccount (accountId) {
|
|||
},
|
||||
statuses => database.insertPinnedStatuses(currentInstance, accountId, statuses),
|
||||
statuses => {
|
||||
let { pinnedStatuses } = store.get()
|
||||
const { pinnedStatuses } = store.get()
|
||||
pinnedStatuses[currentInstance] = pinnedStatuses[currentInstance] || {}
|
||||
pinnedStatuses[currentInstance][accountId] = statuses
|
||||
store.set({ pinnedStatuses: pinnedStatuses })
|
||||
|
|
|
@ -3,9 +3,9 @@ import { store } from '../_store/store'
|
|||
import { toast } from '../_components/toast/toast'
|
||||
|
||||
export async function getPoll (pollId) {
|
||||
let { currentInstance, accessToken } = store.get()
|
||||
const { currentInstance, accessToken } = store.get()
|
||||
try {
|
||||
let poll = await getPollApi(currentInstance, accessToken, pollId)
|
||||
const poll = await getPollApi(currentInstance, accessToken, pollId)
|
||||
return poll
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
|
@ -14,9 +14,9 @@ export async function getPoll (pollId) {
|
|||
}
|
||||
|
||||
export async function voteOnPoll (pollId, choices) {
|
||||
let { currentInstance, accessToken } = store.get()
|
||||
const { currentInstance, accessToken } = store.get()
|
||||
try {
|
||||
let poll = await voteOnPollApi(currentInstance, accessToken, pollId, choices.map(_ => _.toString()))
|
||||
const poll = await voteOnPollApi(currentInstance, accessToken, pollId, choices.map(_ => _.toString()))
|
||||
return poll
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
|
|
|
@ -4,13 +4,13 @@ import { reblogStatus, unreblogStatus } from '../_api/reblog'
|
|||
import { database } from '../_database/database'
|
||||
|
||||
export async function setReblogged (statusId, reblogged) {
|
||||
let online = store.get()
|
||||
const online = store.get()
|
||||
if (!online) {
|
||||
toast.say(`You cannot ${reblogged ? 'boost' : 'unboost'} while offline.`)
|
||||
return
|
||||
}
|
||||
let { currentInstance, accessToken } = store.get()
|
||||
let networkPromise = reblogged
|
||||
const { currentInstance, accessToken } = store.get()
|
||||
const networkPromise = reblogged
|
||||
? reblogStatus(currentInstance, accessToken, statusId)
|
||||
: unreblogStatus(currentInstance, accessToken, statusId)
|
||||
store.setStatusReblogged(currentInstance, statusId, reblogged) // optimistic update
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { importShowReportDialog } from '../_components/dialog/asyncDialogs'
|
||||
|
||||
export async function reportStatusOrAccount ({ status, account }) {
|
||||
let showReportDialog = await importShowReportDialog()
|
||||
const showReportDialog = await importShowReportDialog()
|
||||
showReportDialog({ status, account })
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import { toast } from '../_components/toast/toast'
|
|||
import { report } from '../_api/report'
|
||||
|
||||
export async function reportStatuses (account, statusIds, comment, forward) {
|
||||
let { currentInstance, accessToken } = store.get()
|
||||
const { currentInstance, accessToken } = store.get()
|
||||
try {
|
||||
await report(currentInstance, accessToken, account.id, statusIds, comment, forward)
|
||||
toast.say('Submitted report')
|
||||
|
|
|
@ -4,7 +4,7 @@ import { emit } from '../_utils/eventBus'
|
|||
import { toast } from '../_components/toast/toast'
|
||||
|
||||
export async function setFollowRequestApprovedOrRejected (accountId, approved, toastOnSuccess) {
|
||||
let {
|
||||
const {
|
||||
currentInstance,
|
||||
accessToken
|
||||
} = store.get()
|
||||
|
|
|
@ -3,11 +3,11 @@ import { toast } from '../_components/toast/toast'
|
|||
import { search } from '../_api/search'
|
||||
|
||||
export async function doSearch () {
|
||||
let { currentInstance, accessToken, queryInSearch } = store.get()
|
||||
const { currentInstance, accessToken, queryInSearch } = store.get()
|
||||
store.set({ searchLoading: true })
|
||||
try {
|
||||
let results = await search(currentInstance, accessToken, queryInSearch)
|
||||
let { queryInSearch: newQueryInSearch } = store.get() // avoid race conditions
|
||||
const results = await search(currentInstance, accessToken, queryInSearch)
|
||||
const { queryInSearch: newQueryInSearch } = store.get() // avoid race conditions
|
||||
if (newQueryInSearch === queryInSearch) {
|
||||
store.set({
|
||||
searchResultsForQuery: queryInSearch,
|
||||
|
|
|
@ -4,7 +4,7 @@ import { toast } from '../_components/toast/toast'
|
|||
import { updateRelationship } from './accounts'
|
||||
|
||||
export async function setDomainBlocked (accountId, domain, block, toastOnSuccess) {
|
||||
let { currentInstance, accessToken } = store.get()
|
||||
const { currentInstance, accessToken } = store.get()
|
||||
try {
|
||||
if (block) {
|
||||
await blockDomain(currentInstance, accessToken, domain)
|
||||
|
|
|
@ -4,9 +4,9 @@ import { toast } from '../_components/toast/toast'
|
|||
import { updateLocalRelationship } from './accounts'
|
||||
|
||||
export async function setShowReblogs (accountId, showReblogs, toastOnSuccess) {
|
||||
let { currentInstance, accessToken } = store.get()
|
||||
const { currentInstance, accessToken } = store.get()
|
||||
try {
|
||||
let relationship = await setShowReblogsApi(currentInstance, accessToken, accountId, showReblogs)
|
||||
const relationship = await setShowReblogsApi(currentInstance, accessToken, accountId, showReblogs)
|
||||
await updateLocalRelationship(currentInstance, accountId, relationship)
|
||||
if (toastOnSuccess) {
|
||||
if (showReblogs) {
|
||||
|
|
|
@ -11,27 +11,27 @@ export function showMoreAndScrollToTop () {
|
|||
// Similar to Twitter, pressing "." will click the "show more" button and select
|
||||
// the first toot.
|
||||
showMoreItemsForCurrentTimeline()
|
||||
let {
|
||||
const {
|
||||
currentInstance,
|
||||
timelineItemSummaries,
|
||||
currentTimelineType,
|
||||
currentTimelineValue
|
||||
} = store.get()
|
||||
let firstItemSummary = timelineItemSummaries && timelineItemSummaries[0]
|
||||
const firstItemSummary = timelineItemSummaries && timelineItemSummaries[0]
|
||||
if (!firstItemSummary) {
|
||||
return
|
||||
}
|
||||
let notificationId = currentTimelineType === 'notifications' && firstItemSummary.id
|
||||
let statusId = currentTimelineType !== 'notifications' && firstItemSummary.id
|
||||
const notificationId = currentTimelineType === 'notifications' && firstItemSummary.id
|
||||
const statusId = currentTimelineType !== 'notifications' && firstItemSummary.id
|
||||
scrollToTop(/* smooth */ false)
|
||||
// try 5 times to wait for the element to be rendered and then focus it
|
||||
let count = 0
|
||||
const tryToFocusElement = () => {
|
||||
let uuid = createStatusOrNotificationUuid(
|
||||
const uuid = createStatusOrNotificationUuid(
|
||||
currentInstance, currentTimelineType,
|
||||
currentTimelineValue, notificationId, statusId
|
||||
)
|
||||
let element = document.getElementById(uuid)
|
||||
const element = document.getElementById(uuid)
|
||||
if (element) {
|
||||
try {
|
||||
element.focus({ preventScroll: true })
|
||||
|
|
|
@ -2,10 +2,10 @@ import { store } from '../_store/store'
|
|||
import { importShowComposeDialog } from '../_components/dialog/asyncDialogs'
|
||||
|
||||
export async function showShareDialogIfNecessary () {
|
||||
let { isUserLoggedIn, openShareDialog } = store.get()
|
||||
const { isUserLoggedIn, openShareDialog } = store.get()
|
||||
store.set({ openShareDialog: false })
|
||||
if (isUserLoggedIn && openShareDialog) {
|
||||
let showComposeDialog = await importShowComposeDialog()
|
||||
const showComposeDialog = await importShowComposeDialog()
|
||||
showComposeDialog()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { database } from '../_database/database'
|
||||
|
||||
export async function getIdThatThisStatusReblogged (instanceName, statusId) {
|
||||
let status = await database.getStatus(instanceName, statusId)
|
||||
const status = await database.getStatus(instanceName, statusId)
|
||||
return status.reblog && status.reblog.id
|
||||
}
|
||||
|
||||
export async function getIdsThatTheseStatusesReblogged (instanceName, statusIds) {
|
||||
let reblogIds = await Promise.all(statusIds.map(async statusId => {
|
||||
const reblogIds = await Promise.all(statusIds.map(async statusId => {
|
||||
return getIdThatThisStatusReblogged(instanceName, statusId)
|
||||
}))
|
||||
return reblogIds.filter(Boolean)
|
||||
|
|
|
@ -35,11 +35,11 @@ export function createStream (api, instanceName, accessToken, timelineName, firs
|
|||
console.log(`streaming ${instanceName} ${timelineName}: reconnected`)
|
||||
// When reconnecting, we recompute the firstStatusId and firstNotificationId because these may have
|
||||
// changed since we first started streaming.
|
||||
let newFirstStatusId = store.getFirstTimelineItemId(instanceName, timelineName)
|
||||
const newFirstStatusId = store.getFirstTimelineItemId(instanceName, timelineName)
|
||||
fillGap(timelineName, newFirstStatusId)
|
||||
if (timelineName === 'home') {
|
||||
// special case - home timeline stream also handles notifications
|
||||
let newFirstNotificationId = store.getFirstTimelineItemId(instanceName, 'notifications')
|
||||
const newFirstNotificationId = store.getFirstTimelineItemId(instanceName, 'notifications')
|
||||
fillGap('notifications', newFirstNotificationId)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,10 +25,10 @@ async function storeFreshTimelineItemsInDatabase (instanceName, timelineName, it
|
|||
|
||||
async function fetchTimelineItemsFromNetwork (instanceName, accessToken, timelineName, lastTimelineItemId) {
|
||||
if (timelineName.startsWith('status/')) { // special case - this is a list of descendents and ancestors
|
||||
let statusId = timelineName.split('/').slice(-1)[0]
|
||||
let statusRequest = getStatus(instanceName, accessToken, statusId)
|
||||
let contextRequest = getStatusContext(instanceName, accessToken, statusId)
|
||||
let [ status, context ] = await Promise.all([statusRequest, contextRequest])
|
||||
const statusId = timelineName.split('/').slice(-1)[0]
|
||||
const statusRequest = getStatus(instanceName, accessToken, statusId)
|
||||
const contextRequest = getStatusContext(instanceName, accessToken, statusId)
|
||||
const [status, context] = await Promise.all([statusRequest, contextRequest])
|
||||
return concat(context.ancestors, status, context.descendants)
|
||||
} else { // normal timeline
|
||||
return getTimeline(instanceName, accessToken, timelineName, lastTimelineItemId, null, TIMELINE_BATCH_SIZE)
|
||||
|
@ -61,16 +61,16 @@ async function fetchTimelineItems (instanceName, accessToken, timelineName, last
|
|||
async function addTimelineItems (instanceName, timelineName, items, stale) {
|
||||
console.log('addTimelineItems, length:', items.length)
|
||||
mark('addTimelineItemSummaries')
|
||||
let newSummaries = items.map(timelineItemToSummary)
|
||||
const newSummaries = items.map(timelineItemToSummary)
|
||||
addTimelineItemSummaries(instanceName, timelineName, newSummaries, stale)
|
||||
stop('addTimelineItemSummaries')
|
||||
}
|
||||
|
||||
export async function addTimelineItemSummaries (instanceName, timelineName, newSummaries, newStale) {
|
||||
let oldSummaries = store.getForTimeline(instanceName, timelineName, 'timelineItemSummaries') || []
|
||||
let oldStale = store.getForTimeline(instanceName, timelineName, 'timelineItemSummariesAreStale')
|
||||
const oldSummaries = store.getForTimeline(instanceName, timelineName, 'timelineItemSummaries') || []
|
||||
const oldStale = store.getForTimeline(instanceName, timelineName, 'timelineItemSummariesAreStale')
|
||||
|
||||
let mergedSummaries = mergeArrays(oldSummaries, newSummaries, compareTimelineItemSummaries)
|
||||
const mergedSummaries = mergeArrays(oldSummaries, newSummaries, compareTimelineItemSummaries)
|
||||
|
||||
if (!isEqual(oldSummaries, mergedSummaries)) {
|
||||
store.setForTimeline(instanceName, timelineName, { timelineItemSummaries: mergedSummaries })
|
||||
|
@ -82,7 +82,7 @@ export async function addTimelineItemSummaries (instanceName, timelineName, newS
|
|||
|
||||
async function fetchTimelineItemsAndPossiblyFallBack () {
|
||||
mark('fetchTimelineItemsAndPossiblyFallBack')
|
||||
let {
|
||||
const {
|
||||
currentTimeline,
|
||||
currentInstance,
|
||||
accessToken,
|
||||
|
@ -90,7 +90,7 @@ async function fetchTimelineItemsAndPossiblyFallBack () {
|
|||
online
|
||||
} = store.get()
|
||||
|
||||
let { items, stale } = await fetchTimelineItems(currentInstance, accessToken, currentTimeline, lastTimelineItemId, online)
|
||||
const { items, stale } = await fetchTimelineItems(currentInstance, accessToken, currentTimeline, lastTimelineItemId, online)
|
||||
addTimelineItems(currentInstance, currentTimeline, items, stale)
|
||||
stop('fetchTimelineItemsAndPossiblyFallBack')
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ export async function setupTimeline () {
|
|||
// (i.e. via offline mode), then we need to re-fetch
|
||||
// Also do this if it's a thread, because threads change pretty frequently and
|
||||
// we don't have a good way to update them.
|
||||
let {
|
||||
const {
|
||||
timelineItemSummaries,
|
||||
timelineItemSummariesAreStale,
|
||||
currentTimeline
|
||||
|
@ -136,7 +136,7 @@ export async function showMoreItemsForTimeline (instanceName, timelineName) {
|
|||
}
|
||||
|
||||
export function showMoreItemsForCurrentTimeline () {
|
||||
let { currentInstance, currentTimeline } = store.get()
|
||||
const { currentInstance, currentTimeline } = store.get()
|
||||
return showMoreItemsForTimeline(
|
||||
currentInstance,
|
||||
currentTimeline
|
||||
|
@ -145,11 +145,11 @@ export function showMoreItemsForCurrentTimeline () {
|
|||
|
||||
export async function showMoreItemsForThread (instanceName, timelineName) {
|
||||
mark('showMoreItemsForThread')
|
||||
let itemSummariesToAdd = store.getForTimeline(instanceName, timelineName, 'timelineItemSummariesToAdd')
|
||||
let timelineItemSummaries = store.getForTimeline(instanceName, timelineName, 'timelineItemSummaries')
|
||||
let timelineItemIds = new Set(timelineItemSummaries.map(_ => _.id))
|
||||
const itemSummariesToAdd = store.getForTimeline(instanceName, timelineName, 'timelineItemSummariesToAdd')
|
||||
const timelineItemSummaries = store.getForTimeline(instanceName, timelineName, 'timelineItemSummaries')
|
||||
const timelineItemIds = new Set(timelineItemSummaries.map(_ => _.id))
|
||||
// TODO: update database and do the thread merge correctly
|
||||
for (let itemSummaryToAdd of itemSummariesToAdd) {
|
||||
for (const itemSummaryToAdd of itemSummariesToAdd) {
|
||||
if (!timelineItemIds.has(itemSummaryToAdd.id)) {
|
||||
timelineItemSummaries.push(itemSummaryToAdd)
|
||||
}
|
||||
|
|
|
@ -2,11 +2,11 @@ import { auth, basename } from './utils'
|
|||
import { post, WRITE_TIMEOUT } from '../_utils/ajax'
|
||||
|
||||
export async function blockAccount (instanceName, accessToken, accountId) {
|
||||
let url = `${basename(instanceName)}/api/v1/accounts/${accountId}/block`
|
||||
const url = `${basename(instanceName)}/api/v1/accounts/${accountId}/block`
|
||||
return post(url, null, auth(accessToken), { timeout: WRITE_TIMEOUT })
|
||||
}
|
||||
|
||||
export async function unblockAccount (instanceName, accessToken, accountId) {
|
||||
let url = `${basename(instanceName)}/api/v1/accounts/${accountId}/unblock`
|
||||
const url = `${basename(instanceName)}/api/v1/accounts/${accountId}/unblock`
|
||||
return post(url, null, auth(accessToken), { timeout: WRITE_TIMEOUT })
|
||||
}
|
||||
|
|
|
@ -2,11 +2,11 @@ import { post, WRITE_TIMEOUT, paramsString, del } from '../_utils/ajax'
|
|||
import { auth, basename } from './utils'
|
||||
|
||||
export async function blockDomain (instanceName, accessToken, domain) {
|
||||
let url = `${basename(instanceName)}/api/v1/domain_blocks?${paramsString({ domain })}`
|
||||
const url = `${basename(instanceName)}/api/v1/domain_blocks?${paramsString({ domain })}`
|
||||
return post(url, null, auth(accessToken), { timeout: WRITE_TIMEOUT })
|
||||
}
|
||||
|
||||
export async function unblockDomain (instanceName, accessToken, domain) {
|
||||
let url = `${basename(instanceName)}/api/v1/domain_blocks?${paramsString({ domain })}`
|
||||
const url = `${basename(instanceName)}/api/v1/domain_blocks?${paramsString({ domain })}`
|
||||
return del(url, auth(accessToken), { timeout: WRITE_TIMEOUT })
|
||||
}
|
||||
|
|
|
@ -2,6 +2,6 @@ import { auth, basename } from './utils'
|
|||
import { del, WRITE_TIMEOUT } from '../_utils/ajax'
|
||||
|
||||
export async function deleteStatus (instanceName, accessToken, statusId) {
|
||||
let url = `${basename(instanceName)}/api/v1/statuses/${statusId}`
|
||||
const url = `${basename(instanceName)}/api/v1/statuses/${statusId}`
|
||||
return del(url, auth(accessToken), { timeout: WRITE_TIMEOUT })
|
||||
}
|
||||
|
|
|
@ -2,6 +2,6 @@ import { basename } from './utils'
|
|||
import { DEFAULT_TIMEOUT, get } from '../_utils/ajax'
|
||||
|
||||
export async function getCustomEmoji (instanceName) {
|
||||
let url = `${basename(instanceName)}/api/v1/custom_emojis`
|
||||
const url = `${basename(instanceName)}/api/v1/custom_emojis`
|
||||
return get(url, null, { timeout: DEFAULT_TIMEOUT })
|
||||
}
|
||||
|
|
|
@ -2,11 +2,11 @@ import { post, WRITE_TIMEOUT } from '../_utils/ajax'
|
|||
import { basename, auth } from './utils'
|
||||
|
||||
export async function favoriteStatus (instanceName, accessToken, statusId) {
|
||||
let url = `${basename(instanceName)}/api/v1/statuses/${statusId}/favourite`
|
||||
const url = `${basename(instanceName)}/api/v1/statuses/${statusId}/favourite`
|
||||
return post(url, null, auth(accessToken), { timeout: WRITE_TIMEOUT })
|
||||
}
|
||||
|
||||
export async function unfavoriteStatus (instanceName, accessToken, statusId) {
|
||||
let url = `${basename(instanceName)}/api/v1/statuses/${statusId}/unfavourite`
|
||||
const url = `${basename(instanceName)}/api/v1/statuses/${statusId}/unfavourite`
|
||||
return post(url, null, auth(accessToken), { timeout: WRITE_TIMEOUT })
|
||||
}
|
||||
|
|
|
@ -2,11 +2,11 @@ import { post, WRITE_TIMEOUT } from '../_utils/ajax'
|
|||
import { auth, basename } from './utils'
|
||||
|
||||
export async function followAccount (instanceName, accessToken, accountId) {
|
||||
let url = `${basename(instanceName)}/api/v1/accounts/${accountId}/follow`
|
||||
const url = `${basename(instanceName)}/api/v1/accounts/${accountId}/follow`
|
||||
return post(url, null, auth(accessToken), { timeout: WRITE_TIMEOUT })
|
||||
}
|
||||
|
||||
export async function unfollowAccount (instanceName, accessToken, accountId) {
|
||||
let url = `${basename(instanceName)}/api/v1/accounts/${accountId}/unfollow`
|
||||
const url = `${basename(instanceName)}/api/v1/accounts/${accountId}/unfollow`
|
||||
return post(url, null, auth(accessToken), { timeout: WRITE_TIMEOUT })
|
||||
}
|
||||
|
|
|
@ -2,6 +2,6 @@ import { get, DEFAULT_TIMEOUT } from '../_utils/ajax'
|
|||
import { basename } from './utils'
|
||||
|
||||
export function getInstanceInfo (instanceName) {
|
||||
let url = `${basename(instanceName)}/api/v1/instance`
|
||||
const url = `${basename(instanceName)}/api/v1/instance`
|
||||
return get(url, null, { timeout: DEFAULT_TIMEOUT })
|
||||
}
|
||||
|
|
|
@ -2,6 +2,6 @@ import { get, DEFAULT_TIMEOUT } from '../_utils/ajax'
|
|||
import { auth, basename } from './utils'
|
||||
|
||||
export function getLists (instanceName, accessToken) {
|
||||
let url = `${basename(instanceName)}/api/v1/lists`
|
||||
const url = `${basename(instanceName)}/api/v1/lists`
|
||||
return get(url, auth(accessToken), { timeout: DEFAULT_TIMEOUT })
|
||||
}
|
||||
|
|
|
@ -2,16 +2,16 @@ import { auth, basename } from './utils'
|
|||
import { post, put, MEDIA_WRITE_TIMEOUT, WRITE_TIMEOUT } from '../_utils/ajax'
|
||||
|
||||
export async function uploadMedia (instanceName, accessToken, file, description) {
|
||||
let formData = new FormData()
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
if (description) {
|
||||
formData.append('description', description)
|
||||
}
|
||||
let url = `${basename(instanceName)}/api/v1/media`
|
||||
const url = `${basename(instanceName)}/api/v1/media`
|
||||
return post(url, formData, auth(accessToken), { timeout: MEDIA_WRITE_TIMEOUT })
|
||||
}
|
||||
|
||||
export async function putMediaMetadata (instanceName, accessToken, mediaId, description, focus) {
|
||||
let url = `${basename(instanceName)}/api/v1/media/${mediaId}`
|
||||
const url = `${basename(instanceName)}/api/v1/media/${mediaId}`
|
||||
return put(url, { description, focus: (focus && focus.join(',')) }, auth(accessToken), { timeout: WRITE_TIMEOUT })
|
||||
}
|
||||
|
|
|
@ -2,11 +2,11 @@ import { auth, basename } from './utils'
|
|||
import { post, WRITE_TIMEOUT } from '../_utils/ajax'
|
||||
|
||||
export async function muteAccount (instanceName, accessToken, accountId, notifications) {
|
||||
let url = `${basename(instanceName)}/api/v1/accounts/${accountId}/mute`
|
||||
const url = `${basename(instanceName)}/api/v1/accounts/${accountId}/mute`
|
||||
return post(url, { notifications }, auth(accessToken), { timeout: WRITE_TIMEOUT })
|
||||
}
|
||||
|
||||
export async function unmuteAccount (instanceName, accessToken, accountId) {
|
||||
let url = `${basename(instanceName)}/api/v1/accounts/${accountId}/unmute`
|
||||
const url = `${basename(instanceName)}/api/v1/accounts/${accountId}/unmute`
|
||||
return post(url, null, auth(accessToken), { timeout: WRITE_TIMEOUT })
|
||||
}
|
||||
|
|
|
@ -2,11 +2,11 @@ import { auth, basename } from './utils'
|
|||
import { post, WRITE_TIMEOUT } from '../_utils/ajax'
|
||||
|
||||
export async function muteConversation (instanceName, accessToken, statusId) {
|
||||
let url = `${basename(instanceName)}/api/v1/statuses/${statusId}/mute`
|
||||
const url = `${basename(instanceName)}/api/v1/statuses/${statusId}/mute`
|
||||
return post(url, null, auth(accessToken), { timeout: WRITE_TIMEOUT })
|
||||
}
|
||||
|
||||
export async function unmuteConversation (instanceName, accessToken, statusId) {
|
||||
let url = `${basename(instanceName)}/api/v1/statuses/${statusId}/unmute`
|
||||
const url = `${basename(instanceName)}/api/v1/statuses/${statusId}/unmute`
|
||||
return post(url, null, auth(accessToken), { timeout: WRITE_TIMEOUT })
|
||||
}
|
||||
|
|
|
@ -16,17 +16,17 @@ export function registerApplication (instanceName, redirectUri) {
|
|||
}
|
||||
|
||||
export function generateAuthLink (instanceName, clientId, redirectUri) {
|
||||
let params = paramsString({
|
||||
'client_id': clientId,
|
||||
'redirect_uri': redirectUri,
|
||||
'response_type': 'code',
|
||||
'scope': SCOPES
|
||||
const params = paramsString({
|
||||
client_id: clientId,
|
||||
redirect_uri: redirectUri,
|
||||
response_type: 'code',
|
||||
scope: SCOPES
|
||||
})
|
||||
return `${basename(instanceName)}/oauth/authorize?${params}`
|
||||
}
|
||||
|
||||
export function getAccessTokenFromAuthCode (instanceName, clientId, clientSecret, code, redirectUri) {
|
||||
let url = `${basename(instanceName)}/oauth/token`
|
||||
const url = `${basename(instanceName)}/oauth/token`
|
||||
return post(url, {
|
||||
client_id: clientId,
|
||||
client_secret: clientSecret,
|
||||
|
|
|
@ -2,11 +2,11 @@ import { post, WRITE_TIMEOUT } from '../_utils/ajax'
|
|||
import { auth, basename } from './utils'
|
||||
|
||||
export async function pinStatus (instanceName, accessToken, statusId) {
|
||||
let url = `${basename(instanceName)}/api/v1/statuses/${statusId}/pin`
|
||||
const url = `${basename(instanceName)}/api/v1/statuses/${statusId}/pin`
|
||||
return post(url, null, auth(accessToken), { timeout: WRITE_TIMEOUT })
|
||||
}
|
||||
|
||||
export async function unpinStatus (instanceName, accessToken, statusId) {
|
||||
let url = `${basename(instanceName)}/api/v1/statuses/${statusId}/unpin`
|
||||
const url = `${basename(instanceName)}/api/v1/statuses/${statusId}/unpin`
|
||||
return post(url, null, auth(accessToken), { timeout: WRITE_TIMEOUT })
|
||||
}
|
||||
|
|
|
@ -2,11 +2,11 @@ import { get, post, DEFAULT_TIMEOUT, WRITE_TIMEOUT } from '../_utils/ajax'
|
|||
import { auth, basename } from './utils'
|
||||
|
||||
export async function getPoll (instanceName, accessToken, pollId) {
|
||||
let url = `${basename(instanceName)}/api/v1/polls/${pollId}`
|
||||
const url = `${basename(instanceName)}/api/v1/polls/${pollId}`
|
||||
return get(url, auth(accessToken), { timeout: DEFAULT_TIMEOUT })
|
||||
}
|
||||
|
||||
export async function voteOnPoll (instanceName, accessToken, pollId, choices) {
|
||||
let url = `${basename(instanceName)}/api/v1/polls/${pollId}/votes`
|
||||
const url = `${basename(instanceName)}/api/v1/polls/${pollId}/votes`
|
||||
return post(url, { choices }, auth(accessToken), { timeout: WRITE_TIMEOUT })
|
||||
}
|
||||
|
|
|
@ -2,11 +2,11 @@ import { post } from '../_utils/ajax'
|
|||
import { basename, auth } from './utils'
|
||||
|
||||
export async function reblogStatus (instanceName, accessToken, statusId) {
|
||||
let url = `${basename(instanceName)}/api/v1/statuses/${statusId}/reblog`
|
||||
const url = `${basename(instanceName)}/api/v1/statuses/${statusId}/reblog`
|
||||
return post(url, null, auth(accessToken))
|
||||
}
|
||||
|
||||
export async function unreblogStatus (instanceName, accessToken, statusId) {
|
||||
let url = `${basename(instanceName)}/api/v1/statuses/${statusId}/unreblog`
|
||||
const url = `${basename(instanceName)}/api/v1/statuses/${statusId}/unreblog`
|
||||
return post(url, null, auth(accessToken))
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import { basename, auth } from './utils'
|
|||
import { get, paramsString, DEFAULT_TIMEOUT } from '../_utils/ajax'
|
||||
|
||||
export async function getRelationship (instanceName, accessToken, accountId) {
|
||||
let url = `${basename(instanceName)}/api/v1/accounts/relationships?${paramsString({ id: accountId })}`
|
||||
let res = await get(url, auth(accessToken), { timeout: DEFAULT_TIMEOUT })
|
||||
const url = `${basename(instanceName)}/api/v1/accounts/relationships?${paramsString({ id: accountId })}`
|
||||
const res = await get(url, auth(accessToken), { timeout: DEFAULT_TIMEOUT })
|
||||
return res[0]
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import { auth, basename } from './utils'
|
|||
import { post } from '../_utils/ajax'
|
||||
|
||||
export async function report (instanceName, accessToken, accountId, statusIds, comment, forward) {
|
||||
let url = `${basename(instanceName)}/api/v1/reports`
|
||||
const url = `${basename(instanceName)}/api/v1/reports`
|
||||
return post(url, {
|
||||
account_id: accountId,
|
||||
status_ids: statusIds,
|
||||
|
|
|
@ -2,11 +2,11 @@ import { post, WRITE_TIMEOUT } from '../_utils/ajax'
|
|||
import { auth, basename } from './utils'
|
||||
|
||||
export async function approveFollowRequest (instanceName, accessToken, accountId) {
|
||||
let url = `${basename(instanceName)}/api/v1/follow_requests/${accountId}/authorize`
|
||||
const url = `${basename(instanceName)}/api/v1/follow_requests/${accountId}/authorize`
|
||||
return post(url, null, auth(accessToken), { timeout: WRITE_TIMEOUT })
|
||||
}
|
||||
|
||||
export async function rejectFollowRequest (instanceName, accessToken, accountId) {
|
||||
let url = `${basename(instanceName)}/api/v1/follow_requests/${accountId}/reject`
|
||||
const url = `${basename(instanceName)}/api/v1/follow_requests/${accountId}/reject`
|
||||
return post(url, null, auth(accessToken), { timeout: WRITE_TIMEOUT })
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import { get, paramsString, DEFAULT_TIMEOUT } from '../_utils/ajax'
|
|||
import { auth, basename } from './utils'
|
||||
|
||||
export function search (instanceName, accessToken, query, resolve = true, limit = 5, signal = null) {
|
||||
let url = `${basename(instanceName)}/api/v1/search?` + paramsString({
|
||||
const url = `${basename(instanceName)}/api/v1/search?` + paramsString({
|
||||
q: query,
|
||||
resolve,
|
||||
limit
|
||||
|
|
|
@ -2,6 +2,6 @@ import { auth, basename } from './utils'
|
|||
import { post, WRITE_TIMEOUT } from '../_utils/ajax'
|
||||
|
||||
export function setShowReblogs (instanceName, accessToken, accountId, showReblogs) {
|
||||
let url = `${basename(instanceName)}/api/v1/accounts/${accountId}/follow`
|
||||
const url = `${basename(instanceName)}/api/v1/accounts/${accountId}/follow`
|
||||
return post(url, { reblogs: !!showReblogs }, auth(accessToken), { timeout: WRITE_TIMEOUT })
|
||||
}
|
||||
|
|
|
@ -3,9 +3,9 @@ import { DEFAULT_TIMEOUT, get, post, WRITE_TIMEOUT } from '../_utils/ajax'
|
|||
|
||||
export async function postStatus (instanceName, accessToken, text, inReplyToId, mediaIds,
|
||||
sensitive, spoilerText, visibility, poll) {
|
||||
let url = `${basename(instanceName)}/api/v1/statuses`
|
||||
const url = `${basename(instanceName)}/api/v1/statuses`
|
||||
|
||||
let body = {
|
||||
const body = {
|
||||
status: text,
|
||||
in_reply_to_id: inReplyToId,
|
||||
media_ids: mediaIds,
|
||||
|
@ -15,8 +15,8 @@ export async function postStatus (instanceName, accessToken, text, inReplyToId,
|
|||
poll: poll
|
||||
}
|
||||
|
||||
for (let key of Object.keys(body)) {
|
||||
let value = body[key]
|
||||
for (const key of Object.keys(body)) {
|
||||
const value = body[key]
|
||||
// remove any unnecessary fields, except 'status' which must at least be an empty string
|
||||
if (key !== 'status' && (!value || (Array.isArray(value) && !value.length))) {
|
||||
delete body[key]
|
||||
|
@ -27,11 +27,11 @@ export async function postStatus (instanceName, accessToken, text, inReplyToId,
|
|||
}
|
||||
|
||||
export async function getStatusContext (instanceName, accessToken, statusId) {
|
||||
let url = `${basename(instanceName)}/api/v1/statuses/${statusId}/context`
|
||||
const url = `${basename(instanceName)}/api/v1/statuses/${statusId}/context`
|
||||
return get(url, auth(accessToken), { timeout: DEFAULT_TIMEOUT })
|
||||
}
|
||||
|
||||
export async function getStatus (instanceName, accessToken, statusId) {
|
||||
let url = `${basename(instanceName)}/api/v1/statuses/${statusId}`
|
||||
const url = `${basename(instanceName)}/api/v1/statuses/${statusId}`
|
||||
return get(url, auth(accessToken), { timeout: DEFAULT_TIMEOUT })
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ export class TimelineStream extends EventEmitter {
|
|||
this._teardownEvents()
|
||||
// events-light currently does not support removeAllListeners()
|
||||
// https://github.com/patrick-steele-idem/events-light/issues/2
|
||||
for (let event of ['open', 'close', 'reconnect', 'message']) {
|
||||
for (const event of ['open', 'close', 'reconnect', 'message']) {
|
||||
this.removeAllListeners(event)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,10 +22,10 @@ function getStreamName (timeline) {
|
|||
}
|
||||
|
||||
export function getStreamUrl (streamingApi, accessToken, timeline) {
|
||||
let url = `${streamingApi}/api/v1/streaming`
|
||||
let streamName = getStreamName(timeline)
|
||||
const url = `${streamingApi}/api/v1/streaming`
|
||||
const streamName = getStreamName(timeline)
|
||||
|
||||
let params = {
|
||||
const params = {
|
||||
stream: streamName
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ function getTimelineUrlPath (timeline) {
|
|||
}
|
||||
|
||||
export async function getTimeline (instanceName, accessToken, timeline, maxId, since, limit) {
|
||||
let timelineUrlName = getTimelineUrlPath(timeline)
|
||||
const timelineUrlName = getTimelineUrlPath(timeline)
|
||||
let url = `${basename(instanceName)}/api/v1/${timelineUrlName}`
|
||||
|
||||
if (timeline.startsWith('tag/')) {
|
||||
|
@ -37,7 +37,7 @@ export async function getTimeline (instanceName, accessToken, timeline, maxId, s
|
|||
url += '/' + timeline.split('/')[1]
|
||||
}
|
||||
|
||||
let params = {}
|
||||
const params = {}
|
||||
if (since) {
|
||||
params.since_id = since
|
||||
}
|
||||
|
|
|
@ -2,6 +2,6 @@ import { WRITE_TIMEOUT, patch } from '../_utils/ajax'
|
|||
import { auth, basename } from './utils'
|
||||
|
||||
export async function updateCredentials (instanceName, accessToken, accountData) {
|
||||
let url = `${basename(instanceName)}/api/v1/accounts/update_credentials`
|
||||
const url = `${basename(instanceName)}/api/v1/accounts/update_credentials`
|
||||
return patch(url, accountData, auth(accessToken), { timeout: WRITE_TIMEOUT })
|
||||
}
|
||||
|
|
|
@ -2,11 +2,11 @@ import { get, DEFAULT_TIMEOUT } from '../_utils/ajax'
|
|||
import { auth, basename } from './utils'
|
||||
|
||||
export function getVerifyCredentials (instanceName, accessToken) {
|
||||
let url = `${basename(instanceName)}/api/v1/accounts/verify_credentials`
|
||||
const url = `${basename(instanceName)}/api/v1/accounts/verify_credentials`
|
||||
return get(url, auth(accessToken), { timeout: DEFAULT_TIMEOUT })
|
||||
}
|
||||
|
||||
export function getAccount (instanceName, accessToken, accountId) {
|
||||
let url = `${basename(instanceName)}/api/v1/accounts/${accountId}`
|
||||
const url = `${basename(instanceName)}/api/v1/accounts/${accountId}`
|
||||
return get(url, auth(accessToken), { timeout: DEFAULT_TIMEOUT })
|
||||
}
|
||||
|
|
|
@ -11,6 +11,6 @@ export function basename (instanceName) {
|
|||
|
||||
export function auth (accessToken) {
|
||||
return {
|
||||
'Authorization': `Bearer ${accessToken}`
|
||||
Authorization: `Bearer ${accessToken}`
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,12 +61,12 @@
|
|||
},
|
||||
methods: {
|
||||
onClickAction (event) {
|
||||
let { action, accountId } = event
|
||||
const { action, accountId } = event
|
||||
action.onclick(accountId)
|
||||
},
|
||||
async refreshAccounts () {
|
||||
let { accountsFetcher } = this.get()
|
||||
let accounts = await accountsFetcher()
|
||||
const { accountsFetcher } = this.get()
|
||||
const accounts = await accountsFetcher()
|
||||
this.set({ accounts: accounts })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
onPointerDown (e) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
let rect = this.refs.indicator.getBoundingClientRect()
|
||||
const rect = this.refs.indicator.getBoundingClientRect()
|
||||
this.set({
|
||||
dragging: true,
|
||||
dragOffsetX: e.clientX - rect.left,
|
||||
|
@ -64,13 +64,13 @@
|
|||
if (this.get().dragging) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
let { indicatorWidth, indicatorHeight, dragOffsetX, dragOffsetY } = this.get()
|
||||
const { indicatorWidth, indicatorHeight, dragOffsetX, dragOffsetY } = this.get()
|
||||
throttledRaf(() => {
|
||||
let rect = this.refs.area.getBoundingClientRect()
|
||||
let offsetX = dragOffsetX - (indicatorWidth / 2)
|
||||
let offsetY = dragOffsetY - (indicatorHeight / 2)
|
||||
let x = clamp((e.clientX - rect.left - offsetX) / rect.width)
|
||||
let y = clamp((e.clientY - rect.top - offsetY) / rect.height)
|
||||
const rect = this.refs.area.getBoundingClientRect()
|
||||
const offsetX = dragOffsetX - (indicatorWidth / 2)
|
||||
const offsetY = dragOffsetY - (indicatorHeight / 2)
|
||||
const x = clamp((e.clientX - rect.left - offsetX) / rect.width)
|
||||
const y = clamp((e.clientY - rect.top - offsetY) / rect.height)
|
||||
this.set({ x, y })
|
||||
this.fire('change', { x, y })
|
||||
})
|
||||
|
@ -90,9 +90,9 @@
|
|||
if (!e.target.classList.contains('draggable-indicator')) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
let rect = this.refs.area.getBoundingClientRect()
|
||||
let x = clamp((e.clientX - rect.left) / rect.width)
|
||||
let y = clamp((e.clientY - rect.top) / rect.height)
|
||||
const rect = this.refs.area.getBoundingClientRect()
|
||||
const x = clamp((e.clientX - rect.left) / rect.width)
|
||||
const y = clamp((e.clientY - rect.top) / rect.height)
|
||||
this.set({ x, y })
|
||||
this.fire('change', { x, y })
|
||||
}
|
||||
|
|
|
@ -93,7 +93,7 @@
|
|||
|
||||
export default {
|
||||
oncreate () {
|
||||
let { clickListener, elementId } = this.get()
|
||||
const { clickListener, elementId } = this.get()
|
||||
if (clickListener) {
|
||||
this.onClick = this.onClick.bind(this)
|
||||
this.refs.node.addEventListener('click', this.onClick)
|
||||
|
@ -103,7 +103,7 @@
|
|||
}
|
||||
},
|
||||
ondestroy () {
|
||||
let { clickListener } = this.get()
|
||||
const { clickListener } = this.get()
|
||||
if (clickListener) {
|
||||
this.refs.node.removeEventListener('click', this.onClick)
|
||||
}
|
||||
|
|
|
@ -109,14 +109,14 @@
|
|||
|
||||
export default {
|
||||
oncreate () {
|
||||
let { name } = this.get()
|
||||
let indicator = this.refs.indicator
|
||||
const { name } = this.get()
|
||||
const indicator = this.refs.indicator
|
||||
on('animateNavPart1', this, ({ fromPage, toPage }) => {
|
||||
if (fromPage !== name) {
|
||||
return
|
||||
}
|
||||
mark('animateNavPart1 gBCR')
|
||||
let fromRect = indicator.getBoundingClientRect()
|
||||
const fromRect = indicator.getBoundingClientRect()
|
||||
stop('animateNavPart1 gBCR')
|
||||
emit('animateNavPart2', { fromRect, fromPage, toPage })
|
||||
})
|
||||
|
@ -125,12 +125,12 @@
|
|||
return
|
||||
}
|
||||
mark('animateNavPart2 gBCR')
|
||||
let toRect = indicator.getBoundingClientRect()
|
||||
const toRect = indicator.getBoundingClientRect()
|
||||
stop('animateNavPart2 gBCR')
|
||||
let translateX = fromRect.left - toRect.left
|
||||
let scaleX = fromRect.width / toRect.width
|
||||
const translateX = fromRect.left - toRect.left
|
||||
const scaleX = fromRect.width / toRect.width
|
||||
indicator.style.transform = `translateX(${translateX}px) scaleX(${scaleX})`
|
||||
let onTransitionEnd = () => {
|
||||
const onTransitionEnd = () => {
|
||||
indicator.removeEventListener('transitionend', onTransitionEnd)
|
||||
indicator.classList.remove('animate')
|
||||
}
|
||||
|
@ -163,7 +163,7 @@
|
|||
},
|
||||
methods: {
|
||||
onClick (e) {
|
||||
let { selected } = this.get()
|
||||
const { selected } = this.get()
|
||||
if (!selected) {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -26,11 +26,11 @@
|
|||
methods: {
|
||||
goto,
|
||||
async showShortcutHelpDialog () {
|
||||
let showShortcutHelpDialog = await importShowShortcutHelpDialog()
|
||||
const showShortcutHelpDialog = await importShowShortcutHelpDialog()
|
||||
showShortcutHelpDialog()
|
||||
},
|
||||
async showComposeDialog () {
|
||||
let showComposeDialog = await importShowComposeDialog()
|
||||
const showComposeDialog = await importShowComposeDialog()
|
||||
showComposeDialog()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
export default {
|
||||
async oncreate () {
|
||||
let { currentSrc } = this.get()
|
||||
const { currentSrc } = this.get()
|
||||
try {
|
||||
let image = new Image()
|
||||
const image = new Image()
|
||||
image.src = currentSrc
|
||||
await decodeImage(image)
|
||||
this.set({ loaded: true })
|
||||
|
|
|
@ -25,11 +25,11 @@
|
|||
},
|
||||
methods: {
|
||||
animate (animation) {
|
||||
let { reduceMotion } = this.store.get()
|
||||
const { reduceMotion } = this.store.get()
|
||||
if (!animation || reduceMotion) {
|
||||
return
|
||||
}
|
||||
let svg = this.refs.svg
|
||||
const svg = this.refs.svg
|
||||
animate(svg, animation)
|
||||
}
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 790 B After Width: | Height: | Size: 794 B |
|
@ -60,7 +60,7 @@
|
|||
toggle (e) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
let { shown, mouseover } = this.get()
|
||||
const { shown, mouseover } = this.get()
|
||||
if (!mouseover) {
|
||||
this.set({ shown: !shown })
|
||||
}
|
||||
|
|
|
@ -87,8 +87,8 @@
|
|||
methods: {
|
||||
onPinClick (e) {
|
||||
e.preventDefault()
|
||||
let { currentInstance, pinnedPages } = this.store.get()
|
||||
let { href } = this.get()
|
||||
const { currentInstance, pinnedPages } = this.store.get()
|
||||
const { href } = this.get()
|
||||
pinnedPages[currentInstance] = href
|
||||
this.store.set({ pinnedPages: pinnedPages })
|
||||
this.store.save()
|
||||
|
|
|
@ -95,7 +95,7 @@
|
|||
},
|
||||
methods: {
|
||||
onClick (e) {
|
||||
let { realm, dialogId, href } = this.get()
|
||||
const { realm, dialogId, href } = this.get()
|
||||
if (realm === 'dialog') {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
|
|
|
@ -105,7 +105,7 @@
|
|||
|
||||
export default {
|
||||
oncreate () {
|
||||
let { realm, replySpoiler, replyVisibility } = this.get()
|
||||
const { realm, replySpoiler, replyVisibility } = this.get()
|
||||
if (realm !== 'home' && realm !== 'dialog') {
|
||||
// if this is a reply, populate the handle immediately
|
||||
/* no await */ insertHandleForReply(realm)
|
||||
|
@ -179,7 +179,7 @@
|
|||
},
|
||||
methods: {
|
||||
doPostStatus () {
|
||||
let {
|
||||
const {
|
||||
text,
|
||||
media,
|
||||
postPrivacyKey,
|
||||
|
@ -190,17 +190,17 @@
|
|||
inReplyToId, // delete-and-redraft replies, using standard id
|
||||
poll
|
||||
} = this.get()
|
||||
let sensitive = media.length && !!contentWarning
|
||||
let mediaIds = media.map(_ => _.data.id)
|
||||
let mediaDescriptions = media.map(_ => _.description)
|
||||
let mediaFocalPoints = media.map(_ => [_.focusX, _.focusY])
|
||||
let inReplyTo = inReplyToId || ((realm === 'home' || realm === 'dialog') ? null : realm)
|
||||
const sensitive = media.length && !!contentWarning
|
||||
const mediaIds = media.map(_ => _.data.id)
|
||||
const mediaDescriptions = media.map(_ => _.description)
|
||||
const mediaFocalPoints = media.map(_ => [_.focusX, _.focusY])
|
||||
const inReplyTo = inReplyToId || ((realm === 'home' || realm === 'dialog') ? null : realm)
|
||||
|
||||
if (overLimit || (!text && !media.length)) {
|
||||
return // do nothing if invalid
|
||||
}
|
||||
|
||||
let hasPoll = poll && poll.options && poll.options.length
|
||||
const hasPoll = poll && poll.options && poll.options.length
|
||||
if (hasPoll) {
|
||||
// validate poll
|
||||
if (poll.options.length < 2 || !poll.options.every(Boolean)) {
|
||||
|
@ -209,7 +209,7 @@
|
|||
}
|
||||
|
||||
// convert internal poll format to the format Mastodon's REST API uses
|
||||
let pollToPost = hasPoll && {
|
||||
const pollToPost = hasPoll && {
|
||||
expires_in: (poll.expiry || POLL_EXPIRY_DEFAULT).toString(),
|
||||
multiple: !!poll.multiple,
|
||||
options: poll.options
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
const saveText = debounce(() => scheduleIdleTask(() => this.store.save()), 1000)
|
||||
|
||||
this.observe('rawText', rawText => {
|
||||
let { realm } = this.get()
|
||||
const { realm } = this.get()
|
||||
this.store.setComposeData(realm, {
|
||||
contentWarning: rawText
|
||||
})
|
||||
|
|
|
@ -76,9 +76,9 @@
|
|||
}),
|
||||
methods: {
|
||||
async onFileDrop (e) {
|
||||
let { files } = e
|
||||
let { realm } = this.get()
|
||||
for (let file of files) { // upload one at a time to avoid hitting limits
|
||||
const { files } = e
|
||||
const { realm } = this.get()
|
||||
for (const file of files) { // upload one at a time to avoid hitting limits
|
||||
await doMediaUpload(realm, file)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,10 +83,10 @@
|
|||
methods: {
|
||||
observe,
|
||||
setupSyncFromStore () {
|
||||
let textarea = this.refs.textarea
|
||||
const textarea = this.refs.textarea
|
||||
let firstTime = true
|
||||
this.observe('text', text => {
|
||||
let { rawText } = this.get()
|
||||
const { rawText } = this.get()
|
||||
if (rawText !== text) {
|
||||
this.set({ rawText: text })
|
||||
// this next autosize is required to resize after
|
||||
|
@ -97,7 +97,7 @@
|
|||
}
|
||||
if (firstTime) {
|
||||
firstTime = false
|
||||
let { autoFocus } = this.get()
|
||||
const { autoFocus } = this.get()
|
||||
if (autoFocus) {
|
||||
requestAnimationFrame(() => textarea.focus({ preventScroll: true }))
|
||||
}
|
||||
|
@ -109,14 +109,14 @@
|
|||
|
||||
this.observe('rawText', rawText => {
|
||||
mark('observe rawText')
|
||||
let { realm } = this.get()
|
||||
const { realm } = this.get()
|
||||
this.store.setComposeData(realm, { text: rawText })
|
||||
saveStore()
|
||||
stop('observe rawText')
|
||||
}, { init: false })
|
||||
},
|
||||
setupAutosize () {
|
||||
let textarea = this.refs.textarea
|
||||
const textarea = this.refs.textarea
|
||||
requestAnimationFrame(() => {
|
||||
mark('autosize()')
|
||||
autosize(textarea)
|
||||
|
@ -135,7 +135,7 @@
|
|||
},
|
||||
onFocus () {
|
||||
scheduleIdleTask(() => {
|
||||
let { realm } = this.get()
|
||||
const { realm } = this.get()
|
||||
this.store.set({ currentComposeRealm: realm })
|
||||
this.store.setForCurrentAutosuggest({ composeFocused: true })
|
||||
})
|
||||
|
@ -146,7 +146,7 @@
|
|||
})
|
||||
},
|
||||
onKeydown (e) {
|
||||
let { keyCode } = e
|
||||
const { keyCode } = e
|
||||
// ctrl or cmd (on macs) was pressed; ctrl-enter means post a toot
|
||||
const ctrlPressed = e.getModifierState('Control') || e.getModifierState('Meta')
|
||||
switch (keyCode) {
|
||||
|
@ -172,7 +172,7 @@
|
|||
}
|
||||
},
|
||||
clickSelectedAutosuggestion (event) {
|
||||
let {
|
||||
const {
|
||||
autosuggestShown,
|
||||
autosuggestType
|
||||
} = this.store.get()
|
||||
|
@ -183,7 +183,7 @@
|
|||
event.stopPropagation()
|
||||
|
||||
const clickAutosuggestedItem = async () => {
|
||||
let { realm } = this.get()
|
||||
const { realm } = this.get()
|
||||
/* autosuggestSelecting prevents a flash of searched content */
|
||||
this.store.setForCurrentAutosuggest({ autosuggestSelecting: true })
|
||||
if (autosuggestType === 'account') {
|
||||
|
@ -217,7 +217,7 @@
|
|||
event.stopPropagation()
|
||||
},
|
||||
clearAutosuggestions (event) {
|
||||
let { autosuggestShown } = this.store.get()
|
||||
const { autosuggestShown } = this.store.get()
|
||||
if (!autosuggestShown) {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -25,13 +25,13 @@
|
|||
|
||||
export default {
|
||||
oncreate () {
|
||||
let { lengthAsFraction } = this.get()
|
||||
const { lengthAsFraction } = this.get()
|
||||
this.set({ lengthAsFractionDeferred: lengthAsFraction })
|
||||
// perf improvement for keyboard input latency
|
||||
this.observe('lengthAsFraction', () => {
|
||||
scheduleIdleTask(() => {
|
||||
mark('set lengthAsFractionDeferred')
|
||||
let { lengthAsFraction } = this.get()
|
||||
const { lengthAsFraction } = this.get()
|
||||
this.set({ lengthAsFractionDeferred: lengthAsFraction })
|
||||
stop('set lengthAsFractionDeferred')
|
||||
requestAnimationFrame(() => this.set({ shouldAnimate: true }))
|
||||
|
@ -46,7 +46,7 @@
|
|||
computed: {
|
||||
lengthAsFraction: ({ length, $maxStatusChars }) => {
|
||||
// We don't need to update the gauge for every decimal point, so round it to the nearest 0.02
|
||||
let int = Math.round(Math.min($maxStatusChars, length) / $maxStatusChars * 100)
|
||||
const int = Math.round(Math.min($maxStatusChars, length) / $maxStatusChars * 100)
|
||||
return (int - (int % 2)) / 100
|
||||
}
|
||||
},
|
||||
|
|
|
@ -23,13 +23,13 @@
|
|||
|
||||
export default {
|
||||
oncreate () {
|
||||
let { lengthToDisplay } = this.get()
|
||||
const { lengthToDisplay } = this.get()
|
||||
this.set({ lengthToDisplayDeferred: lengthToDisplay })
|
||||
// perf improvement for keyboard input latency
|
||||
this.observe('lengthToDisplay', () => {
|
||||
scheduleIdleTask(() => {
|
||||
mark('set lengthToDisplayDeferred')
|
||||
let { lengthToDisplay } = this.get()
|
||||
const { lengthToDisplay } = this.get()
|
||||
this.set({ lengthToDisplayDeferred: lengthToDisplay })
|
||||
stop('set lengthToDisplayDeferred')
|
||||
})
|
||||
|
|
|
@ -172,13 +172,13 @@
|
|||
setupSyncFromStore () {
|
||||
this.observe('media', media => {
|
||||
media = media || []
|
||||
let { index, rawText } = this.get()
|
||||
let text = get(media, [index, 'description'], '')
|
||||
const { index, rawText } = this.get()
|
||||
const text = get(media, [index, 'description'], '')
|
||||
if (rawText !== text) {
|
||||
this.set({ rawText: text })
|
||||
}
|
||||
let focusX = get(media, [index, 'focusX'], 0)
|
||||
let focusY = get(media, [index, 'focusY'], 0)
|
||||
const focusX = get(media, [index, 'focusX'], 0)
|
||||
const focusY = get(media, [index, 'focusY'], 0)
|
||||
this.set({ focusX, focusY })
|
||||
})
|
||||
},
|
||||
|
@ -186,7 +186,7 @@
|
|||
const saveStore = debounce(() => scheduleIdleTask(() => this.store.save()), 1000)
|
||||
|
||||
this.observe('rawText', rawText => {
|
||||
let { realm, index, media } = this.get()
|
||||
const { realm, index, media } = this.get()
|
||||
if (media[index].description !== rawText) {
|
||||
media[index].description = rawText
|
||||
this.store.setComposeData(realm, { media })
|
||||
|
@ -201,12 +201,12 @@
|
|||
autosize.destroy(this.refs.textarea)
|
||||
},
|
||||
onDeleteMedia () {
|
||||
let { realm, index } = this.get()
|
||||
const { realm, index } = this.get()
|
||||
deleteMedia(realm, index)
|
||||
},
|
||||
async onSetFocalPoint () {
|
||||
let { realm, index } = this.get()
|
||||
let showMediaFocalPointDialog = await importMediaFocalPointDialog()
|
||||
const { realm, index } = this.get()
|
||||
const showMediaFocalPointDialog = await importMediaFocalPointDialog()
|
||||
showMediaFocalPointDialog(realm, index)
|
||||
}
|
||||
},
|
||||
|
|
|
@ -83,15 +83,15 @@
|
|||
|
||||
function flushPollOptionsToDom (poll, realm) {
|
||||
for (let i = 0; i < poll.options.length; i++) {
|
||||
let element = document.getElementById(`poll-option-${realm}-${i}`)
|
||||
const element = document.getElementById(`poll-option-${realm}-${i}`)
|
||||
element.value = poll.options[i]
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
oncreate () {
|
||||
let { realm } = this.get()
|
||||
let poll = this.store.getComposeData(realm, 'poll')
|
||||
const { realm } = this.get()
|
||||
const poll = this.store.getComposeData(realm, 'poll')
|
||||
flushPollOptionsToDom(poll, realm)
|
||||
document.getElementById(`poll-option-multiple-${realm}`).checked = !!poll.multiple
|
||||
this.set({ pollExpiryDefaultValue: poll.expiry || POLL_EXPIRY_DEFAULT })
|
||||
|
@ -104,26 +104,26 @@
|
|||
methods: {
|
||||
onChange (i) {
|
||||
scheduleIdleTask(() => {
|
||||
let { realm } = this.get()
|
||||
let element = document.getElementById(`poll-option-${realm}-${i}`)
|
||||
let poll = this.store.getComposeData(realm, 'poll')
|
||||
const { realm } = this.get()
|
||||
const element = document.getElementById(`poll-option-${realm}-${i}`)
|
||||
const poll = this.store.getComposeData(realm, 'poll')
|
||||
poll.options[i] = element.value
|
||||
this.store.setComposeData(realm, { poll })
|
||||
})
|
||||
},
|
||||
onMultipleChange () {
|
||||
requestAnimationFrame(() => {
|
||||
let { realm } = this.get()
|
||||
let element = document.getElementById(`poll-option-multiple-${realm}`)
|
||||
let poll = this.store.getComposeData(realm, 'poll')
|
||||
const { realm } = this.get()
|
||||
const element = document.getElementById(`poll-option-multiple-${realm}`)
|
||||
const poll = this.store.getComposeData(realm, 'poll')
|
||||
poll.multiple = !!element.checked
|
||||
this.store.setComposeData(realm, { poll })
|
||||
})
|
||||
},
|
||||
onDeleteClick (i) {
|
||||
requestAnimationFrame(() => {
|
||||
let { realm } = this.get()
|
||||
let poll = this.store.getComposeData(realm, 'poll')
|
||||
const { realm } = this.get()
|
||||
const poll = this.store.getComposeData(realm, 'poll')
|
||||
poll.options.splice(i, 1)
|
||||
this.store.setComposeData(realm, { poll })
|
||||
flushPollOptionsToDom(poll, realm)
|
||||
|
@ -131,8 +131,8 @@
|
|||
},
|
||||
onAddClick () {
|
||||
requestAnimationFrame(() => {
|
||||
let { realm } = this.get()
|
||||
let poll = this.store.getComposeData(realm, 'poll')
|
||||
const { realm } = this.get()
|
||||
const poll = this.store.getComposeData(realm, 'poll')
|
||||
if (!poll.options.length !== 4) {
|
||||
poll.options.push('')
|
||||
}
|
||||
|
@ -141,9 +141,9 @@
|
|||
},
|
||||
onExpiryChange (e) {
|
||||
requestAnimationFrame(() => {
|
||||
let { realm } = this.get()
|
||||
let { value } = e.target
|
||||
let poll = this.store.getComposeData(realm, 'poll')
|
||||
const { realm } = this.get()
|
||||
const { value } = e.target
|
||||
const poll = this.store.getComposeData(realm, 'poll')
|
||||
poll.expiry = parseInt(value, 10)
|
||||
this.store.setComposeData(realm, { poll })
|
||||
})
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue