forked from AkkomaGang/akkoma-fe
Compare commits
119 commits
Author | SHA1 | Date | |
---|---|---|---|
715e13d1cc | |||
e449b0c897 | |||
8a8fc11219 | |||
ccac52d046 | |||
8a49d12b8f | |||
35cf3327c8 | |||
f391cf70a4 | |||
fa8fde2ab1 | |||
1f2c96a485 | |||
6c178aa257 | |||
|
3349fe6ff2 | ||
e274adf47d | |||
8765491399 | |||
4211e05a75 | |||
a3251a1ba6 | |||
e5608f4009 | |||
1092d43802 | |||
|
98a3622172 | ||
24b9e350e2 | |||
|
7ab4d22a4c | ||
8489f6d5ae | |||
b2cab6d088 | |||
3ebaba6fa7 | |||
f1058567b9 | |||
49a850a1e9 | |||
|
b2de68239f | ||
c68595345f | |||
a5d4b0a68c | |||
bd263587b2 | |||
|
c19fb198ca | ||
97966045cb | |||
aad023c8a0 | |||
c952b2335c | |||
0baf31f498 | |||
8fa24d0c40 | |||
5848c18ec8 | |||
|
54dbead22c | ||
3e86db24d3 | |||
|
d8f3f5002f | ||
7789c5def6 | |||
a45f482c79 | |||
|
ed22c480f9 | ||
f3934afbd8 | |||
|
3797495e53 | ||
0b437ab6fd | |||
a7dea2f70f | |||
|
2c9da4a58c | ||
8964dce609 | |||
|
156b036caa | ||
1a49a1b3ac | |||
|
61d82a2a07 | ||
1adef56603 | |||
|
b9bf0f0002 | ||
5aaa605df0 | |||
|
7136ea80b9 | ||
71e287d56c | |||
|
a64cdda725 | ||
70275684bf | |||
|
7e7f03aece | ||
29ff2ef455 | |||
8c49474dea | |||
62e0dd858c | |||
cc709394c5 | |||
57beea6a0d | |||
|
45524552a0 | ||
|
ee66b69ab5 | ||
|
d42e374704 | ||
|
ce8a9d2b4a | ||
|
d2b7ac6d8c | ||
|
754c72cb24 | ||
|
f5bd195422 | ||
|
d49fd46554 | ||
|
9982373853 | ||
|
5206b5cf9c | ||
|
a65a06ca04 | ||
|
c10b38afbc | ||
|
009941ea2c | ||
042e8c78dc | |||
0e07d88afa | |||
1f5f8665c8 | |||
428ed70b0d | |||
ed0b403c33 | |||
0f842b300b | |||
865cb6f96a | |||
050c7df2e6 | |||
a77a9e04d9 | |||
a57334991e | |||
8dce31d0ad | |||
ea9ad4d600 | |||
34e2800f59 | |||
3d65eccf04 | |||
d304be654f | |||
aee97fa948 | |||
7da1687f31 | |||
a8f193d4bd | |||
81c82e11bc | |||
00cadce5b4 | |||
40a08f279b | |||
c524a47e6f | |||
235c734d37 | |||
deaef1d0b9 | |||
1b28ec3b72 | |||
c9dc8f00f9 | |||
beee99e733 | |||
ccb0ffdc8a | |||
ab250c2f3a | |||
1de62fffcd | |||
306cea04a1 | |||
d9e1bc4d99 | |||
52b0b6f008 | |||
8afbe5e3bc | |||
58be48d164 | |||
1056b89fd1 | |||
3e64d78d05 | |||
3947aafeba | |||
345934c2f3 | |||
42a13b0f1b | |||
e13c4b6b85 | |||
6a1409e09b |
150 changed files with 8535 additions and 5962 deletions
|
@ -1,2 +0,0 @@
|
||||||
build/*.js
|
|
||||||
config/*.js
|
|
30
.eslintrc.js
30
.eslintrc.js
|
@ -1,30 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
root: true,
|
|
||||||
parserOptions: {
|
|
||||||
parser: '@babel/eslint-parser',
|
|
||||||
sourceType: 'module'
|
|
||||||
},
|
|
||||||
// https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
|
|
||||||
extends: [
|
|
||||||
'plugin:vue/recommended'
|
|
||||||
],
|
|
||||||
// required to lint *.vue files
|
|
||||||
plugins: [
|
|
||||||
'vue',
|
|
||||||
'import'
|
|
||||||
],
|
|
||||||
// add your custom rules here
|
|
||||||
rules: {
|
|
||||||
// allow paren-less arrow functions
|
|
||||||
'arrow-parens': 0,
|
|
||||||
// allow async-await
|
|
||||||
'generator-star-spacing': 0,
|
|
||||||
// allow debugger during development
|
|
||||||
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
|
|
||||||
'vue/require-prop-types': 0,
|
|
||||||
'vue/no-unused-vars': 0,
|
|
||||||
'no-tabs': 0,
|
|
||||||
'vue/multi-word-component-names': 0,
|
|
||||||
'vue/no-reserved-component-names': 0
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
7.2.1
|
|
1
.tool-versions
Normal file
1
.tool-versions
Normal file
|
@ -0,0 +1 @@
|
||||||
|
nodejs 20.12.2
|
|
@ -1,20 +1,21 @@
|
||||||
|
labels:
|
||||||
platform: linux/amd64
|
platform: linux/amd64
|
||||||
pipeline:
|
|
||||||
|
steps:
|
||||||
lint:
|
lint:
|
||||||
when:
|
when:
|
||||||
event:
|
event:
|
||||||
- pull_request
|
- pull_request
|
||||||
image: node:18
|
image: node:20
|
||||||
commands:
|
commands:
|
||||||
- yarn
|
- yarn
|
||||||
- yarn lint
|
- yarn lint
|
||||||
#- yarn stylelint
|
|
||||||
|
|
||||||
test:
|
test:
|
||||||
when:
|
when:
|
||||||
event:
|
event:
|
||||||
- pull_request
|
- pull_request
|
||||||
image: node:18
|
image: node:20
|
||||||
commands:
|
commands:
|
||||||
- apt update
|
- apt update
|
||||||
- apt install firefox-esr -y --no-install-recommends
|
- apt install firefox-esr -y --no-install-recommends
|
||||||
|
@ -28,7 +29,7 @@ pipeline:
|
||||||
branch:
|
branch:
|
||||||
- develop
|
- develop
|
||||||
- stable
|
- stable
|
||||||
image: node:18
|
image: node:20
|
||||||
commands:
|
commands:
|
||||||
- yarn
|
- yarn
|
||||||
- yarn build
|
- yarn build
|
||||||
|
@ -40,15 +41,15 @@ pipeline:
|
||||||
branch:
|
branch:
|
||||||
- develop
|
- develop
|
||||||
- stable
|
- stable
|
||||||
image: node:18
|
image: node:20
|
||||||
secrets:
|
secrets:
|
||||||
- SCW_ACCESS_KEY
|
- SCW_ACCESS_KEY
|
||||||
- SCW_SECRET_KEY
|
- SCW_SECRET_KEY
|
||||||
- SCW_DEFAULT_ORGANIZATION_ID
|
- SCW_DEFAULT_ORGANIZATION_ID
|
||||||
commands:
|
commands:
|
||||||
- apt-get update && apt-get install -y rclone wget zip
|
- apt-get update && apt-get install -y rclone wget zip
|
||||||
- wget https://github.com/scaleway/scaleway-cli/releases/download/v2.5.1/scaleway-cli_2.5.1_linux_amd64
|
- wget https://github.com/scaleway/scaleway-cli/releases/download/v2.30.0/scaleway-cli_2.30.0_linux_amd64
|
||||||
- mv scaleway-cli_2.5.1_linux_amd64 scaleway-cli
|
- mv scaleway-cli_2.30.0_linux_amd64 scaleway-cli
|
||||||
- chmod +x scaleway-cli
|
- chmod +x scaleway-cli
|
||||||
- ./scaleway-cli object config install type=rclone
|
- ./scaleway-cli object config install type=rclone
|
||||||
- zip akkoma-fe.zip -r dist
|
- zip akkoma-fe.zip -r dist
|
||||||
|
@ -70,8 +71,8 @@ pipeline:
|
||||||
- SCW_DEFAULT_ORGANIZATION_ID
|
- SCW_DEFAULT_ORGANIZATION_ID
|
||||||
commands:
|
commands:
|
||||||
- apt-get update && apt-get install -y rclone wget git zip
|
- apt-get update && apt-get install -y rclone wget git zip
|
||||||
- wget https://github.com/scaleway/scaleway-cli/releases/download/v2.5.1/scaleway-cli_2.5.1_linux_amd64
|
- wget https://github.com/scaleway/scaleway-cli/releases/download/v2.30.0/scaleway-cli_2.30.0_linux_amd64
|
||||||
- mv scaleway-cli_2.5.1_linux_amd64 scaleway-cli
|
- mv scaleway-cli_2.30.0_linux_amd64 scaleway-cli
|
||||||
- chmod +x scaleway-cli
|
- chmod +x scaleway-cli
|
||||||
- ./scaleway-cli object config install type=rclone
|
- ./scaleway-cli object config install type=rclone
|
||||||
- cd docs
|
- cd docs
|
||||||
|
|
|
@ -20,9 +20,11 @@ To use Akkoma-FE in Akkoma, use the [frontend](https://docs.akkoma.dev/stable/ad
|
||||||
|
|
||||||
## Build Setup
|
## Build Setup
|
||||||
|
|
||||||
|
Make sure you have [Node.js](https://nodejs.org/) installed. You can check `/.woodpecker.yml` for which node version the Akkoma CI currently uses.
|
||||||
|
|
||||||
``` bash
|
``` bash
|
||||||
# install dependencies
|
# install dependencies
|
||||||
npm install -g yarn
|
corepack enable
|
||||||
yarn
|
yarn
|
||||||
|
|
||||||
# serve with hot reload at localhost:8080
|
# serve with hot reload at localhost:8080
|
||||||
|
@ -37,7 +39,7 @@ npm run unit
|
||||||
|
|
||||||
# For Contributors:
|
# For Contributors:
|
||||||
|
|
||||||
You can create file `/config/local.json` (see [example](https://git.pleroma.social/pleroma/pleroma-fe/blob/develop/config/local.example.json)) to enable some convenience dev options:
|
You can create file `/config/local.json` (see [example](https://akkoma.dev/AkkomaGang/akkoma-fe/src/branch/develop/config/local.example.json)) to enable some convenience dev options:
|
||||||
|
|
||||||
* `target`: makes local dev server redirect to some existing instance's BE instead of local BE, useful for testing things in near-production environment and searching for real-life use-cases.
|
* `target`: makes local dev server redirect to some existing instance's BE instead of local BE, useful for testing things in near-production environment and searching for real-life use-cases.
|
||||||
* `staticConfigPreference`: makes FE's `/static/config.json` take preference of BE-served `/api/statusnet/config.json`. Only works in dev mode.
|
* `staticConfigPreference`: makes FE's `/static/config.json` take preference of BE-served `/api/statusnet/config.json`. Only works in dev mode.
|
||||||
|
|
|
@ -1,36 +1,36 @@
|
||||||
// https://github.com/shelljs/shelljs
|
// https://github.com/shelljs/shelljs
|
||||||
require('./check-versions')()
|
require("./check-versions")();
|
||||||
require('shelljs/global')
|
require("shelljs/global");
|
||||||
env.NODE_ENV = 'production'
|
env.NODE_ENV = "production";
|
||||||
|
|
||||||
var path = require('path')
|
var path = require("path");
|
||||||
var config = require('../config')
|
var config = require("../config");
|
||||||
var ora = require('ora')
|
var webpack = require("webpack");
|
||||||
var webpack = require('webpack')
|
var webpackConfig = require("./webpack.prod.conf");
|
||||||
var webpackConfig = require('./webpack.prod.conf')
|
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
' Tip:\n' +
|
" Tip:\n" +
|
||||||
' Built files are meant to be served over an HTTP server.\n' +
|
" Built files are meant to be served over an HTTP server.\n" +
|
||||||
' Opening index.html over file:// won\'t work.\n'
|
" Opening index.html over file:// won't work.\n",
|
||||||
)
|
);
|
||||||
|
|
||||||
var spinner = ora('building for production...')
|
var assetsPath = path.join(
|
||||||
spinner.start()
|
config.build.assetsRoot,
|
||||||
|
config.build.assetsSubDirectory,
|
||||||
var assetsPath = path.join(config.build.assetsRoot, config.build.assetsSubDirectory)
|
);
|
||||||
rm('-rf', assetsPath)
|
rm("-rf", assetsPath);
|
||||||
mkdir('-p', assetsPath)
|
mkdir("-p", assetsPath);
|
||||||
cp('-R', 'static/*', assetsPath)
|
cp("-R", "static/*", assetsPath);
|
||||||
|
|
||||||
webpack(webpackConfig, function (err, stats) {
|
webpack(webpackConfig, function (err, stats) {
|
||||||
spinner.stop()
|
if (err) throw err;
|
||||||
if (err) throw err
|
process.stdout.write(
|
||||||
process.stdout.write(stats.toString({
|
stats.toString({
|
||||||
colors: true,
|
colors: true,
|
||||||
modules: false,
|
modules: false,
|
||||||
children: false,
|
children: false,
|
||||||
chunks: false,
|
chunks: false,
|
||||||
chunkModules: false
|
chunkModules: false,
|
||||||
}) + '\n')
|
}) + "\n",
|
||||||
})
|
);
|
||||||
|
});
|
||||||
|
|
|
@ -5,7 +5,7 @@ var path = require('path')
|
||||||
var express = require('express')
|
var express = require('express')
|
||||||
var webpack = require('webpack')
|
var webpack = require('webpack')
|
||||||
var opn = require('opn')
|
var opn = require('opn')
|
||||||
var proxyMiddleware = require('http-proxy-middleware')
|
const { createProxyMiddleware } = require('http-proxy-middleware');
|
||||||
var webpackConfig = process.env.NODE_ENV === 'testing'
|
var webpackConfig = process.env.NODE_ENV === 'testing'
|
||||||
? require('./webpack.prod.conf')
|
? require('./webpack.prod.conf')
|
||||||
: require('./webpack.dev.conf')
|
: require('./webpack.dev.conf')
|
||||||
|
@ -36,7 +36,13 @@ Object.keys(proxyTable).forEach(function (context) {
|
||||||
if (typeof options === 'string') {
|
if (typeof options === 'string') {
|
||||||
options = { target: options }
|
options = { target: options }
|
||||||
}
|
}
|
||||||
app.use(proxyMiddleware(context, options))
|
const targetUrl = new URL(options.target);
|
||||||
|
// add path
|
||||||
|
targetUrl.pathname = context;
|
||||||
|
options.target = targetUrl.toString();
|
||||||
|
|
||||||
|
console.log("Proxying", context, "to", options.target);
|
||||||
|
app.use(context, createProxyMiddleware(options))
|
||||||
})
|
})
|
||||||
|
|
||||||
// handle fallback for HTML5 history API
|
// handle fallback for HTML5 history API
|
||||||
|
|
|
@ -3,6 +3,7 @@ var config = require('../config')
|
||||||
var utils = require('./utils')
|
var utils = require('./utils')
|
||||||
var projectRoot = path.resolve(__dirname, '../')
|
var projectRoot = path.resolve(__dirname, '../')
|
||||||
var { VueLoaderPlugin } = require('vue-loader')
|
var { VueLoaderPlugin } = require('vue-loader')
|
||||||
|
const ESLintPlugin = require('eslint-webpack-plugin');
|
||||||
|
|
||||||
var env = process.env.NODE_ENV
|
var env = process.env.NODE_ENV
|
||||||
// check env & config/index.js to decide weither to enable CSS Sourcemaps for the
|
// check env & config/index.js to decide weither to enable CSS Sourcemaps for the
|
||||||
|
@ -35,6 +36,7 @@ module.exports = {
|
||||||
],
|
],
|
||||||
fallback: {
|
fallback: {
|
||||||
"url": require.resolve("url/"),
|
"url": require.resolve("url/"),
|
||||||
|
querystring: require.resolve("querystring-es3")
|
||||||
},
|
},
|
||||||
alias: {
|
alias: {
|
||||||
'static': path.resolve(__dirname, '../static'),
|
'static': path.resolve(__dirname, '../static'),
|
||||||
|
@ -47,20 +49,6 @@ module.exports = {
|
||||||
module: {
|
module: {
|
||||||
noParse: /node_modules\/localforage\/dist\/localforage.js/,
|
noParse: /node_modules\/localforage\/dist\/localforage.js/,
|
||||||
rules: [
|
rules: [
|
||||||
{
|
|
||||||
enforce: 'pre',
|
|
||||||
test: /\.(js|vue)$/,
|
|
||||||
include: projectRoot,
|
|
||||||
exclude: /node_modules/,
|
|
||||||
use: {
|
|
||||||
loader: 'eslint-loader',
|
|
||||||
options: {
|
|
||||||
formatter: require('eslint-friendly-formatter'),
|
|
||||||
sourceMap: config.build.productionSourceMap,
|
|
||||||
extract: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
enforce: 'post',
|
enforce: 'post',
|
||||||
test: /\.(json5?|ya?ml)$/, // target json, json5, yaml and yml files
|
test: /\.(json5?|ya?ml)$/, // target json, json5, yaml and yml files
|
||||||
|
@ -118,6 +106,9 @@ module.exports = {
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
new VueLoaderPlugin()
|
new VueLoaderPlugin(),
|
||||||
|
new ESLintPlugin({
|
||||||
|
configType: 'flat'
|
||||||
|
})
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{
|
{
|
||||||
"target": "https://pleroma.soykaf.com/",
|
"target": "https://otp.akkoma.dev/",
|
||||||
"staticConfigPreference": false
|
"staticConfigPreference": false
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,5 +2,4 @@ var { merge } = require('webpack-merge')
|
||||||
var devEnv = require('./dev.env')
|
var devEnv = require('./dev.env')
|
||||||
|
|
||||||
module.exports = merge(devEnv, {
|
module.exports = merge(devEnv, {
|
||||||
NODE_ENV: '"testing"'
|
|
||||||
})
|
})
|
||||||
|
|
31
eslint.config.js
Normal file
31
eslint.config.js
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
const pluginVue = require('eslint-plugin-vue')
|
||||||
|
const pluginImport = require('eslint-plugin-import')
|
||||||
|
|
||||||
|
module.exports = [
|
||||||
|
...pluginVue.configs['flat/recommended'],
|
||||||
|
{
|
||||||
|
languageOptions: {
|
||||||
|
parserOptions: {
|
||||||
|
parser: '@babel/eslint-parser',
|
||||||
|
sourceType: 'module'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
// allow paren-less arrow functions
|
||||||
|
'arrow-parens': 0,
|
||||||
|
// allow async-await
|
||||||
|
'generator-star-spacing': 0,
|
||||||
|
// allow debugger during development
|
||||||
|
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
|
||||||
|
'vue/require-prop-types': 0,
|
||||||
|
'vue/no-unused-vars': 0,
|
||||||
|
'no-tabs': 0,
|
||||||
|
'vue/multi-word-component-names': 0,
|
||||||
|
'vue/no-reserved-component-names': 0
|
||||||
|
},
|
||||||
|
ignores: [
|
||||||
|
'build/*.js',
|
||||||
|
'config/*.js'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
162
package.json
162
package.json
|
@ -12,120 +12,118 @@
|
||||||
"e2e": "node test/e2e/runner.js",
|
"e2e": "node test/e2e/runner.js",
|
||||||
"test": "npm run unit && npm run e2e",
|
"test": "npm run unit && npm run e2e",
|
||||||
"stylelint": "stylelint src/**/*.scss",
|
"stylelint": "stylelint src/**/*.scss",
|
||||||
"lint": "eslint --ext .js,.vue src test/unit/specs test/e2e/specs",
|
"lint": "eslint src test/unit/specs test/e2e/specs",
|
||||||
"lint-fix": "eslint --fix --ext .js,.vue src test/unit/specs test/e2e/specs"
|
"lint-fix": "eslint --fix src test/unit/specs test/e2e/specs"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "7.17.8",
|
"@babel/runtime": "7.17.8",
|
||||||
"@chenfengyuan/vue-qrcode": "2.0.0",
|
"@chenfengyuan/vue-qrcode": "^2.0.0",
|
||||||
"@floatingghost/pinch-zoom-element": "^1.3.1",
|
"@floatingghost/pinch-zoom-element": "^1.3.1",
|
||||||
"@fortawesome/fontawesome-svg-core": "1.3.0",
|
"@fortawesome/fontawesome-svg-core": "^6.5.2",
|
||||||
"@fortawesome/free-regular-svg-icons": "^6.1.2",
|
"@fortawesome/free-regular-svg-icons": "^6.5.2",
|
||||||
"@fortawesome/free-solid-svg-icons": "^6.2.0",
|
"@fortawesome/free-solid-svg-icons": "^6.5.2",
|
||||||
"@fortawesome/vue-fontawesome": "3.0.1",
|
"@fortawesome/vue-fontawesome": "^3.0.8",
|
||||||
"@vuelidate/core": "^2.0.0",
|
"@vuelidate/core": "^2.0.3",
|
||||||
"@vuelidate/validators": "^2.0.0",
|
"@vuelidate/validators": "^2.0.4",
|
||||||
"blurhash": "^2.0.4",
|
"blurhash": "^2.0.5",
|
||||||
"body-scroll-lock": "2.7.1",
|
"body-scroll-lock": "^3.1.5",
|
||||||
"chromatism": "3.0.0",
|
"chromatism": "^3.0.0",
|
||||||
"click-outside-vue3": "4.0.1",
|
"click-outside-vue3": "^4.0.1",
|
||||||
"cropperjs": "1.5.12",
|
"cropperjs": "^1.6.2",
|
||||||
"diff": "3.5.0",
|
"diff": "^5.2.0",
|
||||||
"escape-html": "1.0.3",
|
"escape-html": "^1.0.3",
|
||||||
"iso-639-1": "^2.1.15",
|
"iso-639-1": "^2.1.15",
|
||||||
"js-cookie": "^3.0.1",
|
"js-cookie": "^3.0.1",
|
||||||
"localforage": "1.10.0",
|
"localforage": "^1.10.0",
|
||||||
"parse-link-header": "^2.0.0",
|
"parse-link-header": "^2.0.0",
|
||||||
"phoenix": "1.6.2",
|
"phoenix": "^1.7.12",
|
||||||
"punycode.js": "2.1.0",
|
"punycode.js": "^2.3.1",
|
||||||
"qrcode": "1",
|
"qrcode": "^1.5.3",
|
||||||
"url": "^0.11.0",
|
"querystring-es3": "^0.2.1",
|
||||||
"vue": "^3.2.31",
|
"url": "^0.11.3",
|
||||||
"vue-i18n": "^9.2.2",
|
"vue": "^3.4.38",
|
||||||
"vue-router": "4.0.14",
|
"vue-i18n": "^9.14.0",
|
||||||
"vue-template-compiler": "2.6.11",
|
"vue-router": "^4.4.3",
|
||||||
"vuex": "4.0.2"
|
"vue-template-compiler": "^2.7.16",
|
||||||
|
"vuex": "^4.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "7.17.8",
|
"@babel/core": "^7.24.6",
|
||||||
"@babel/eslint-parser": "^7.19.1",
|
"@babel/eslint-parser": "^7.19.1",
|
||||||
"@babel/plugin-transform-runtime": "7.17.0",
|
"@babel/plugin-transform-runtime": "^7.24.6",
|
||||||
"@babel/preset-env": "7.16.11",
|
"@babel/preset-env": "^7.24.6",
|
||||||
"@babel/register": "7.17.7",
|
"@babel/register": "^7.24.6",
|
||||||
"@intlify/vue-i18n-loader": "^5.0.0",
|
"@intlify/vue-i18n-loader": "^5.0.0",
|
||||||
"@ungap/event-target": "0.2.3",
|
"@ungap/event-target": "^0.2.4",
|
||||||
"@vue/babel-helper-vue-jsx-merge-props": "1.2.1",
|
"@vue/babel-helper-vue-jsx-merge-props": "^1.4.0",
|
||||||
"@vue/babel-plugin-jsx": "1.1.1",
|
"@vue/babel-plugin-jsx": "^1.2.2",
|
||||||
"@vue/compiler-sfc": "^3.1.0",
|
"@vue/compiler-sfc": "^3.1.0",
|
||||||
"@vue/test-utils": "^2.0.2",
|
"@vue/test-utils": "^2.0.2",
|
||||||
"autoprefixer": "6.7.7",
|
"autoprefixer": "^10.4.19",
|
||||||
"babel-loader": "^9.1.0",
|
"babel-loader": "^9.1.0",
|
||||||
"babel-plugin-lodash": "3.3.4",
|
"babel-plugin-lodash": "^3.3.4",
|
||||||
"chai": "^4.3.7",
|
"chai": "^4.3.7",
|
||||||
"chalk": "1.1.3",
|
"chalk": "^1.1.3",
|
||||||
"chromedriver": "^107.0.3",
|
"chromedriver": "^119.0.1",
|
||||||
"connect-history-api-fallback": "^2.0.0",
|
"connect-history-api-fallback": "^2.0.0",
|
||||||
"cross-spawn": "^7.0.3",
|
"cross-spawn": "^7.0.3",
|
||||||
"css-loader": "^6.7.2",
|
"css-loader": "^7.1.2",
|
||||||
"custom-event-polyfill": "^1.0.7",
|
"custom-event-polyfill": "^1.0.7",
|
||||||
"eslint": "^7.32.0",
|
"eslint": "^9.3.0",
|
||||||
"eslint-config-standard": "^17.0.0",
|
"eslint-config-standard": "^17.1.0",
|
||||||
"eslint-friendly-formatter": "^4.0.1",
|
"eslint-friendly-formatter": "^4.0.1",
|
||||||
"eslint-loader": "^4.0.2",
|
"eslint-plugin-import": "^2.29.1",
|
||||||
"eslint-plugin-import": "^2.26.0",
|
|
||||||
"eslint-plugin-node": "^11.1.0",
|
"eslint-plugin-node": "^11.1.0",
|
||||||
"eslint-plugin-promise": "^6.1.1",
|
"eslint-plugin-promise": "^6.2.0",
|
||||||
"eslint-plugin-standard": "^5.0.0",
|
"eslint-plugin-standard": "^5.0.0",
|
||||||
"eslint-plugin-vue": "^9.7.0",
|
"eslint-plugin-vue": "^9.26.0",
|
||||||
"eventsource-polyfill": "0.9.6",
|
"eslint-webpack-plugin": "^4.2.0",
|
||||||
"express": "4.17.3",
|
"eventsource-polyfill": "^0.9.6",
|
||||||
|
"express": "^4.19.2",
|
||||||
"file-loader": "^6.2.0",
|
"file-loader": "^6.2.0",
|
||||||
"function-bind": "1.1.1",
|
"function-bind": "^1.1.2",
|
||||||
"html-webpack-plugin": "^5.5.0",
|
"html-webpack-plugin": "^5.5.0",
|
||||||
"http-proxy-middleware": "0.21.0",
|
"http-proxy-middleware": "^3.0.0",
|
||||||
"inject-loader": "2.0.1",
|
"json-loader": "^0.5.7",
|
||||||
"isparta-loader": "2.0.0",
|
"karma": "^6.4.3",
|
||||||
"json-loader": "0.5.7",
|
"karma-coverage": "^2.2.1",
|
||||||
"karma": "6.3.17",
|
"karma-firefox-launcher": "^2.1.3",
|
||||||
"karma-coverage": "1.1.2",
|
"karma-mocha": "^2.0.1",
|
||||||
"karma-firefox-launcher": "1.3.0",
|
"karma-mocha-reporter": "^2.2.5",
|
||||||
"karma-mocha": "2.0.1",
|
"karma-sinon-chai": "^2.0.2",
|
||||||
"karma-mocha-reporter": "2.2.5",
|
"karma-sourcemap-loader": "^0.4.0",
|
||||||
"karma-sinon-chai": "2.0.2",
|
"karma-spec-reporter": "^0.0.36",
|
||||||
"karma-sourcemap-loader": "0.3.8",
|
|
||||||
"karma-spec-reporter": "0.0.33",
|
|
||||||
"karma-webpack": "^5.0.0",
|
"karma-webpack": "^5.0.0",
|
||||||
"lodash": "4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"lolex": "1.6.0",
|
"lolex": "^6.0.0",
|
||||||
"mini-css-extract-plugin": "0.12.0",
|
"mini-css-extract-plugin": "^2.9.0",
|
||||||
"mocha": "3.5.3",
|
"mocha": "^10.4.0",
|
||||||
"nightwatch": "0.9.21",
|
"nightwatch": "^3.6.3",
|
||||||
"opn": "4.0.2",
|
"opn": "^6.0.0",
|
||||||
"ora": "0.4.1",
|
|
||||||
"postcss-html": "^1.5.0",
|
"postcss-html": "^1.5.0",
|
||||||
"postcss-loader": "3.0.0",
|
"postcss-loader": "^8.1.1",
|
||||||
"postcss-sass": "^0.5.0",
|
"postcss-sass": "^0.5.0",
|
||||||
"raw-loader": "0.5.1",
|
"raw-loader": "^4.0.2",
|
||||||
"sass": "^1.56.0",
|
"sass": "^1.77.2",
|
||||||
"sass-loader": "^13.2.0",
|
"sass-loader": "^14.2.1",
|
||||||
"selenium-server": "2.53.1",
|
"selenium-server": "^3.141.59",
|
||||||
"semver": "5.7.1",
|
"semver": "^7.6.2",
|
||||||
"shelljs": "0.8.5",
|
"shelljs": "^0.8.5",
|
||||||
"sinon": "2.4.1",
|
"sinon": "^18.0.0",
|
||||||
"sinon-chai": "2.14.0",
|
"sinon-chai": "^3.7.0",
|
||||||
"stylelint": "^14.15.0",
|
"stylelint": "^14.15.0",
|
||||||
"stylelint-config-recommended-vue": "^1.4.0",
|
"stylelint-config-recommended-vue": "^1.4.0",
|
||||||
"stylelint-config-standard": "^29.0.0",
|
"stylelint-config-standard": "^29.0.0",
|
||||||
"stylelint-config-standard-scss": "^6.1.0",
|
"stylelint-config-standard-scss": "^6.1.0",
|
||||||
"stylelint-rscss": "^0.4.0",
|
"stylelint-rscss": "^0.4.0",
|
||||||
"url-loader": "^4.1.1",
|
"url-loader": "^4.1.1",
|
||||||
"vue-loader": "^17.0.0",
|
"vue-loader": "^17.4.2",
|
||||||
"vue-style-loader": "^4.1.2",
|
"vue-style-loader": "^4.1.3",
|
||||||
"webpack": "^5.75.0",
|
"webpack": "^5.91.0",
|
||||||
"webpack-dev-middleware": "^5.3.3",
|
"webpack-dev-middleware": "^7.2.1",
|
||||||
"webpack-hot-middleware": "^2.25.1",
|
"webpack-hot-middleware": "^2.26.1",
|
||||||
"webpack-merge": "^5.8.0",
|
"webpack-merge": "^5.10.0",
|
||||||
"workbox-webpack-plugin": "^6.5.4"
|
"workbox-webpack-plugin": "^7.1.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 16.0.0",
|
"node": ">= 16.0.0",
|
||||||
|
|
|
@ -64,6 +64,11 @@ export default {
|
||||||
'-' + this.layoutType
|
'-' + this.layoutType
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
pageBackground () {
|
||||||
|
return this.mergedConfig.displayPageBackgrounds
|
||||||
|
? this.$store.state.users.displayBackground
|
||||||
|
: null
|
||||||
|
},
|
||||||
currentUser () { return this.$store.state.users.currentUser },
|
currentUser () { return this.$store.state.users.currentUser },
|
||||||
userBackground () { return this.currentUser.background_image },
|
userBackground () { return this.currentUser.background_image },
|
||||||
instanceBackground () {
|
instanceBackground () {
|
||||||
|
@ -71,7 +76,7 @@ export default {
|
||||||
? null
|
? null
|
||||||
: this.$store.state.instance.background
|
: this.$store.state.instance.background
|
||||||
},
|
},
|
||||||
background () { return this.userBackground || this.instanceBackground },
|
background () { return this.pageBackground || this.userBackground || this.instanceBackground },
|
||||||
bgStyle () {
|
bgStyle () {
|
||||||
if (this.background) {
|
if (this.background) {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
font-size: 14px;
|
font-size: 0.875rem;
|
||||||
// overflow-x: clip causes my browser's tab to crash with SIGILL lul
|
// overflow-x: clip causes my browser's tab to crash with SIGILL lul
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ body {
|
||||||
color: var(--text, $fallback--text);
|
color: var(--text, $fallback--text);
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
overscroll-behavior-y: none;
|
overscroll-behavior-y: auto;
|
||||||
overflow-x: clip;
|
overflow-x: clip;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
:bound-to="{ x: 'container' }"
|
:bound-to="{ x: 'container' }"
|
||||||
remove-padding
|
remove-padding
|
||||||
>
|
>
|
||||||
<template v-slot:content>
|
<template #content>
|
||||||
<div class="dropdown-menu">
|
<div class="dropdown-menu">
|
||||||
<template v-if="relationship.following">
|
<template v-if="relationship.following">
|
||||||
<button
|
<button
|
||||||
|
@ -71,7 +71,7 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:trigger>
|
<template #trigger>
|
||||||
<button class="button-unstyled ellipsis-button">
|
<button class="button-unstyled ellipsis-button">
|
||||||
<FAIcon
|
<FAIcon
|
||||||
class="icon"
|
class="icon"
|
||||||
|
@ -93,7 +93,7 @@
|
||||||
keypath="user_card.block_confirm"
|
keypath="user_card.block_confirm"
|
||||||
tag="span"
|
tag="span"
|
||||||
>
|
>
|
||||||
<template v-slot:user>
|
<template #user>
|
||||||
<span
|
<span
|
||||||
v-text="user.screen_name_ui"
|
v-text="user.screen_name_ui"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
white-space: pre-line;
|
white-space: pre-line;
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
overflow: scroll;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.-static {
|
&.-static {
|
||||||
|
|
|
@ -246,8 +246,8 @@
|
||||||
ref="flash"
|
ref="flash"
|
||||||
class="flash"
|
class="flash"
|
||||||
:src="attachment.large_thumb_url || attachment.url"
|
:src="attachment.large_thumb_url || attachment.url"
|
||||||
@playerOpened="setFlashLoaded(true)"
|
@player-opened="setFlashLoaded(true)"
|
||||||
@playerClosed="setFlashLoaded(false)"
|
@player-closed="setFlashLoaded(false)"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -22,12 +22,12 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
emits: ['update:modelValue'],
|
|
||||||
props: [
|
props: [
|
||||||
'modelValue',
|
'modelValue',
|
||||||
'indeterminate',
|
'indeterminate',
|
||||||
'disabled'
|
'disabled'
|
||||||
]
|
],
|
||||||
|
emits: ['update:modelValue']
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
:model-value="present"
|
:model-value="present"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
class="opt"
|
class="opt"
|
||||||
@update:modelValue="$emit('update:modelValue', typeof modelValue === 'undefined' ? fallback : undefined)"
|
@update:model-value="$emit('update:modelValue', typeof modelValue === 'undefined' ? fallback : undefined)"
|
||||||
/>
|
/>
|
||||||
<div class="input color-input-field">
|
<div class="input color-input-field">
|
||||||
<input
|
<input
|
||||||
|
@ -46,7 +46,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<style lang="scss" src="./color_input.scss"></style>
|
|
||||||
<script>
|
<script>
|
||||||
import Checkbox from '../checkbox/checkbox.vue'
|
import Checkbox from '../checkbox/checkbox.vue'
|
||||||
import { hex2rgb } from '../../services/color_convert/color_convert.js'
|
import { hex2rgb } from '../../services/color_convert/color_convert.js'
|
||||||
|
@ -108,6 +107,7 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
<style lang="scss" src="./color_input.scss"></style>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.color-control {
|
.color-control {
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
</dialog-modal>
|
</dialog-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script src="./confirm_modal.js"></script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '../../_variables';
|
@import '../../_variables';
|
||||||
|
|
||||||
|
@ -35,5 +37,3 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script src="./confirm_modal.js"></script>
|
|
||||||
|
|
|
@ -267,11 +267,11 @@ const conversation = {
|
||||||
},
|
},
|
||||||
replies () {
|
replies () {
|
||||||
let i = 1
|
let i = 1
|
||||||
// eslint-disable-next-line camelcase
|
|
||||||
return reduce(this.conversation, (result, { id, in_reply_to_status_id }) => {
|
return reduce(this.conversation, (result, { id, in_reply_to_status_id }) => {
|
||||||
/* eslint-disable camelcase */
|
|
||||||
const irid = in_reply_to_status_id
|
const irid = in_reply_to_status_id
|
||||||
/* eslint-enable camelcase */
|
|
||||||
if (irid) {
|
if (irid) {
|
||||||
result[irid] = result[irid] || []
|
result[irid] = result[irid] || []
|
||||||
result[irid].push({
|
result[irid].push({
|
||||||
|
|
|
@ -91,7 +91,7 @@
|
||||||
:controlled-set-media-playing="(newVal) => toggleStatusContentProperty(status.id, 'mediaPlaying', newVal)"
|
:controlled-set-media-playing="(newVal) => toggleStatusContentProperty(status.id, 'mediaPlaying', newVal)"
|
||||||
|
|
||||||
@goto="setHighlight"
|
@goto="setHighlight"
|
||||||
@toggleExpanded="toggleExpanded"
|
@toggle-expanded="toggleExpanded"
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
v-if="showOtherRepliesButtonBelowStatus && getReplies(status.id).length > 1"
|
v-if="showOtherRepliesButtonBelowStatus && getReplies(status.id).length > 1"
|
||||||
|
@ -184,7 +184,7 @@
|
||||||
:toggle-status-content-property="toggleStatusContentProperty"
|
:toggle-status-content-property="toggleStatusContentProperty"
|
||||||
|
|
||||||
@goto="setHighlight"
|
@goto="setHighlight"
|
||||||
@toggleExpanded="toggleExpanded"
|
@toggle-expanded="toggleExpanded"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -44,9 +44,9 @@
|
||||||
/>
|
/>
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link
|
<router-link
|
||||||
|
v-if="publicTimelineVisible"
|
||||||
:to="{ name: 'public-timeline' }"
|
:to="{ name: 'public-timeline' }"
|
||||||
class="nav-icon"
|
class="nav-icon"
|
||||||
v-if="publicTimelineVisible"
|
|
||||||
>
|
>
|
||||||
<FAIcon
|
<FAIcon
|
||||||
fixed-width
|
fixed-width
|
||||||
|
@ -68,9 +68,9 @@
|
||||||
/>
|
/>
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link
|
<router-link
|
||||||
|
v-if="federatedTimelineVisible"
|
||||||
:to="{ name: 'public-external-timeline' }"
|
:to="{ name: 'public-external-timeline' }"
|
||||||
class="nav-icon"
|
class="nav-icon"
|
||||||
v-if="federatedTimelineVisible"
|
|
||||||
>
|
>
|
||||||
<FAIcon
|
<FAIcon
|
||||||
fixed-width
|
fixed-width
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
class="btn button-default"
|
class="btn button-default"
|
||||||
>
|
>
|
||||||
{{ $t('domain_mute_card.unmute') }}
|
{{ $t('domain_mute_card.unmute') }}
|
||||||
<template v-slot:progress>
|
<template #progress>
|
||||||
{{ $t('domain_mute_card.unmute_progress') }}
|
{{ $t('domain_mute_card.unmute_progress') }}
|
||||||
</template>
|
</template>
|
||||||
</ProgressButton>
|
</ProgressButton>
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
class="btn button-default"
|
class="btn button-default"
|
||||||
>
|
>
|
||||||
{{ $t('domain_mute_card.mute') }}
|
{{ $t('domain_mute_card.mute') }}
|
||||||
<template v-slot:progress>
|
<template #progress>
|
||||||
{{ $t('domain_mute_card.mute_progress') }}
|
{{ $t('domain_mute_card.mute_progress') }}
|
||||||
</template>
|
</template>
|
||||||
</ProgressButton>
|
</ProgressButton>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<Modal
|
<Modal
|
||||||
v-if="isFormVisible"
|
v-if="isFormVisible"
|
||||||
class="edit-form-modal-view"
|
class="edit-form-modal-view"
|
||||||
@backdropClicked="closeModal"
|
@backdrop-clicked="closeModal"
|
||||||
>
|
>
|
||||||
<div class="edit-form-modal-panel panel">
|
<div class="edit-form-modal-panel panel">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
|
@ -11,10 +11,10 @@
|
||||||
<PostStatusForm
|
<PostStatusForm
|
||||||
class="panel-body"
|
class="panel-body"
|
||||||
v-bind="params"
|
v-bind="params"
|
||||||
@posted="closeModal"
|
:disable-polls="true"
|
||||||
:disablePolls="true"
|
:disable-visibility-selector="true"
|
||||||
:disableVisibilitySelector="true"
|
|
||||||
:post-handler="doEditStatus"
|
:post-handler="doEditStatus"
|
||||||
|
@posted="closeModal"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
|
@ -43,7 +43,10 @@
|
||||||
:class="{ highlighted: index === highlighted }"
|
:class="{ highlighted: index === highlighted }"
|
||||||
@click.stop.prevent="onClick($event, suggestion)"
|
@click.stop.prevent="onClick($event, suggestion)"
|
||||||
>
|
>
|
||||||
<span v-if="!suggestion.mfm" class="image">
|
<span
|
||||||
|
v-if="!suggestion.mfm"
|
||||||
|
class="image"
|
||||||
|
>
|
||||||
<img
|
<img
|
||||||
v-if="suggestion.img"
|
v-if="suggestion.img"
|
||||||
:src="suggestion.img"
|
:src="suggestion.img"
|
||||||
|
|
|
@ -122,14 +122,14 @@ export const suggestUsers = ({ dispatch, state }) => {
|
||||||
const screenNameAlphabetically = a.screen_name > b.screen_name ? 1 : -1
|
const screenNameAlphabetically = a.screen_name > b.screen_name ? 1 : -1
|
||||||
|
|
||||||
return diff + nameAlphabetically + screenNameAlphabetically
|
return diff + nameAlphabetically + screenNameAlphabetically
|
||||||
/* eslint-disable camelcase */
|
|
||||||
}).map(({ screen_name, screen_name_ui, name, profile_image_url_original }) => ({
|
}).map(({ screen_name, screen_name_ui, name, profile_image_url_original }) => ({
|
||||||
displayText: screen_name_ui,
|
displayText: screen_name_ui,
|
||||||
detailText: name,
|
detailText: name,
|
||||||
imageUrl: profile_image_url_original,
|
imageUrl: profile_image_url_original,
|
||||||
replacement: '@' + screen_name + ' '
|
replacement: '@' + screen_name + ' '
|
||||||
}))
|
}))
|
||||||
/* eslint-enable camelcase */
|
|
||||||
|
|
||||||
suggestions = newSuggestions || []
|
suggestions = newSuggestions || []
|
||||||
return suggestions
|
return suggestions
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
:bound-to="{ x: 'container' }"
|
:bound-to="{ x: 'container' }"
|
||||||
remove-padding
|
remove-padding
|
||||||
>
|
>
|
||||||
<template v-slot:content="{close}">
|
<template #content="{close}">
|
||||||
<div class="dropdown-menu">
|
<div class="dropdown-menu">
|
||||||
<button
|
<button
|
||||||
v-if="canMute && !status.thread_muted"
|
v-if="canMute && !status.thread_muted"
|
||||||
|
@ -172,7 +172,7 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:trigger>
|
<template #trigger>
|
||||||
<button class="button-unstyled popover-trigger">
|
<button class="button-unstyled popover-trigger">
|
||||||
<FAIcon
|
<FAIcon
|
||||||
class="fa-scale-110 fa-old-padding"
|
class="fa-scale-110 fa-old-padding"
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<basic-user-card :user="user" v-if="show">
|
<basic-user-card
|
||||||
|
v-if="show"
|
||||||
|
:user="user"
|
||||||
|
>
|
||||||
<div class="follow-request-card-content-container">
|
<div class="follow-request-card-content-container">
|
||||||
<button
|
<button
|
||||||
class="btn button-default"
|
class="btn button-default"
|
||||||
|
|
|
@ -31,8 +31,8 @@
|
||||||
:description="descriptions && descriptions[attachment.id]"
|
:description="descriptions && descriptions[attachment.id]"
|
||||||
:hide-description="size === 'small' || tooManyAttachments && hidingLong"
|
:hide-description="size === 'small' || tooManyAttachments && hidingLong"
|
||||||
:style="itemStyle(attachment.id, row.items)"
|
:style="itemStyle(attachment.id, row.items)"
|
||||||
@setMedia="onMedia"
|
@set-media="onMedia"
|
||||||
@naturalSizeLoad="onNaturalSizeLoad"
|
@natural-size-load="onNaturalSizeLoad"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -42,6 +42,7 @@ export default {
|
||||||
@import '../../_variables.scss';
|
@import '../../_variables.scss';
|
||||||
|
|
||||||
.list {
|
.list {
|
||||||
|
min-height: 1em;
|
||||||
&-item:not(:last-child) {
|
&-item:not(:last-child) {
|
||||||
border-bottom: 1px solid;
|
border-bottom: 1px solid;
|
||||||
border-bottom-color: $fallback--border;
|
border-bottom-color: $fallback--border;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<Modal
|
<Modal
|
||||||
v-if="showing"
|
v-if="showing"
|
||||||
class="media-modal-view"
|
class="media-modal-view"
|
||||||
@backdropClicked="hideIfNotSwiped"
|
@backdrop-clicked="hideIfNotSwiped"
|
||||||
>
|
>
|
||||||
<SwipeClick
|
<SwipeClick
|
||||||
v-if="type === 'image'"
|
v-if="type === 'image'"
|
||||||
|
|
|
@ -42,7 +42,7 @@ const mediaUpload = {
|
||||||
.then((fileData) => {
|
.then((fileData) => {
|
||||||
self.$emit('uploaded', fileData)
|
self.$emit('uploaded', fileData)
|
||||||
self.decreaseUploadCount()
|
self.decreaseUploadCount()
|
||||||
}, (error) => { // eslint-disable-line handle-callback-err
|
}, (error) => {
|
||||||
self.$emit('upload-failed', 'default')
|
self.$emit('upload-failed', 'default')
|
||||||
self.decreaseUploadCount()
|
self.decreaseUploadCount()
|
||||||
})
|
})
|
||||||
|
|
|
@ -93,9 +93,6 @@ const MentionLink = {
|
||||||
this.highlightType
|
this.highlightType
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
useAtIcon () {
|
|
||||||
return this.mergedConfig.useAtIcon
|
|
||||||
},
|
|
||||||
isRemote () {
|
isRemote () {
|
||||||
return this.userName !== this.userNameFull
|
return this.userName !== this.userNameFull
|
||||||
},
|
},
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
class="panel-heading"
|
class="panel-heading"
|
||||||
@click="toggleHidden"
|
@click="toggleHidden"
|
||||||
>
|
>
|
||||||
<h4>{{ $t('moderation.reports.report') + ' ' + this.account.screen_name }}</h4>
|
<h4>{{ $t('moderation.reports.report') + ' ' + account.screen_name }}</h4>
|
||||||
<button
|
<button
|
||||||
v-if="isOpen"
|
v-if="isOpen"
|
||||||
class="button-default"
|
class="button-default"
|
||||||
|
@ -35,7 +35,10 @@
|
||||||
<div v-if="content">
|
<div v-if="content">
|
||||||
{{ decode(content) }}
|
{{ decode(content) }}
|
||||||
</div>
|
</div>
|
||||||
<i v-else class="faint">
|
<i
|
||||||
|
v-else
|
||||||
|
class="faint"
|
||||||
|
>
|
||||||
{{ $t('moderation.reports.no_content') }}
|
{{ $t('moderation.reports.no_content') }}
|
||||||
</i>
|
</i>
|
||||||
<div class="report-author">
|
<div class="report-author">
|
||||||
|
@ -43,12 +46,12 @@
|
||||||
class="small-avatar"
|
class="small-avatar"
|
||||||
:user="actor"
|
:user="actor"
|
||||||
/>
|
/>
|
||||||
{{ this.actor.screen_name }}
|
{{ actor.screen_name }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
v-if="!hidden && statuses.length > 0"
|
||||||
class="dropdown"
|
class="dropdown"
|
||||||
v-if="!hidden && this.statuses.length > 0"
|
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="button button-unstyled dropdown-header"
|
class="button button-unstyled dropdown-header"
|
||||||
|
@ -74,8 +77,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
v-if="!hidden && notes.length > 0"
|
||||||
class="dropdown"
|
class="dropdown"
|
||||||
v-if="!hidden && this.notes.length > 0"
|
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="button button-unstyled dropdown-header"
|
class="button button-unstyled dropdown-header"
|
||||||
|
@ -99,9 +102,9 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="report-add-note">
|
<div class="report-add-note">
|
||||||
<textarea
|
<textarea
|
||||||
|
v-model.trim="note"
|
||||||
rows="1"
|
rows="1"
|
||||||
cols="1"
|
cols="1"
|
||||||
v-model.trim="note"
|
|
||||||
:placeholder="$t('moderation.reports.note_placeholder')"
|
:placeholder="$t('moderation.reports.note_placeholder')"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
|
@ -134,7 +137,7 @@
|
||||||
:offset="{ y: 5 }"
|
:offset="{ y: 5 }"
|
||||||
remove-padding
|
remove-padding
|
||||||
>
|
>
|
||||||
<template v-slot:trigger>
|
<template #trigger>
|
||||||
<button
|
<button
|
||||||
class="btn button-default"
|
class="btn button-default"
|
||||||
:disabled="!tagPolicyEnabled"
|
:disabled="!tagPolicyEnabled"
|
||||||
|
@ -147,7 +150,7 @@
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:content="{close}">
|
<template #content="{close}">
|
||||||
<div
|
<div
|
||||||
class="dropdown-menu"
|
class="dropdown-menu"
|
||||||
:disabled="!tagPolicyEnabled"
|
:disabled="!tagPolicyEnabled"
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
class="small-avatar"
|
class="small-avatar"
|
||||||
:user="user"
|
:user="user"
|
||||||
/>
|
/>
|
||||||
{{ this.user.screen_name }}
|
{{ user.screen_name }}
|
||||||
</div>
|
</div>
|
||||||
<div class="header-right">
|
<div class="header-right">
|
||||||
<Timeago
|
<Timeago
|
||||||
|
|
|
@ -22,6 +22,9 @@ export default {
|
||||||
default: false
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
emits: [
|
||||||
|
'backdropClicked',
|
||||||
|
],
|
||||||
computed: {
|
computed: {
|
||||||
classes () {
|
classes () {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
@show="setToggled(true)"
|
@show="setToggled(true)"
|
||||||
@close="setToggled(false)"
|
@close="setToggled(false)"
|
||||||
>
|
>
|
||||||
<template v-slot:content>
|
<template #content>
|
||||||
<div class="dropdown-menu">
|
<div class="dropdown-menu">
|
||||||
<span v-if="user.is_local">
|
<span v-if="user.is_local">
|
||||||
<button
|
<button
|
||||||
|
@ -122,7 +122,7 @@
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:trigger>
|
<template #trigger>
|
||||||
<button
|
<button
|
||||||
class="btn button-default btn-block moderation-tools-button"
|
class="btn button-default btn-block moderation-tools-button"
|
||||||
:class="{ toggled }"
|
:class="{ toggled }"
|
||||||
|
@ -137,11 +137,11 @@
|
||||||
v-if="showDeleteUserDialog"
|
v-if="showDeleteUserDialog"
|
||||||
:on-cancel="deleteUserDialog.bind(this, false)"
|
:on-cancel="deleteUserDialog.bind(this, false)"
|
||||||
>
|
>
|
||||||
<template v-slot:header>
|
<template #header>
|
||||||
{{ $t('user_card.admin_menu.delete_user') }}
|
{{ $t('user_card.admin_menu.delete_user') }}
|
||||||
</template>
|
</template>
|
||||||
<p>{{ $t('user_card.admin_menu.delete_user_confirmation') }}</p>
|
<p>{{ $t('user_card.admin_menu.delete_user_confirmation') }}</p>
|
||||||
<template v-slot:footer>
|
<template #footer>
|
||||||
<button
|
<button
|
||||||
class="btn button-default"
|
class="btn button-default"
|
||||||
@click="deleteUserDialog(false)"
|
@click="deleteUserDialog(false)"
|
||||||
|
|
|
@ -6,6 +6,7 @@ import UserCard from '../user_card/user_card.vue'
|
||||||
import Timeago from '../timeago/timeago.vue'
|
import Timeago from '../timeago/timeago.vue'
|
||||||
import RichContent from 'src/components/rich_content/rich_content.jsx'
|
import RichContent from 'src/components/rich_content/rich_content.jsx'
|
||||||
import ConfirmModal from '../confirm_modal/confirm_modal.vue'
|
import ConfirmModal from '../confirm_modal/confirm_modal.vue'
|
||||||
|
import StillImage from '../still-image/still-image.vue'
|
||||||
import { isStatusNotification } from '../../services/notification_utils/notification_utils.js'
|
import { isStatusNotification } from '../../services/notification_utils/notification_utils.js'
|
||||||
import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js'
|
import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js'
|
||||||
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
|
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
|
||||||
|
@ -50,7 +51,8 @@ const Notification = {
|
||||||
Timeago,
|
Timeago,
|
||||||
Status,
|
Status,
|
||||||
RichContent,
|
RichContent,
|
||||||
ConfirmModal
|
ConfirmModal,
|
||||||
|
StillImage
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
toggleUserExpanded () {
|
toggleUserExpanded () {
|
||||||
|
|
|
@ -116,12 +116,13 @@
|
||||||
scope="global"
|
scope="global"
|
||||||
keypath="notifications.reacted_with"
|
keypath="notifications.reacted_with"
|
||||||
>
|
>
|
||||||
<img
|
<still-image
|
||||||
v-if="notification.emoji_url !== null"
|
v-if="notification.emoji_url !== null"
|
||||||
class="notification-reaction-emoji"
|
class="notification-reaction-emoji"
|
||||||
:src="notification.emoji_url"
|
:src="notification.emoji_url"
|
||||||
:name="notification.emoji"
|
:title="notification.emoji"
|
||||||
>
|
:alt="notification.emoji"
|
||||||
|
/>
|
||||||
<span
|
<span
|
||||||
v-else
|
v-else
|
||||||
class="emoji-reaction-emoji"
|
class="emoji-reaction-emoji"
|
||||||
|
@ -151,7 +152,6 @@
|
||||||
>
|
>
|
||||||
<Timeago
|
<Timeago
|
||||||
:time="notification.created_at"
|
:time="notification.created_at"
|
||||||
:with-direction="true"
|
|
||||||
:auto-update="240"
|
:auto-update="240"
|
||||||
/>
|
/>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
placement="bottom"
|
placement="bottom"
|
||||||
:bound-to="{ x: 'container' }"
|
:bound-to="{ x: 'container' }"
|
||||||
>
|
>
|
||||||
<template v-slot:content>
|
<template #content>
|
||||||
<div class="dropdown-menu">
|
<div class="dropdown-menu">
|
||||||
<button
|
<button
|
||||||
class="button-default dropdown-item"
|
class="button-default dropdown-item"
|
||||||
|
@ -72,7 +72,7 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:trigger>
|
<template #trigger>
|
||||||
<button class="filter-trigger-button button-unstyled">
|
<button class="filter-trigger-button button-unstyled">
|
||||||
<FAIcon icon="filter" />
|
<FAIcon icon="filter" />
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -105,9 +105,12 @@
|
||||||
flex: 1;
|
flex: 1;
|
||||||
padding-left: 0.8em;
|
padding-left: 0.8em;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heading-right, .notification-right {
|
||||||
.timeago {
|
.timeago {
|
||||||
min-width: 3em;
|
display: inline-block;
|
||||||
|
min-width: 6em;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
:model-value="present"
|
:model-value="present"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
class="opt"
|
class="opt"
|
||||||
@update:modelValue="$emit('update:modelValue', !present ? fallback : undefined)"
|
@update:model-value="$emit('update:modelValue', !present ? fallback : undefined)"
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
:id="name"
|
:id="name"
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
<pinch-zoom
|
<pinch-zoom
|
||||||
class="pinch-zoom-parent"
|
class="pinch-zoom-parent"
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
v-on="$listeners"
|
|
||||||
>
|
>
|
||||||
<slot />
|
<slot />
|
||||||
</pinch-zoom>
|
</pinch-zoom>
|
||||||
|
|
|
@ -9,11 +9,12 @@ import StatusContent from '../status_content/status_content.vue'
|
||||||
import fileTypeService from '../../services/file_type/file_type.service.js'
|
import fileTypeService from '../../services/file_type/file_type.service.js'
|
||||||
import { findOffset } from '../../services/offset_finder/offset_finder.service.js'
|
import { findOffset } from '../../services/offset_finder/offset_finder.service.js'
|
||||||
import { reject, map, uniqBy, debounce } from 'lodash'
|
import { reject, map, uniqBy, debounce } from 'lodash'
|
||||||
|
import { usePostLanguageOptions } from 'src/lib/post_language'
|
||||||
import suggestor from '../emoji_input/suggestor.js'
|
import suggestor from '../emoji_input/suggestor.js'
|
||||||
import { mapGetters, mapState } from 'vuex'
|
import { mapGetters, mapState } from 'vuex'
|
||||||
import Checkbox from '../checkbox/checkbox.vue'
|
import Checkbox from '../checkbox/checkbox.vue'
|
||||||
import Select from '../select/select.vue'
|
import Select from '../select/select.vue'
|
||||||
import iso6391 from 'iso-639-1'
|
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
|
@ -62,6 +63,13 @@ const deleteDraft = (draftKey) => {
|
||||||
localStorage.setItem('drafts', JSON.stringify(draftData));
|
localStorage.setItem('drafts', JSON.stringify(draftData));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const interfaceToISOLanguage = (ilang) => {
|
||||||
|
const sep = ilang.indexOf("_");
|
||||||
|
return sep < 0 ?
|
||||||
|
ilang :
|
||||||
|
ilang.substr(0, sep);
|
||||||
|
}
|
||||||
|
|
||||||
const PostStatusForm = {
|
const PostStatusForm = {
|
||||||
props: [
|
props: [
|
||||||
'statusId',
|
'statusId',
|
||||||
|
@ -129,6 +137,13 @@ const PostStatusForm = {
|
||||||
this.$refs.textarea.focus()
|
this.$refs.textarea.focus()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
setup() {
|
||||||
|
const {postLanguageOptions} = usePostLanguageOptions()
|
||||||
|
|
||||||
|
return {
|
||||||
|
postLanguageOptions,
|
||||||
|
}
|
||||||
|
},
|
||||||
data () {
|
data () {
|
||||||
const preset = this.$route.query.message
|
const preset = this.$route.query.message
|
||||||
let statusText = preset || ''
|
let statusText = preset || ''
|
||||||
|
@ -138,7 +153,8 @@ const PostStatusForm = {
|
||||||
statusText = buildMentionsString({ user: this.repliedUser, attentions: this.attentions }, currentUser)
|
statusText = buildMentionsString({ user: this.repliedUser, attentions: this.attentions }, currentUser)
|
||||||
}
|
}
|
||||||
|
|
||||||
const { postContentType: contentType, sensitiveByDefault, sensitiveIfSubject, interfaceLanguage } = this.$store.getters.mergedConfig
|
const { postContentType: contentType, postLanguage: defaultPostLanguage, sensitiveByDefault, sensitiveIfSubject, interfaceLanguage, alwaysShowSubjectInput } = this.$store.getters.mergedConfig
|
||||||
|
const postLanguage = defaultPostLanguage || interfaceToISOLanguage(interfaceLanguage)
|
||||||
|
|
||||||
let statusParams = {
|
let statusParams = {
|
||||||
spoilerText: this.subject || '',
|
spoilerText: this.subject || '',
|
||||||
|
@ -149,7 +165,7 @@ const PostStatusForm = {
|
||||||
poll: {},
|
poll: {},
|
||||||
mediaDescriptions: {},
|
mediaDescriptions: {},
|
||||||
visibility: this.suggestedVisibility(),
|
visibility: this.suggestedVisibility(),
|
||||||
language: interfaceLanguage,
|
language: postLanguage,
|
||||||
contentType
|
contentType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,7 +180,7 @@ const PostStatusForm = {
|
||||||
poll: this.statusPoll || {},
|
poll: this.statusPoll || {},
|
||||||
mediaDescriptions: this.statusMediaDescriptions || {},
|
mediaDescriptions: this.statusMediaDescriptions || {},
|
||||||
visibility: this.statusScope || this.suggestedVisibility(),
|
visibility: this.statusScope || this.suggestedVisibility(),
|
||||||
language: this.statusLanguage || interfaceLanguage,
|
language: this.statusLanguage || postLanguage,
|
||||||
contentType: statusContentType
|
contentType: statusContentType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,6 +215,10 @@ const PostStatusForm = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When first loading the form, hide the subject (CW) field if it's disabled or doesn't have a starting value.
|
||||||
|
// "disableSubject" seems to take priority over "alwaysShowSubjectInput".
|
||||||
|
const showSubject = !this.disableSubject && (statusParams.spoilerText || alwaysShowSubjectInput)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
dropFiles: [],
|
dropFiles: [],
|
||||||
uploadingFiles: false,
|
uploadingFiles: false,
|
||||||
|
@ -213,7 +233,10 @@ const PostStatusForm = {
|
||||||
preview: null,
|
preview: null,
|
||||||
previewLoading: false,
|
previewLoading: false,
|
||||||
emojiInputShown: false,
|
emojiInputShown: false,
|
||||||
idempotencyKey: ''
|
idempotencyKey: '',
|
||||||
|
activeEmojiInput: undefined,
|
||||||
|
activeTextInput: undefined,
|
||||||
|
subjectVisible: showSubject
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -302,9 +325,6 @@ const PostStatusForm = {
|
||||||
...mapState({
|
...mapState({
|
||||||
mobileLayout: state => state.interface.mobileLayout
|
mobileLayout: state => state.interface.mobileLayout
|
||||||
}),
|
}),
|
||||||
isoLanguages () {
|
|
||||||
return iso6391.getAllCodes();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'newStatus': {
|
'newStatus': {
|
||||||
|
@ -674,8 +694,33 @@ const PostStatusForm = {
|
||||||
this.$refs['emoji-input'].resize()
|
this.$refs['emoji-input'].resize()
|
||||||
},
|
},
|
||||||
showEmojiPicker () {
|
showEmojiPicker () {
|
||||||
this.$refs['textarea'].focus()
|
if (!this.activeEmojiInput || !this.activeTextInput)
|
||||||
this.$refs['emoji-input'].triggerShowPicker()
|
this.focusStatusInput()
|
||||||
|
|
||||||
|
this.$refs[this.activeTextInput].focus()
|
||||||
|
this.$refs[this.activeEmojiInput].triggerShowPicker()
|
||||||
|
},
|
||||||
|
focusStatusInput() {
|
||||||
|
this.activeEmojiInput = 'emoji-input'
|
||||||
|
this.activeTextInput = 'textarea'
|
||||||
|
},
|
||||||
|
focusSubjectInput() {
|
||||||
|
this.activeEmojiInput = 'subject-emoji-input'
|
||||||
|
this.activeTextInput = 'subject-input'
|
||||||
|
},
|
||||||
|
toggleSubjectVisible() {
|
||||||
|
// If hiding CW, then we need to clear the subject and reset focus
|
||||||
|
if (this.subjectVisible)
|
||||||
|
{
|
||||||
|
this.focusStatusInput()
|
||||||
|
|
||||||
|
// "nsfw" property is normally set by the @change listener, but this bypasses it.
|
||||||
|
// We need to clear it manually instead.
|
||||||
|
this.newStatus.spoilerText = ''
|
||||||
|
this.newStatus.nsfw = false
|
||||||
|
}
|
||||||
|
|
||||||
|
this.subjectVisible = !this.subjectVisible
|
||||||
},
|
},
|
||||||
clearError () {
|
clearError () {
|
||||||
this.error = null
|
this.error = null
|
||||||
|
|
|
@ -118,13 +118,16 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<EmojiInput
|
<EmojiInput
|
||||||
v-if="!disableSubject && (newStatus.spoilerText || alwaysShowSubject)"
|
v-if="subjectVisible"
|
||||||
|
ref="subject-emoji-input"
|
||||||
v-model="newStatus.spoilerText"
|
v-model="newStatus.spoilerText"
|
||||||
enable-emoji-picker
|
enable-emoji-picker
|
||||||
|
hide-emoji-button
|
||||||
:suggest="emojiSuggestor"
|
:suggest="emojiSuggestor"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
|
ref="subject-input"
|
||||||
v-model="newStatus.spoilerText"
|
v-model="newStatus.spoilerText"
|
||||||
type="text"
|
type="text"
|
||||||
:placeholder="$t('post_status.content_warning')"
|
:placeholder="$t('post_status.content_warning')"
|
||||||
|
@ -132,6 +135,7 @@
|
||||||
size="1"
|
size="1"
|
||||||
class="form-post-subject"
|
class="form-post-subject"
|
||||||
@input="onSubjectInput"
|
@input="onSubjectInput"
|
||||||
|
@focus="focusSubjectInput()"
|
||||||
>
|
>
|
||||||
</EmojiInput>
|
</EmojiInput>
|
||||||
<i18n-t
|
<i18n-t
|
||||||
|
@ -166,13 +170,14 @@
|
||||||
cols="1"
|
cols="1"
|
||||||
:disabled="posting && !optimisticPosting"
|
:disabled="posting && !optimisticPosting"
|
||||||
class="form-post-body"
|
class="form-post-body"
|
||||||
:class="{ 'scrollable-form': !!maxHeight }"
|
:class="{ 'scrollable-form': !!maxHeight, '-has-subject': subjectVisible }"
|
||||||
@keydown.exact.enter="submitOnEnter && postStatus($event, newStatus)"
|
@keydown.exact.enter="submitOnEnter && postStatus($event, newStatus)"
|
||||||
@keydown.meta.enter="postStatus($event, newStatus)"
|
@keydown.meta.enter="postStatus($event, newStatus)"
|
||||||
@keydown.ctrl.enter="!submitOnEnter && postStatus($event, newStatus)"
|
@keydown.ctrl.enter="!submitOnEnter && postStatus($event, newStatus)"
|
||||||
@input="resize"
|
@input="resize"
|
||||||
@compositionupdate="resize"
|
@compositionupdate="resize"
|
||||||
@paste="paste"
|
@paste="paste"
|
||||||
|
@focus="focusStatusInput()"
|
||||||
/>
|
/>
|
||||||
<p
|
<p
|
||||||
v-if="hasStatusLengthLimit"
|
v-if="hasStatusLengthLimit"
|
||||||
|
@ -185,6 +190,7 @@
|
||||||
<div
|
<div
|
||||||
v-if="!disableScopeSelector"
|
v-if="!disableScopeSelector"
|
||||||
class="visibility-tray"
|
class="visibility-tray"
|
||||||
|
:class="{ 'visibility-tray-edit': isEdit }"
|
||||||
>
|
>
|
||||||
<scope-selector
|
<scope-selector
|
||||||
v-if="!disableVisibilitySelector"
|
v-if="!disableVisibilitySelector"
|
||||||
|
@ -195,7 +201,9 @@
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="language-selector"
|
class="format-selector-container">
|
||||||
|
<div
|
||||||
|
class="format-selector"
|
||||||
>
|
>
|
||||||
<Select
|
<Select
|
||||||
id="post-language"
|
id="post-language"
|
||||||
|
@ -203,17 +211,17 @@
|
||||||
class="form-control"
|
class="form-control"
|
||||||
>
|
>
|
||||||
<option
|
<option
|
||||||
v-for="language in isoLanguages"
|
v-for="language in postLanguageOptions"
|
||||||
:key="language"
|
:key="language.key"
|
||||||
:value="language"
|
:value="language.value"
|
||||||
>
|
>
|
||||||
{{ language }}
|
{{ language.label }}
|
||||||
</option>
|
</option>
|
||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="postFormats.length > 1"
|
v-if="postFormats.length > 1"
|
||||||
class="text-format"
|
class="text-format format-selector"
|
||||||
>
|
>
|
||||||
<Select
|
<Select
|
||||||
id="post-content-type"
|
id="post-content-type"
|
||||||
|
@ -231,7 +239,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="postFormats.length === 1 && postFormats[0] !== 'text/plain'"
|
v-if="postFormats.length === 1 && postFormats[0] !== 'text/plain'"
|
||||||
class="text-format"
|
class="text-format format-selector"
|
||||||
>
|
>
|
||||||
<span class="only-format">
|
<span class="only-format">
|
||||||
{{ $t(`post_status.content_type["${postFormats[0]}"]`) }}
|
{{ $t(`post_status.content_type["${postFormats[0]}"]`) }}
|
||||||
|
@ -239,6 +247,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<poll-form
|
<poll-form
|
||||||
v-if="pollsAvailable"
|
v-if="pollsAvailable"
|
||||||
ref="pollForm"
|
ref="pollForm"
|
||||||
|
@ -276,6 +285,15 @@
|
||||||
>
|
>
|
||||||
<FAIcon icon="poll-h" />
|
<FAIcon icon="poll-h" />
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
v-if="!disableSubject"
|
||||||
|
class="spoiler-icon button-unstyled"
|
||||||
|
:class="{ selected: subjectVisible }"
|
||||||
|
:title="$t('post_status.toggle_content_warning')"
|
||||||
|
@click="toggleSubjectVisible"
|
||||||
|
>
|
||||||
|
<FAIcon icon="eye-slash" />
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
v-if="posting"
|
v-if="posting"
|
||||||
|
@ -446,6 +464,10 @@
|
||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.visibility-tray-edit {
|
||||||
|
justify-content: right;
|
||||||
|
}
|
||||||
|
|
||||||
.visibility-notice.edit-warning {
|
.visibility-notice.edit-warning {
|
||||||
> :first-child {
|
> :first-child {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
|
@ -456,7 +478,13 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.media-upload-icon, .poll-icon, .emoji-icon {
|
.format-selector-container {
|
||||||
|
.format-selector {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.media-upload-icon, .poll-icon, .emoji-icon, .spoiler-icon {
|
||||||
font-size: 1.85em;
|
font-size: 1.85em;
|
||||||
line-height: 1.1;
|
line-height: 1.1;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
@ -499,6 +527,11 @@
|
||||||
|
|
||||||
.poll-icon {
|
.poll-icon {
|
||||||
order: 3;
|
order: 3;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spoiler-icon {
|
||||||
|
order: 4;
|
||||||
justify-content: right;
|
justify-content: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -551,6 +584,11 @@
|
||||||
line-height: 1.85;
|
line-height: 1.85;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.form-post-subject {
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.form-post-body {
|
.form-post-body {
|
||||||
// TODO: make a resizable textarea component?
|
// TODO: make a resizable textarea component?
|
||||||
box-sizing: content-box; // needed for easier computation of dynamic size
|
box-sizing: content-box; // needed for easier computation of dynamic size
|
||||||
|
@ -563,6 +601,11 @@
|
||||||
min-height: calc(var(--post-line-height) * 1em);
|
min-height: calc(var(--post-line-height) * 1em);
|
||||||
resize: none;
|
resize: none;
|
||||||
|
|
||||||
|
&.-has-subject {
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
&.scrollable-form {
|
&.scrollable-form {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
v-if="isLoggedIn && !resettingForm"
|
v-if="isLoggedIn && !resettingForm"
|
||||||
:is-open="modalActivated"
|
:is-open="modalActivated"
|
||||||
class="post-form-modal-view"
|
class="post-form-modal-view"
|
||||||
@backdropClicked="closeModal"
|
@backdrop-clicked="closeModal"
|
||||||
>
|
>
|
||||||
<div class="post-form-modal-panel panel">
|
<div class="post-form-modal-panel panel">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
|
|
|
@ -8,13 +8,13 @@
|
||||||
remove-padding
|
remove-padding
|
||||||
@show="focusInput"
|
@show="focusInput"
|
||||||
>
|
>
|
||||||
<template v-slot:content="{close}">
|
<template #content="{close}">
|
||||||
<EmojiPicker
|
<EmojiPicker
|
||||||
:enable-sticker-picker="false"
|
:enable-sticker-picker="false"
|
||||||
@emoji="addReaction($event, close)"
|
@emoji="addReaction($event, close)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:trigger>
|
<template #trigger>
|
||||||
<button
|
<button
|
||||||
class="button-unstyled popover-trigger"
|
class="button-unstyled popover-trigger"
|
||||||
:title="$t('tool_tip.add_reaction')"
|
:title="$t('tool_tip.add_reaction')"
|
||||||
|
|
|
@ -2,7 +2,7 @@ export default {
|
||||||
props: [ 'user' ],
|
props: [ 'user' ],
|
||||||
computed: {
|
computed: {
|
||||||
subscribeUrl () {
|
subscribeUrl () {
|
||||||
// eslint-disable-next-line no-undef
|
|
||||||
const serverUrl = new URL(this.user.statusnet_profile_url)
|
const serverUrl = new URL(this.user.statusnet_profile_url)
|
||||||
return `${serverUrl.protocol}//${serverUrl.host}/main/ostatus`
|
return `${serverUrl.protocol}//${serverUrl.host}/main/ostatus`
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
|
import Popover from '../popover/popover.vue'
|
||||||
import ConfirmModal from '../confirm_modal/confirm_modal.vue'
|
import ConfirmModal from '../confirm_modal/confirm_modal.vue'
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import { faRetweet } from '@fortawesome/free-solid-svg-icons'
|
import { faRetweet, faTrash } from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
||||||
library.add(faRetweet)
|
library.add(faRetweet, faTrash)
|
||||||
|
|
||||||
const RetweetButton = {
|
const RetweetButton = {
|
||||||
props: ['status', 'loggedIn', 'visibility'],
|
props: ['status', 'loggedIn', 'visibility'],
|
||||||
components: {
|
components: {
|
||||||
|
Popover,
|
||||||
ConfirmModal
|
ConfirmModal
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
|
@ -16,16 +18,16 @@ const RetweetButton = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
retweet () {
|
retweet (visibility) {
|
||||||
if (!this.status.repeated && this.shouldConfirmRepeat) {
|
if (!this.status.repeated && this.shouldConfirmRepeat) {
|
||||||
this.showConfirmDialog()
|
this.showConfirmDialog()
|
||||||
} else {
|
} else {
|
||||||
this.doRetweet()
|
this.doRetweet(visibility)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
doRetweet () {
|
doRetweet (visibility) {
|
||||||
if (!this.status.repeated) {
|
if (!this.status.repeated) {
|
||||||
this.$store.dispatch('retweet', { id: this.status.id })
|
this.$store.dispatch('retweet', { id: this.status.id, visibility: visibility })
|
||||||
} else {
|
} else {
|
||||||
this.$store.dispatch('unretweet', { id: this.status.id })
|
this.$store.dispatch('unretweet', { id: this.status.id })
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,76 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="RetweetButton">
|
<!-- TODO settings the offset like this feels like a hack -->
|
||||||
|
<Popover
|
||||||
|
class="RetweetButton"
|
||||||
|
trigger="click"
|
||||||
|
placement="bottom"
|
||||||
|
:offset="{ y: 22 }"
|
||||||
|
:bound-to="{ x: 'container' }"
|
||||||
|
remove-padding
|
||||||
|
>
|
||||||
|
<template v-slot:content="{close}">
|
||||||
|
<div class="dropdown-menu">
|
||||||
|
<template v-if="status.repeated">
|
||||||
|
<button
|
||||||
|
v-if="status.repeated"
|
||||||
|
class="button-default dropdown-item dropdown-item-icon"
|
||||||
|
@click.prevent="retweet()"
|
||||||
|
>
|
||||||
|
<!-- TODO: i18n -->
|
||||||
|
<FAIcon
|
||||||
|
fixed-width
|
||||||
|
icon="trash"
|
||||||
|
/><span>Undo repeat</span>
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<!-- TODO: don't show button that would increase post visibility -->
|
||||||
|
<button
|
||||||
|
class="button-default dropdown-item dropdown-item-icon"
|
||||||
|
@click.prevent="retweet('public')"
|
||||||
|
>
|
||||||
|
<FAIcon
|
||||||
|
fixed-width
|
||||||
|
icon="globe"
|
||||||
|
/><span>{{ $t("general.scope_in_timeline.public") }}</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="button-default dropdown-item dropdown-item-icon"
|
||||||
|
@click.prevent="retweet('unlisted')"
|
||||||
|
>
|
||||||
|
<FAIcon
|
||||||
|
fixed-width
|
||||||
|
icon="lock-open"
|
||||||
|
/><span>{{ $t("general.scope_in_timeline.unlisted") }}</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="button-default dropdown-item dropdown-item-icon"
|
||||||
|
@click.prevent="retweet('private')"
|
||||||
|
>
|
||||||
|
<FAIcon
|
||||||
|
fixed-width
|
||||||
|
icon="lock"
|
||||||
|
/><span>{{ $t("general.scope_in_timeline.private") }}</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="button-default dropdown-item dropdown-item-icon"
|
||||||
|
@click.prevent="retweet('local')"
|
||||||
|
>
|
||||||
|
<!-- TODO: "general.scope_in_timeline.local" feels too long for the popover -->
|
||||||
|
<FAIcon
|
||||||
|
fixed-width
|
||||||
|
icon="users"
|
||||||
|
/><span>Local</span>
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-slot:trigger>
|
||||||
<button
|
<button
|
||||||
v-if="(visibility !== 'private' || isOwn) && visibility !== 'direct' && loggedIn"
|
v-if="(visibility !== 'private' || isOwn) && visibility !== 'direct' && loggedIn"
|
||||||
class="button-unstyled interactive"
|
class="button-unstyled popover-trigger"
|
||||||
:class="status.repeated && '-repeated'"
|
:class="status.repeated && '-repeated'"
|
||||||
:title="$t('tool_tip.repeat')"
|
:title="$t('tool_tip.repeat')"
|
||||||
@click.prevent="retweet()"
|
|
||||||
>
|
>
|
||||||
<FAIcon
|
<FAIcon
|
||||||
class="fa-scale-110 fa-old-padding"
|
class="fa-scale-110 fa-old-padding"
|
||||||
|
@ -40,6 +105,7 @@
|
||||||
{{ status.repeat_num }}
|
{{ status.repeat_num }}
|
||||||
</span>
|
</span>
|
||||||
<teleport to="#modal">
|
<teleport to="#modal">
|
||||||
|
<!-- TODO does this work for all? -->
|
||||||
<confirm-modal
|
<confirm-modal
|
||||||
v-if="showingConfirmDialog"
|
v-if="showingConfirmDialog"
|
||||||
:title="$t('status.repeat_confirm_title')"
|
:title="$t('status.repeat_confirm_title')"
|
||||||
|
@ -51,7 +117,8 @@
|
||||||
{{ $t('status.repeat_confirm') }}
|
{{ $t('status.repeat_confirm') }}
|
||||||
</confirm-modal>
|
</confirm-modal>
|
||||||
</teleport>
|
</teleport>
|
||||||
</div>
|
</template>
|
||||||
|
</Popover>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script src="./retweet_button.js"></script>
|
<script src="./retweet_button.js"></script>
|
||||||
|
@ -72,7 +139,7 @@
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.interactive {
|
.popover-trigger {
|
||||||
.svg-inline--fa {
|
.svg-inline--fa {
|
||||||
@media (prefers-reduced-motion: reduce) {
|
@media (prefers-reduced-motion: reduce) {
|
||||||
animation: unset;
|
animation: unset;
|
||||||
|
@ -80,6 +147,7 @@
|
||||||
animation-duration: 0.6s;
|
animation-duration: 0.6s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: don't turn green on hover because it keeps being focused on mobile when the popover is open. Instead make it while(?) like in extra_buttons and only green once it's been repeated. */
|
||||||
&:hover .svg-inline--fa,
|
&:hover .svg-inline--fa,
|
||||||
&.-repeated .svg-inline--fa {
|
&.-repeated .svg-inline--fa {
|
||||||
color: $fallback--cGreen;
|
color: $fallback--cGreen;
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
:items="items"
|
:items="items"
|
||||||
:get-key="getKey"
|
:get-key="getKey"
|
||||||
>
|
>
|
||||||
<template v-slot:item="{item}">
|
<template #item="{item}">
|
||||||
<div
|
<div
|
||||||
class="selectable-list-item-inner"
|
class="selectable-list-item-inner"
|
||||||
:class="{ 'selectable-list-item-selected-inner': isSelected(item) }"
|
:class="{ 'selectable-list-item-selected-inner': isSelected(item) }"
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:empty>
|
<template #empty>
|
||||||
<slot name="empty" />
|
<slot name="empty" />
|
||||||
</template>
|
</template>
|
||||||
</List>
|
</List>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<Checkbox
|
<Checkbox
|
||||||
:model-value="state"
|
:model-value="state"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
@update:modelValue="update"
|
@update:model-value="update"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
v-if="!!$slots.default"
|
v-if="!!$slots.default"
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<Select
|
<Select
|
||||||
:model-value="state"
|
:model-value="state"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
@update:modelValue="update"
|
@update:model-value="update"
|
||||||
>
|
>
|
||||||
<option
|
<option
|
||||||
v-for="option in options"
|
v-for="option in options"
|
||||||
|
|
|
@ -6,14 +6,14 @@
|
||||||
<Popover
|
<Popover
|
||||||
trigger="hover"
|
trigger="hover"
|
||||||
>
|
>
|
||||||
<template v-slot:trigger>
|
<template #trigger>
|
||||||
|
|
||||||
<FAIcon
|
<FAIcon
|
||||||
icon="wrench"
|
icon="wrench"
|
||||||
:aria-label="$t('settings.setting_changed')"
|
:aria-label="$t('settings.setting_changed')"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:content>
|
<template #content>
|
||||||
<div class="modified-tooltip">
|
<div class="modified-tooltip">
|
||||||
{{ $t('settings.setting_changed') }}
|
{{ $t('settings.setting_changed') }}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -6,14 +6,14 @@
|
||||||
<Popover
|
<Popover
|
||||||
trigger="hover"
|
trigger="hover"
|
||||||
>
|
>
|
||||||
<template v-slot:trigger>
|
<template #trigger>
|
||||||
|
|
||||||
<FAIcon
|
<FAIcon
|
||||||
icon="server"
|
icon="server"
|
||||||
:aria-label="$t('settings.setting_server_side')"
|
:aria-label="$t('settings.setting_server_side')"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:content>
|
<template #content>
|
||||||
<div class="serverside-tooltip">
|
<div class="serverside-tooltip">
|
||||||
{{ $t('settings.setting_server_side') }}
|
{{ $t('settings.setting_server_side') }}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -108,7 +108,7 @@
|
||||||
<Checkbox
|
<Checkbox
|
||||||
:model-value="!!expertLevel"
|
:model-value="!!expertLevel"
|
||||||
class="expertMode"
|
class="expertMode"
|
||||||
@update:modelValue="expertLevel = Number($event)"
|
@update:model-value="expertLevel = Number($event)"
|
||||||
>
|
>
|
||||||
{{ $t("settings.expert_mode") }}
|
{{ $t("settings.expert_mode") }}
|
||||||
</Checkbox>
|
</Checkbox>
|
||||||
|
|
|
@ -72,7 +72,7 @@ const DataImportExportTab = {
|
||||||
// check is it's a local user
|
// check is it's a local user
|
||||||
if (user && user.is_local) {
|
if (user && user.is_local) {
|
||||||
// append the instance address
|
// append the instance address
|
||||||
// eslint-disable-next-line no-undef
|
|
||||||
return user.screen_name + '@' + location.hostname
|
return user.screen_name + '@' + location.hostname
|
||||||
}
|
}
|
||||||
return user.screen_name
|
return user.screen_name
|
||||||
|
|
|
@ -4,6 +4,7 @@ import ScopeSelector from 'src/components/scope_selector/scope_selector.vue'
|
||||||
import IntegerSetting from '../helpers/integer_setting.vue'
|
import IntegerSetting from '../helpers/integer_setting.vue'
|
||||||
import InterfaceLanguageSwitcher from 'src/components/interface_language_switcher/interface_language_switcher.vue'
|
import InterfaceLanguageSwitcher from 'src/components/interface_language_switcher/interface_language_switcher.vue'
|
||||||
|
|
||||||
|
import { usePostLanguageOptions } from 'src/lib/post_language'
|
||||||
import SharedComputedObject from '../helpers/shared_computed_object.js'
|
import SharedComputedObject from '../helpers/shared_computed_object.js'
|
||||||
import ServerSideIndicator from '../helpers/server_side_indicator.vue'
|
import ServerSideIndicator from '../helpers/server_side_indicator.vue'
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
|
@ -17,6 +18,11 @@ library.add(
|
||||||
)
|
)
|
||||||
|
|
||||||
const GeneralTab = {
|
const GeneralTab = {
|
||||||
|
setup() {
|
||||||
|
const {postLanguageOptions} = usePostLanguageOptions()
|
||||||
|
|
||||||
|
return {postLanguageOptions}
|
||||||
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
subjectLineOptions: ['email', 'noop', 'masto'].map(mode => ({
|
subjectLineOptions: ['email', 'noop', 'masto'].map(mode => ({
|
||||||
|
@ -118,6 +124,12 @@ const GeneralTab = {
|
||||||
this.$store.dispatch('setOption', { name: 'translationLanguage', value: val })
|
this.$store.dispatch('setOption', { name: 'translationLanguage', value: val })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
postLanguage: {
|
||||||
|
get: function () { return this.$store.getters.mergedConfig.postLanguage },
|
||||||
|
set: function (val) {
|
||||||
|
this.$store.dispatch('setOption', { name: 'postLanguage', value: val })
|
||||||
|
}
|
||||||
|
},
|
||||||
...SharedComputedObject()
|
...SharedComputedObject()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
@ -44,7 +44,6 @@
|
||||||
<template
|
<template
|
||||||
v-if="profilesExpanded"
|
v-if="profilesExpanded"
|
||||||
>
|
>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-for="profile in settingsProfiles"
|
v-for="profile in settingsProfiles"
|
||||||
:key="profile.id"
|
:key="profile.id"
|
||||||
|
@ -73,15 +72,24 @@
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn button-default" @click="refreshProfiles()">
|
<button
|
||||||
|
class="btn button-default"
|
||||||
|
@click="refreshProfiles()"
|
||||||
|
>
|
||||||
{{ $t('settings.settings_profiles_refresh') }}
|
{{ $t('settings.settings_profiles_refresh') }}
|
||||||
<FAIcon icon="sync" @click="refreshProfiles()" />
|
<FAIcon
|
||||||
|
icon="sync"
|
||||||
|
@click="refreshProfiles()"
|
||||||
|
/>
|
||||||
</button>
|
</button>
|
||||||
<h3>{{ $t('settings.settings_profile_creation') }}</h3>
|
<h3>{{ $t('settings.settings_profile_creation') }}</h3>
|
||||||
<label for="settings-profile-new-name">
|
<label for="settings-profile-new-name">
|
||||||
{{ $t('settings.settings_profile_creation_new_name_label') }}
|
{{ $t('settings.settings_profile_creation_new_name_label') }}
|
||||||
</label>
|
</label>
|
||||||
<input v-model="newProfileName" id="settings-profile-new-name">
|
<input
|
||||||
|
id="settings-profile-new-name"
|
||||||
|
v-model="newProfileName"
|
||||||
|
>
|
||||||
<button
|
<button
|
||||||
class="btn button-default"
|
class="btn button-default"
|
||||||
@click="createSettingsProfile"
|
@click="createSettingsProfile"
|
||||||
|
@ -146,6 +154,11 @@
|
||||||
{{ $t('settings.show_wider_shortcuts') }}
|
{{ $t('settings.show_wider_shortcuts') }}
|
||||||
</BooleanSetting>
|
</BooleanSetting>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<BooleanSetting path="displayPageBackgrounds">
|
||||||
|
{{ $t('settings.show_page_backgrounds') }}
|
||||||
|
</BooleanSetting>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<BooleanSetting path="stopGifs">
|
<BooleanSetting path="stopGifs">
|
||||||
{{ $t('settings.stop_gifs') }}
|
{{ $t('settings.stop_gifs') }}
|
||||||
|
@ -483,14 +496,6 @@
|
||||||
</BooleanSetting>
|
</BooleanSetting>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<li>
|
|
||||||
<BooleanSetting
|
|
||||||
path="useAtIcon"
|
|
||||||
expert="1"
|
|
||||||
>
|
|
||||||
{{ $t('settings.use_at_icon') }}
|
|
||||||
</BooleanSetting>
|
|
||||||
</li>
|
|
||||||
<li>
|
<li>
|
||||||
<BooleanSetting path="mentionLinkShowAvatar">
|
<BooleanSetting path="mentionLinkShowAvatar">
|
||||||
{{ $t('settings.mention_link_show_avatar') }}
|
{{ $t('settings.mention_link_show_avatar') }}
|
||||||
|
@ -588,6 +593,15 @@
|
||||||
{{ $t('settings.post_status_content_type') }}
|
{{ $t('settings.post_status_content_type') }}
|
||||||
</ChoiceSetting>
|
</ChoiceSetting>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<ChoiceSetting
|
||||||
|
id="postLanguage"
|
||||||
|
path="postLanguage"
|
||||||
|
:options="postLanguageOptions"
|
||||||
|
>
|
||||||
|
{{ $t('settings.post_language') }}
|
||||||
|
</ChoiceSetting>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<BooleanSetting
|
<BooleanSetting
|
||||||
path="alwaysShowNewPostButton"
|
path="alwaysShowNewPostButton"
|
||||||
|
|
|
@ -85,7 +85,7 @@ const MutesAndBlocks = {
|
||||||
// check is it's a local user
|
// check is it's a local user
|
||||||
if (user && user.is_local) {
|
if (user && user.is_local) {
|
||||||
// append the instance address
|
// append the instance address
|
||||||
// eslint-disable-next-line no-undef
|
|
||||||
return user.screen_name + '@' + location.hostname
|
return user.screen_name + '@' + location.hostname
|
||||||
}
|
}
|
||||||
return user.screen_name
|
return user.screen_name
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
:query="queryUserIds"
|
:query="queryUserIds"
|
||||||
:placeholder="$t('settings.search_user_to_block')"
|
:placeholder="$t('settings.search_user_to_block')"
|
||||||
>
|
>
|
||||||
<template v-slot="row">
|
<template #default="row">
|
||||||
<BlockCard
|
<BlockCard
|
||||||
:user-id="row.item"
|
:user-id="row.item"
|
||||||
/>
|
/>
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
:refresh="true"
|
:refresh="true"
|
||||||
:get-key="i => i"
|
:get-key="i => i"
|
||||||
>
|
>
|
||||||
<template v-slot:header="{selected}">
|
<template #header="{selected}">
|
||||||
<div class="bulk-actions">
|
<div class="bulk-actions">
|
||||||
<ProgressButton
|
<ProgressButton
|
||||||
v-if="selected.length > 0"
|
v-if="selected.length > 0"
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
:click="() => blockUsers(selected)"
|
:click="() => blockUsers(selected)"
|
||||||
>
|
>
|
||||||
{{ $t('user_card.block') }}
|
{{ $t('user_card.block') }}
|
||||||
<template v-slot:progress>
|
<template #progress>
|
||||||
{{ $t('user_card.block_progress') }}
|
{{ $t('user_card.block_progress') }}
|
||||||
</template>
|
</template>
|
||||||
</ProgressButton>
|
</ProgressButton>
|
||||||
|
@ -39,16 +39,16 @@
|
||||||
:click="() => unblockUsers(selected)"
|
:click="() => unblockUsers(selected)"
|
||||||
>
|
>
|
||||||
{{ $t('user_card.unblock') }}
|
{{ $t('user_card.unblock') }}
|
||||||
<template v-slot:progress>
|
<template #progress>
|
||||||
{{ $t('user_card.unblock_progress') }}
|
{{ $t('user_card.unblock_progress') }}
|
||||||
</template>
|
</template>
|
||||||
</ProgressButton>
|
</ProgressButton>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:item="{item}">
|
<template #item="{item}">
|
||||||
<BlockCard :user-id="item" />
|
<BlockCard :user-id="item" />
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:empty>
|
<template #empty>
|
||||||
{{ $t('settings.no_blocks') }}
|
{{ $t('settings.no_blocks') }}
|
||||||
</template>
|
</template>
|
||||||
</BlockList>
|
</BlockList>
|
||||||
|
@ -63,7 +63,7 @@
|
||||||
:query="queryUserIds"
|
:query="queryUserIds"
|
||||||
:placeholder="$t('settings.search_user_to_mute')"
|
:placeholder="$t('settings.search_user_to_mute')"
|
||||||
>
|
>
|
||||||
<template v-slot="row">
|
<template #default="row">
|
||||||
<MuteCard
|
<MuteCard
|
||||||
:user-id="row.item"
|
:user-id="row.item"
|
||||||
/>
|
/>
|
||||||
|
@ -74,7 +74,7 @@
|
||||||
:refresh="true"
|
:refresh="true"
|
||||||
:get-key="i => i"
|
:get-key="i => i"
|
||||||
>
|
>
|
||||||
<template v-slot:header="{selected}">
|
<template #header="{selected}">
|
||||||
<div class="bulk-actions">
|
<div class="bulk-actions">
|
||||||
<ProgressButton
|
<ProgressButton
|
||||||
v-if="selected.length > 0"
|
v-if="selected.length > 0"
|
||||||
|
@ -82,7 +82,7 @@
|
||||||
:click="() => muteUsers(selected)"
|
:click="() => muteUsers(selected)"
|
||||||
>
|
>
|
||||||
{{ $t('user_card.mute') }}
|
{{ $t('user_card.mute') }}
|
||||||
<template v-slot:progress>
|
<template #progress>
|
||||||
{{ $t('user_card.mute_progress') }}
|
{{ $t('user_card.mute_progress') }}
|
||||||
</template>
|
</template>
|
||||||
</ProgressButton>
|
</ProgressButton>
|
||||||
|
@ -92,16 +92,16 @@
|
||||||
:click="() => unmuteUsers(selected)"
|
:click="() => unmuteUsers(selected)"
|
||||||
>
|
>
|
||||||
{{ $t('user_card.unmute') }}
|
{{ $t('user_card.unmute') }}
|
||||||
<template v-slot:progress>
|
<template #progress>
|
||||||
{{ $t('user_card.unmute_progress') }}
|
{{ $t('user_card.unmute_progress') }}
|
||||||
</template>
|
</template>
|
||||||
</ProgressButton>
|
</ProgressButton>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:item="{item}">
|
<template #item="{item}">
|
||||||
<MuteCard :user-id="item" />
|
<MuteCard :user-id="item" />
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:empty>
|
<template #empty>
|
||||||
{{ $t('settings.no_mutes') }}
|
{{ $t('settings.no_mutes') }}
|
||||||
</template>
|
</template>
|
||||||
</MuteList>
|
</MuteList>
|
||||||
|
@ -114,7 +114,7 @@
|
||||||
:query="queryKnownDomains"
|
:query="queryKnownDomains"
|
||||||
:placeholder="$t('settings.type_domains_to_mute')"
|
:placeholder="$t('settings.type_domains_to_mute')"
|
||||||
>
|
>
|
||||||
<template v-slot="row">
|
<template #default="row">
|
||||||
<DomainMuteCard
|
<DomainMuteCard
|
||||||
:domain="row.item"
|
:domain="row.item"
|
||||||
/>
|
/>
|
||||||
|
@ -125,7 +125,7 @@
|
||||||
:refresh="true"
|
:refresh="true"
|
||||||
:get-key="i => i"
|
:get-key="i => i"
|
||||||
>
|
>
|
||||||
<template v-slot:header="{selected}">
|
<template #header="{selected}">
|
||||||
<div class="bulk-actions">
|
<div class="bulk-actions">
|
||||||
<ProgressButton
|
<ProgressButton
|
||||||
v-if="selected.length > 0"
|
v-if="selected.length > 0"
|
||||||
|
@ -133,16 +133,16 @@
|
||||||
:click="() => unmuteDomains(selected)"
|
:click="() => unmuteDomains(selected)"
|
||||||
>
|
>
|
||||||
{{ $t('domain_mute_card.unmute') }}
|
{{ $t('domain_mute_card.unmute') }}
|
||||||
<template v-slot:progress>
|
<template #progress>
|
||||||
{{ $t('domain_mute_card.unmute_progress') }}
|
{{ $t('domain_mute_card.unmute_progress') }}
|
||||||
</template>
|
</template>
|
||||||
</ProgressButton>
|
</ProgressButton>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:item="{item}">
|
<template #item="{item}">
|
||||||
<DomainMuteCard :domain="item" />
|
<DomainMuteCard :domain="item" />
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:empty>
|
<template #empty>
|
||||||
{{ $t('settings.no_mutes') }}
|
{{ $t('settings.no_mutes') }}
|
||||||
</template>
|
</template>
|
||||||
</DomainMuteList>
|
</DomainMuteList>
|
||||||
|
|
|
@ -33,6 +33,7 @@ const ProfileTab = {
|
||||||
newName: this.$store.state.users.currentUser.name_unescaped,
|
newName: this.$store.state.users.currentUser.name_unescaped,
|
||||||
newBio: unescape(this.$store.state.users.currentUser.description),
|
newBio: unescape(this.$store.state.users.currentUser.description),
|
||||||
newLocked: this.$store.state.users.currentUser.locked,
|
newLocked: this.$store.state.users.currentUser.locked,
|
||||||
|
newPermitFollowback: this.$store.state.users.currentUser.permit_followback,
|
||||||
newFields: this.$store.state.users.currentUser.fields.map(field => ({ name: field.name, value: field.value })),
|
newFields: this.$store.state.users.currentUser.fields.map(field => ({ name: field.name, value: field.value })),
|
||||||
showRole: this.$store.state.users.currentUser.show_role,
|
showRole: this.$store.state.users.currentUser.show_role,
|
||||||
role: this.$store.state.users.currentUser.role,
|
role: this.$store.state.users.currentUser.role,
|
||||||
|
@ -129,14 +130,15 @@ const ProfileTab = {
|
||||||
note: this.newBio,
|
note: this.newBio,
|
||||||
locked: this.newLocked,
|
locked: this.newLocked,
|
||||||
// Backend notation.
|
// Backend notation.
|
||||||
/* eslint-disable camelcase */
|
|
||||||
display_name: this.newName,
|
display_name: this.newName,
|
||||||
fields_attributes: this.newFields.filter(el => el != null),
|
fields_attributes: this.newFields.filter(el => el != null),
|
||||||
bot: this.bot,
|
bot: this.bot,
|
||||||
show_role: this.showRole,
|
show_role: this.showRole,
|
||||||
status_ttl_days: this.expirePosts ? this.newPostTTLDays : -1,
|
status_ttl_days: this.expirePosts ? this.newPostTTLDays : -1,
|
||||||
|
permit_followback: this.permit_followback,
|
||||||
accepts_direct_messages_from: this.userAcceptsDirectMessagesFrom
|
accepts_direct_messages_from: this.userAcceptsDirectMessagesFrom
|
||||||
/* eslint-enable camelcase */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.emailLanguage) {
|
if (this.emailLanguage) {
|
||||||
|
@ -185,7 +187,7 @@ const ProfileTab = {
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line no-undef
|
|
||||||
const reader = new FileReader()
|
const reader = new FileReader()
|
||||||
reader.onload = ({ target }) => {
|
reader.onload = ({ target }) => {
|
||||||
const img = target.result
|
const img = target.result
|
||||||
|
|
|
@ -110,11 +110,9 @@
|
||||||
max="730"
|
max="730"
|
||||||
class="expire-posts-days"
|
class="expire-posts-days"
|
||||||
:placeholder="$t('settings.expire_posts_input_placeholder')"
|
:placeholder="$t('settings.expire_posts_input_placeholder')"
|
||||||
/>
|
>
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
|
<p />
|
||||||
<p>
|
<p>
|
||||||
<interface-language-switcher
|
<interface-language-switcher
|
||||||
:prompt-text="$t('settings.email_language')"
|
:prompt-text="$t('settings.email_language')"
|
||||||
|
@ -259,6 +257,19 @@
|
||||||
<BooleanSetting path="serverSide_locked">
|
<BooleanSetting path="serverSide_locked">
|
||||||
{{ $t('settings.lock_account_description') }}
|
{{ $t('settings.lock_account_description') }}
|
||||||
</BooleanSetting>
|
</BooleanSetting>
|
||||||
|
<ul
|
||||||
|
class="setting-list suboptions"
|
||||||
|
:class="[{disabled: !serverSide_locked}]"
|
||||||
|
>
|
||||||
|
<li>
|
||||||
|
<BooleanSetting
|
||||||
|
path="serverSide_permitFollowback"
|
||||||
|
:disabled="!serverSide_locked"
|
||||||
|
>
|
||||||
|
{{ $t('settings.permit_followback_description') }}
|
||||||
|
</BooleanSetting>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<BooleanSetting path="serverSide_discoverable">
|
<BooleanSetting path="serverSide_discoverable">
|
||||||
|
|
|
@ -215,6 +215,7 @@ const Status = {
|
||||||
retweeter () { return this.statusoid.user.name || this.statusoid.user.screen_name_ui },
|
retweeter () { return this.statusoid.user.name || this.statusoid.user.screen_name_ui },
|
||||||
retweeterHtml () { return this.statusoid.user.name },
|
retweeterHtml () { return this.statusoid.user.name },
|
||||||
retweeterProfileLink () { return this.generateUserProfileLink(this.statusoid.user.id, this.statusoid.user.screen_name) },
|
retweeterProfileLink () { return this.generateUserProfileLink(this.statusoid.user.id, this.statusoid.user.screen_name) },
|
||||||
|
retweeterVisibility () { return this.statusoid.visibility },
|
||||||
status () {
|
status () {
|
||||||
if (this.retweet) {
|
if (this.retweet) {
|
||||||
return this.statusoid.retweeted_status
|
return this.statusoid.retweeted_status
|
||||||
|
@ -440,6 +441,9 @@ const Status = {
|
||||||
visibilityLocalized () {
|
visibilityLocalized () {
|
||||||
return this.$i18n.t('general.scope_in_timeline.' + this.status.visibility)
|
return this.$i18n.t('general.scope_in_timeline.' + this.status.visibility)
|
||||||
},
|
},
|
||||||
|
retweeterVisibilityLocalized () {
|
||||||
|
return this.$i18n.t('general.scope_in_timeline.' + this.statusoid.visibility)
|
||||||
|
},
|
||||||
isEdited () {
|
isEdited () {
|
||||||
return this.status.edited_at !== null
|
return this.status.edited_at !== null
|
||||||
},
|
},
|
||||||
|
|
|
@ -42,10 +42,6 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: var(--status-margin, $status-margin);
|
padding: var(--status-margin, $status-margin);
|
||||||
|
|
||||||
.content {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
> * {
|
> * {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
@ -266,6 +262,16 @@
|
||||||
color: $fallback--cGreen;
|
color: $fallback--cGreen;
|
||||||
color: var(--cGreen, $fallback--cGreen);
|
color: var(--cGreen, $fallback--cGreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.right-side {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.repeat-tooltip {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.repeater-avatar {
|
.repeater-avatar {
|
||||||
|
|
|
@ -83,7 +83,7 @@
|
||||||
:user="statusoid.user"
|
:user="statusoid.user"
|
||||||
/>
|
/>
|
||||||
<div class="right-side faint">
|
<div class="right-side faint">
|
||||||
<span
|
<div
|
||||||
class="status-username repeater-name"
|
class="status-username repeater-name"
|
||||||
:title="retweeter"
|
:title="retweeter"
|
||||||
>
|
>
|
||||||
|
@ -100,8 +100,12 @@
|
||||||
v-else
|
v-else
|
||||||
:to="retweeterProfileLink"
|
:to="retweeterProfileLink"
|
||||||
>{{ retweeter }}</router-link>
|
>{{ retweeter }}</router-link>
|
||||||
</span>
|
</div>
|
||||||
{{ ' ' }}
|
{{ ' ' }}
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="repeat-tooltip"
|
||||||
|
>
|
||||||
<FAIcon
|
<FAIcon
|
||||||
icon="retweet"
|
icon="retweet"
|
||||||
class="repeat-icon"
|
class="repeat-icon"
|
||||||
|
@ -109,6 +113,19 @@
|
||||||
/>
|
/>
|
||||||
{{ $t('timeline.repeated') }}
|
{{ $t('timeline.repeated') }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<span
|
||||||
|
v-if="retweeterVisibility"
|
||||||
|
class="visibility-icon"
|
||||||
|
:title="retweeterVisibilityLocalized"
|
||||||
|
>
|
||||||
|
<FAIcon
|
||||||
|
fixed-width
|
||||||
|
class="fa-scale-110"
|
||||||
|
:icon="visibilityIcon(retweeterVisibility)"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
@ -190,7 +207,7 @@
|
||||||
>
|
>
|
||||||
<Timeago
|
<Timeago
|
||||||
:time="status.created_at"
|
:time="status.created_at"
|
||||||
:with-direction="true"
|
:with-direction="!compact"
|
||||||
:auto-update="60"
|
:auto-update="60"
|
||||||
/>
|
/>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
@ -368,7 +385,7 @@
|
||||||
:controlled-toggle-showing-long-subject="controlledToggleShowingLongSubject"
|
:controlled-toggle-showing-long-subject="controlledToggleShowingLongSubject"
|
||||||
@mediaplay="addMediaPlaying($event)"
|
@mediaplay="addMediaPlaying($event)"
|
||||||
@mediapause="removeMediaPlaying($event)"
|
@mediapause="removeMediaPlaying($event)"
|
||||||
@parseReady="setHeadTailLinks"
|
@parse-ready="setHeadTailLinks"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -476,8 +493,8 @@
|
||||||
/>
|
/>
|
||||||
<extra-buttons
|
<extra-buttons
|
||||||
:status="status"
|
:status="status"
|
||||||
@onError="showError"
|
@on-error="showError"
|
||||||
@onSuccess="clearError"
|
@on-success="clearError"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
:mfm="renderMisskeyMarkdown && (status.media_type === 'text/x.misskeymarkdown')"
|
:mfm="renderMisskeyMarkdown && (status.media_type === 'text/x.misskeymarkdown')"
|
||||||
:greentext="mergedConfig.greentext"
|
:greentext="mergedConfig.greentext"
|
||||||
:attentions="status.attentions"
|
:attentions="status.attentions"
|
||||||
@parseReady="onParseReady"
|
@parse-ready="onParseReady"
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
v-if="status.translation"
|
v-if="status.translation"
|
||||||
|
@ -70,7 +70,7 @@
|
||||||
:mfm="renderMisskeyMarkdown && (status.media_type === 'text/x.misskeymarkdown')"
|
:mfm="renderMisskeyMarkdown && (status.media_type === 'text/x.misskeymarkdown')"
|
||||||
:greentext="mergedConfig.greentext"
|
:greentext="mergedConfig.greentext"
|
||||||
:attentions="status.attentions"
|
:attentions="status.attentions"
|
||||||
@parseReady="onParseReady"
|
@parse-ready="onParseReady"
|
||||||
/>
|
/>
|
||||||
<div>
|
<div>
|
||||||
<label class="label">{{ $t('status.override_translation_source_language') }}</label>
|
<label class="label">{{ $t('status.override_translation_source_language') }}</label>
|
||||||
|
@ -89,7 +89,10 @@
|
||||||
</option>
|
</option>
|
||||||
</Select>
|
</Select>
|
||||||
{{ ' ' }}
|
{{ ' ' }}
|
||||||
<button @click="translateStatus" class="btn button-default">
|
<button
|
||||||
|
class="btn button-default"
|
||||||
|
@click="translateStatus"
|
||||||
|
>
|
||||||
{{ $t('status.translate') }}
|
{{ $t('status.translate') }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
:toggle-showing-tall="toggleShowingTall"
|
:toggle-showing-tall="toggleShowingTall"
|
||||||
:toggle-expanding-subject="toggleExpandingSubject"
|
:toggle-expanding-subject="toggleExpandingSubject"
|
||||||
:toggle-showing-long-subject="toggleShowingLongSubject"
|
:toggle-showing-long-subject="toggleShowingLongSubject"
|
||||||
@parseReady="$emit('parseReady', $event)"
|
@parse-ready="$emit('parseReady', $event)"
|
||||||
>
|
>
|
||||||
<div v-if="status.poll && status.poll.options && !compact">
|
<div v-if="status.poll && status.poll.options && !compact">
|
||||||
<Poll
|
<Poll
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<Modal
|
<Modal
|
||||||
v-if="modalActivated"
|
v-if="modalActivated"
|
||||||
class="status-history-modal-view"
|
class="status-history-modal-view"
|
||||||
@backdropClicked="closeModal"
|
@backdrop-clicked="closeModal"
|
||||||
>
|
>
|
||||||
<div class="status-history-modal-panel panel">
|
<div class="status-history-modal-panel panel">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
v-for="status in history"
|
v-for="status in history"
|
||||||
:key="status.id"
|
:key="status.id"
|
||||||
:statusoid="status"
|
:statusoid="status"
|
||||||
:isPreview="true"
|
:is-preview="true"
|
||||||
class="conversation-status status-fadein panel-body"
|
class="conversation-status status-fadein panel-body"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,10 +5,10 @@
|
||||||
:bound-to="{ x: 'container' }"
|
:bound-to="{ x: 'container' }"
|
||||||
@show="enter"
|
@show="enter"
|
||||||
>
|
>
|
||||||
<template v-slot:trigger>
|
<template #trigger>
|
||||||
<slot />
|
<slot />
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:content>
|
<template #content>
|
||||||
<Status
|
<Status
|
||||||
v-if="status"
|
v-if="status"
|
||||||
:is-preview="true"
|
:is-preview="true"
|
||||||
|
|
|
@ -13,6 +13,7 @@ const StillImage = {
|
||||||
return {
|
return {
|
||||||
stopGifs: this.$store.getters.mergedConfig.stopGifs || window.matchMedia('(prefers-reduced-motion: reduce)').matches,
|
stopGifs: this.$store.getters.mergedConfig.stopGifs || window.matchMedia('(prefers-reduced-motion: reduce)').matches,
|
||||||
isAnimated: false,
|
isAnimated: false,
|
||||||
|
imageTypeLabel: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -39,27 +40,24 @@ const StillImage = {
|
||||||
this.imageLoadError && this.imageLoadError()
|
this.imageLoadError && this.imageLoadError()
|
||||||
},
|
},
|
||||||
detectAnimation (image) {
|
detectAnimation (image) {
|
||||||
// If there are no file extensions, the mimetype isn't set, and no mediaproxy is available, we can't figure out
|
|
||||||
// the mimetype of the image.
|
|
||||||
const hasFileExtension = this.src.split('/').pop().includes('.') // TODO: Better check?
|
|
||||||
const mediaProxyAvailable = this.$store.state.instance.mediaProxyAvailable
|
const mediaProxyAvailable = this.$store.state.instance.mediaProxyAvailable
|
||||||
if (!hasFileExtension && this.mimetype === undefined && !mediaProxyAvailable) {
|
|
||||||
|
if (!mediaProxyAvailable) {
|
||||||
// It's a bit aggressive to assume all images we can't find the mimetype of is animated, but necessary for
|
// It's a bit aggressive to assume all images we can't find the mimetype of is animated, but necessary for
|
||||||
// people in need of reduced motion accessibility. As such, we'll consider those images animated if the user
|
// people in need of reduced motion accessibility. As such, we'll consider those images animated if the user
|
||||||
// agent is set to prefer reduced motion. Otherwise, it'll just be used as an early exit.
|
// agent is set to prefer reduced motion. Otherwise, it'll just be used as an early exit.
|
||||||
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches)
|
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
|
||||||
|
// Since the canvas and images are not pixel-perfect matching (due to scaling),
|
||||||
|
// It makes the images jiggle on hover, which is not ideal for accessibility, methinks
|
||||||
this.isAnimated = true
|
this.isAnimated = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
this.detectWithoutMediaProxy(image)
|
||||||
if (this.mimetype === 'image/gif' || this.src.endsWith('.gif')) {
|
} else {
|
||||||
this.isAnimated = true
|
this.detectWithMediaProxy(image)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
// harmless CORS errors without-- clean console with
|
},
|
||||||
if (!mediaProxyAvailable) return
|
detectAnimationWithFetch (image) {
|
||||||
// Animated JPEGs?
|
|
||||||
if (!(this.src.endsWith('.webp') || this.src.endsWith('.png'))) return
|
|
||||||
// Browser Cache should ensure image doesn't get loaded twice if cache exists
|
// Browser Cache should ensure image doesn't get loaded twice if cache exists
|
||||||
fetch(image.src, {
|
fetch(image.src, {
|
||||||
referrerPolicy: 'same-origin'
|
referrerPolicy: 'same-origin'
|
||||||
|
@ -68,12 +66,20 @@ const StillImage = {
|
||||||
// We don't need to read the whole file so only call it once
|
// We don't need to read the whole file so only call it once
|
||||||
data.body.getReader().read()
|
data.body.getReader().read()
|
||||||
.then(reader => {
|
.then(reader => {
|
||||||
if (this.src.endsWith('.webp') && this.isAnimatedWEBP(reader.value)) {
|
// Ordered from least to most intensive
|
||||||
|
if (this.isGIF(reader.value)) {
|
||||||
this.isAnimated = true
|
this.isAnimated = true
|
||||||
|
this.setLabel('GIF')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (this.src.endsWith('.png') && this.isAnimatedPNG(reader.value)) {
|
if (this.isAnimatedWEBP(reader.value)) {
|
||||||
this.isAnimated = true
|
this.isAnimated = true
|
||||||
|
this.setLabel('WEBP')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.isAnimatedPNG(reader.value)) {
|
||||||
|
this.isAnimated = true
|
||||||
|
this.setLabel('APNG')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -81,6 +87,53 @@ const StillImage = {
|
||||||
// this.imageLoadError && this.imageLoadError()
|
// this.imageLoadError && this.imageLoadError()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
detectWithMediaProxy (image) {
|
||||||
|
this.detectAnimationWithFetch(image)
|
||||||
|
},
|
||||||
|
detectWithoutMediaProxy (image) {
|
||||||
|
// We'll just assume that gifs and webp are animated
|
||||||
|
const extension = image.src.split('.').pop().toLowerCase()
|
||||||
|
|
||||||
|
if (extension === 'gif') {
|
||||||
|
this.isAnimated = true
|
||||||
|
this.setLabel('GIF')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (extension === 'webp') {
|
||||||
|
this.isAnimated = true
|
||||||
|
this.setLabel('WEBP')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Beware the apng! use this if ye dare
|
||||||
|
// if (extension === 'png') {
|
||||||
|
// this.isAnimated = true
|
||||||
|
// this.setLabel('PNG')
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Hail mary for extensionless
|
||||||
|
if (extension.includes('/')) {
|
||||||
|
// Don't mind the CORS error barrage
|
||||||
|
this.detectAnimationWithFetch(image)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setLabel (name) {
|
||||||
|
this.imageTypeLabel = name;
|
||||||
|
},
|
||||||
|
isGIF (data) {
|
||||||
|
// I am a perfectly sane individual
|
||||||
|
//
|
||||||
|
// GIF HEADER CHUNK
|
||||||
|
// === START HEADER ===
|
||||||
|
// 47 49 46 38 ("GIF8")
|
||||||
|
const gifHeader = [0x47, 0x49, 0x46];
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
if (data[i] !== gifHeader[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
},
|
||||||
isAnimatedWEBP (data) {
|
isAnimatedWEBP (data) {
|
||||||
/**
|
/**
|
||||||
* WEBP HEADER CHUNK
|
* WEBP HEADER CHUNK
|
||||||
|
@ -115,14 +168,53 @@ const StillImage = {
|
||||||
return (str.substring(0, idatPos > 0 ? idatPos : 0).indexOf('acTL') > 0)
|
return (str.substring(0, idatPos > 0 ? idatPos : 0).indexOf('acTL') > 0)
|
||||||
},
|
},
|
||||||
drawThumbnail() {
|
drawThumbnail() {
|
||||||
const canvas = this.$refs.canvas
|
const canvas = this.$refs.canvas;
|
||||||
if (!this.$refs.canvas) return
|
if (!canvas) return;
|
||||||
const image = this.$refs.src
|
|
||||||
const width = image.naturalWidth
|
const context = canvas.getContext('2d');
|
||||||
const height = image.naturalHeight
|
const image = this.$refs.src;
|
||||||
canvas.width = width
|
const parentElement = canvas.parentElement;
|
||||||
canvas.height = height
|
|
||||||
canvas.getContext('2d').drawImage(image, 0, 0, width, height)
|
// Draw the quick, unscaled version first
|
||||||
|
context.drawImage(image, 0, 0, parentElement.clientWidth, parentElement.clientHeight);
|
||||||
|
|
||||||
|
// Use requestAnimationFrame to schedule the scaling to the next frame
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
// Compute scaling ratio between the natural dimensions of the image and its display dimensions
|
||||||
|
const scalingRatioWidth = parentElement.clientWidth / image.naturalWidth;
|
||||||
|
const scalingRatioHeight = parentElement.clientHeight / image.naturalHeight;
|
||||||
|
|
||||||
|
// Adjust for high-DPI displays
|
||||||
|
const ratio = window.devicePixelRatio || 1;
|
||||||
|
canvas.width = image.naturalWidth * scalingRatioWidth * ratio;
|
||||||
|
canvas.height = image.naturalHeight * scalingRatioHeight * ratio;
|
||||||
|
canvas.style.width = `${parentElement.clientWidth}px`;
|
||||||
|
canvas.style.height = `${parentElement.clientHeight}px`;
|
||||||
|
context.scale(ratio, ratio);
|
||||||
|
|
||||||
|
// Maintain the aspect ratio of the image
|
||||||
|
const imgAspectRatio = image.naturalWidth / image.naturalHeight;
|
||||||
|
const canvasAspectRatio = parentElement.clientWidth / parentElement.clientHeight;
|
||||||
|
|
||||||
|
let drawWidth, drawHeight;
|
||||||
|
|
||||||
|
if (imgAspectRatio > canvasAspectRatio) {
|
||||||
|
drawWidth = parentElement.clientWidth;
|
||||||
|
drawHeight = parentElement.clientWidth / imgAspectRatio;
|
||||||
|
} else {
|
||||||
|
drawHeight = parentElement.clientHeight;
|
||||||
|
drawWidth = parentElement.clientHeight * imgAspectRatio;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.clearRect(0, 0, canvas.width, canvas.height); // Clear the previous unscaled image
|
||||||
|
context.imageSmoothingEnabled = true;
|
||||||
|
context.imageSmoothingQuality = 'high';
|
||||||
|
|
||||||
|
// Draw the good one for realsies
|
||||||
|
const dx = (parentElement.clientWidth - drawWidth) / 2;
|
||||||
|
const dy = (parentElement.clientHeight - drawHeight) / 2;
|
||||||
|
context.drawImage(image, dx, dy, drawWidth, drawHeight);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
updated () {
|
updated () {
|
||||||
|
|
|
@ -1,9 +1,16 @@
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
|
ref="still-image"
|
||||||
class="still-image"
|
class="still-image"
|
||||||
:class="{ animated: animated }"
|
:class="{ animated: animated }"
|
||||||
:style="style"
|
:style="style"
|
||||||
>
|
>
|
||||||
|
<div
|
||||||
|
v-if="animated && imageTypeLabel"
|
||||||
|
class="image-type-label"
|
||||||
|
>
|
||||||
|
{{ imageTypeLabel }}
|
||||||
|
</div>
|
||||||
<canvas
|
<canvas
|
||||||
v-if="animated"
|
v-if="animated"
|
||||||
ref="canvas"
|
ref="canvas"
|
||||||
|
@ -57,30 +64,26 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.animated {
|
.image-type-label {
|
||||||
&::before {
|
|
||||||
zoom: var(--_still_image-label-scale, 1);
|
|
||||||
content: 'gif';
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
top: 0.25em;
|
||||||
|
left: 0.25em;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
font-size: 0.7em;
|
font-size: 0.6em;
|
||||||
top: 0.5em;
|
|
||||||
left: 0.5em;
|
|
||||||
background: rgba(127, 127, 127, 0.5);
|
background: rgba(127, 127, 127, 0.5);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
display: block;
|
|
||||||
padding: 2px 4px;
|
padding: 2px 4px;
|
||||||
border-radius: $fallback--tooltipRadius;
|
|
||||||
border-radius: var(--tooltipRadius, $fallback--tooltipRadius);
|
border-radius: var(--tooltipRadius, $fallback--tooltipRadius);
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
visibility: var(--_still-image-label-visibility, visible);
|
visibility: var(--_still-image-label-visibility, visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.animated {
|
||||||
&:hover canvas {
|
&:hover canvas {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover::before {
|
&:hover .image-type-label {
|
||||||
visibility: var(--_still-image-label-visibility, hidden);
|
visibility: var(--_still-image-label-visibility, hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
:dive="dive ? () => dive(status.id) : undefined"
|
:dive="dive ? () => dive(status.id) : undefined"
|
||||||
|
|
||||||
@goto="setHighlight"
|
@goto="setHighlight"
|
||||||
@toggleExpanded="toggleExpanded"
|
@toggle-expanded="toggleExpanded"
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
v-if="currentReplies.length && threadShowing"
|
v-if="currentReplies.length && threadShowing"
|
||||||
|
|
|
@ -28,4 +28,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.timeline {
|
||||||
|
min-height: 1em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
class="TimelineQuickSettings"
|
class="TimelineQuickSettings"
|
||||||
:bound-to="{ x: 'container' }"
|
:bound-to="{ x: 'container' }"
|
||||||
>
|
>
|
||||||
<template v-slot:content>
|
<template #content>
|
||||||
<div class="dropdown-menu">
|
<div class="dropdown-menu">
|
||||||
<div v-if="loggedIn">
|
<div v-if="loggedIn">
|
||||||
<button
|
<button
|
||||||
|
@ -80,7 +80,7 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:trigger>
|
<template #trigger>
|
||||||
<button class="button-unstyled">
|
<button class="button-unstyled">
|
||||||
<FAIcon icon="filter" />
|
<FAIcon icon="filter" />
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -9,12 +9,12 @@
|
||||||
@show="openMenu"
|
@show="openMenu"
|
||||||
@close="() => isOpen = false"
|
@close="() => isOpen = false"
|
||||||
>
|
>
|
||||||
<template v-slot:content>
|
<template #content>
|
||||||
<div class="timeline-menu-popover popover-default">
|
<div class="timeline-menu-popover popover-default">
|
||||||
<TimelineMenuContent />
|
<TimelineMenuContent />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:trigger>
|
<template #trigger>
|
||||||
<button class="button-unstyled title timeline-menu-title">
|
<button class="button-unstyled title timeline-menu-title">
|
||||||
<span class="timeline-title">{{ timelineName() }}</span>
|
<span class="timeline-title">{{ timelineName() }}</span>
|
||||||
<span>
|
<span>
|
||||||
|
|
|
@ -62,7 +62,6 @@
|
||||||
:title="$t('nav.twkn_timeline_description')"
|
:title="$t('nav.twkn_timeline_description')"
|
||||||
:aria-label="$t('nav.twkn_timeline_description')"
|
:aria-label="$t('nav.twkn_timeline_description')"
|
||||||
>{{ $t("nav.twkn") }}</span>
|
>{{ $t("nav.twkn") }}</span>
|
||||||
|
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="currentUser">
|
<li v-if="currentUser">
|
||||||
|
|
|
@ -16,9 +16,9 @@
|
||||||
/>
|
/>
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link
|
<router-link
|
||||||
|
v-if="publicTimelineVisible"
|
||||||
:to="{ name: 'public-timeline' }"
|
:to="{ name: 'public-timeline' }"
|
||||||
class="nav-icon"
|
class="nav-icon"
|
||||||
v-if="publicTimelineVisible"
|
|
||||||
>
|
>
|
||||||
<FAIcon
|
<FAIcon
|
||||||
fixed-width
|
fixed-width
|
||||||
|
@ -40,9 +40,9 @@
|
||||||
/>
|
/>
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link
|
<router-link
|
||||||
|
v-if="federatedTimelineVisible"
|
||||||
:to="{ name: 'public-external-timeline' }"
|
:to="{ name: 'public-external-timeline' }"
|
||||||
class="nav-icon"
|
class="nav-icon"
|
||||||
v-if="federatedTimelineVisible"
|
|
||||||
>
|
>
|
||||||
<FAIcon
|
<FAIcon
|
||||||
fixed-width
|
fixed-width
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
--_avatarShadowBox: var(--avatarStatusShadow);
|
--_avatarShadowBox: var(--avatarStatusShadow);
|
||||||
--_avatarShadowFilter: var(--avatarStatusShadowFilter);
|
--_avatarShadowFilter: var(--avatarStatusShadowFilter);
|
||||||
--_avatarShadowInset: var(--avatarStatusShadowInset);
|
--_avatarShadowInset: var(--avatarStatusShadowInset);
|
||||||
--_still-image-label-visibility: hidden;
|
// --_still-image-label-visibility: hidden;
|
||||||
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
|
@ -66,7 +66,7 @@ export default {
|
||||||
return this.user.id !== this.$store.state.users.currentUser.id
|
return this.user.id !== this.$store.state.users.currentUser.id
|
||||||
},
|
},
|
||||||
subscribeUrl () {
|
subscribeUrl () {
|
||||||
// eslint-disable-next-line no-undef
|
|
||||||
const serverUrl = new URL(this.user.statusnet_profile_url)
|
const serverUrl = new URL(this.user.statusnet_profile_url)
|
||||||
return `${serverUrl.protocol}//${serverUrl.host}/main/ostatus`
|
return `${serverUrl.protocol}//${serverUrl.host}/main/ostatus`
|
||||||
},
|
},
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
-webkit-mask-composite: xor;
|
-webkit-mask-composite: xor;
|
||||||
mask-composite: exclude;
|
mask-composite: exclude;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
|
background-position: top;
|
||||||
mask-size: 100% 60%;
|
mask-size: 100% 60%;
|
||||||
border-top-left-radius: calc(var(--panelRadius) - 1px);
|
border-top-left-radius: calc(var(--panelRadius) - 1px);
|
||||||
border-top-right-radius: calc(var(--panelRadius) - 1px);
|
border-top-right-radius: calc(var(--panelRadius) - 1px);
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
placement="top"
|
placement="top"
|
||||||
:offset="{ y: 5 }"
|
:offset="{ y: 5 }"
|
||||||
>
|
>
|
||||||
<template v-slot:trigger>
|
<template #trigger>
|
||||||
<slot />
|
<slot />
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:content>
|
<template #content>
|
||||||
<div class="user-list-popover">
|
<div class="user-list-popover">
|
||||||
<template v-if="users.length">
|
<template v-if="users.length">
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -145,10 +145,12 @@ const UserProfile = {
|
||||||
if (user) {
|
if (user) {
|
||||||
loadById(user.id)
|
loadById(user.id)
|
||||||
this.note = user.relationship.note
|
this.note = user.relationship.note
|
||||||
|
this.$store.dispatch('setDisplayBackground', user.background_image)
|
||||||
} else {
|
} else {
|
||||||
this.$store.dispatch('fetchUser', userNameOrId)
|
this.$store.dispatch('fetchUser', userNameOrId)
|
||||||
.then(({ id, relationship }) => {
|
.then(({ id, relationship, background_image }) => {
|
||||||
this.note = relationship.note
|
this.note = relationship.note
|
||||||
|
this.$store.dispatch('setDisplayBackground', background_image)
|
||||||
return loadById(id)
|
return loadById(id)
|
||||||
})
|
})
|
||||||
.catch((reason) => {
|
.catch((reason) => {
|
||||||
|
@ -225,6 +227,9 @@ const UserProfile = {
|
||||||
Conversation,
|
Conversation,
|
||||||
RichContent,
|
RichContent,
|
||||||
FollowedTagList
|
FollowedTagList
|
||||||
|
},
|
||||||
|
beforeRouteLeave(to, from) {
|
||||||
|
this.$store.dispatch('setDisplayBackground', null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,8 +121,8 @@
|
||||||
</FriendList>
|
</FriendList>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
key="tags"
|
|
||||||
v-if="isUs"
|
v-if="isUs"
|
||||||
|
key="tags"
|
||||||
:label="$t('user_card.followed_tags')"
|
:label="$t('user_card.followed_tags')"
|
||||||
>
|
>
|
||||||
<FollowedTagList
|
<FollowedTagList
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<Modal
|
<Modal
|
||||||
v-if="isOpen"
|
v-if="isOpen"
|
||||||
@backdropClicked="closeModal"
|
@backdrop-clicked="closeModal"
|
||||||
>
|
>
|
||||||
<div class="user-reporting-panel panel">
|
<div class="user-reporting-panel panel">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="user-reporting-panel-right">
|
<div class="user-reporting-panel-right">
|
||||||
<List :items="statuses">
|
<List :items="statuses">
|
||||||
<template v-slot:item="{item}">
|
<template #item="{item}">
|
||||||
<div class="status-fadein user-reporting-panel-sitem">
|
<div class="status-fadein user-reporting-panel-sitem">
|
||||||
<Status
|
<Status
|
||||||
:in-conversation="false"
|
:in-conversation="false"
|
||||||
|
|
|
@ -84,6 +84,7 @@
|
||||||
"keep_open": "Mantindre el selector obert",
|
"keep_open": "Mantindre el selector obert",
|
||||||
"load_all": "Carregant tots els {emojiAmount} emoji",
|
"load_all": "Carregant tots els {emojiAmount} emoji",
|
||||||
"load_all_hint": "Carregat el primer {saneAmount} emoji, carregar tots els emoji pot causar problemes de rendiment.",
|
"load_all_hint": "Carregat el primer {saneAmount} emoji, carregar tots els emoji pot causar problemes de rendiment.",
|
||||||
|
"recent": "Recents",
|
||||||
"search_emoji": "Buscar un emoji",
|
"search_emoji": "Buscar un emoji",
|
||||||
"stickers": "Adhesius",
|
"stickers": "Adhesius",
|
||||||
"unicode": "Emojis unicode"
|
"unicode": "Emojis unicode"
|
||||||
|
@ -254,6 +255,10 @@
|
||||||
"hint": "Entra per a participar en la conversa",
|
"hint": "Entra per a participar en la conversa",
|
||||||
"login": "Inicia sessió",
|
"login": "Inicia sessió",
|
||||||
"logout": "Tanca la sessió",
|
"logout": "Tanca la sessió",
|
||||||
|
"logout_confirm": "Segur que vols tancar la sessió?",
|
||||||
|
"logout_confirm_accept_button": "Surt",
|
||||||
|
"logout_confirm_cancel_button": "Canceŀla",
|
||||||
|
"logout_confirm_title": "Tanca la sessió",
|
||||||
"password": "Contrasenya",
|
"password": "Contrasenya",
|
||||||
"placeholder": "el meu nom d'usuari",
|
"placeholder": "el meu nom d'usuari",
|
||||||
"recovery_code": "Codi de recuperació",
|
"recovery_code": "Codi de recuperació",
|
||||||
|
@ -266,6 +271,32 @@
|
||||||
"next": "Següent",
|
"next": "Següent",
|
||||||
"previous": "Anterior"
|
"previous": "Anterior"
|
||||||
},
|
},
|
||||||
|
"moderation": {
|
||||||
|
"moderation": "Moderació",
|
||||||
|
"reports": {
|
||||||
|
"add_note": "Afegeix una nota",
|
||||||
|
"close": "Tanca",
|
||||||
|
"delete_note": "Esborra la nota",
|
||||||
|
"delete_note_accept": "Sí, esborra-la",
|
||||||
|
"delete_note_cancel": "No, conserva-la",
|
||||||
|
"delete_note_confirm": "Segur que vols esborrar aquesta nota?",
|
||||||
|
"delete_note_title": "Cal confirmació",
|
||||||
|
"no_content": "Sense descripció",
|
||||||
|
"no_reports": "No hi ha informes per mostrar",
|
||||||
|
"note_placeholder": "Deixa una nota",
|
||||||
|
"notes": "{ count } nota | { count } notes",
|
||||||
|
"reopen": "Reobre",
|
||||||
|
"report": "Denuncia-ho",
|
||||||
|
"reports": "Denúncies",
|
||||||
|
"resolve": "Resol",
|
||||||
|
"show_closed": "Mostra les tancades",
|
||||||
|
"statuses": "{ count } post| { count } posts",
|
||||||
|
"tag_policy_notice": "Activa la restricció de publicacions segons la TagPolicy MRF",
|
||||||
|
"tags": "Estableix restriccions a les publicacions"
|
||||||
|
},
|
||||||
|
"statuses": "Publicacions",
|
||||||
|
"users": "Usuàries"
|
||||||
|
},
|
||||||
"nav": {
|
"nav": {
|
||||||
"about": "Quant a",
|
"about": "Quant a",
|
||||||
"administration": "Administració",
|
"administration": "Administració",
|
||||||
|
@ -282,6 +313,7 @@
|
||||||
"interactions": "Interaccions",
|
"interactions": "Interaccions",
|
||||||
"lists": "Llistes",
|
"lists": "Llistes",
|
||||||
"mentions": "Mencions",
|
"mentions": "Mencions",
|
||||||
|
"moderation": "Moderació",
|
||||||
"preferences": "Preferències",
|
"preferences": "Preferències",
|
||||||
"public_timeline_description": "Apunts públics des d'aquesta instància",
|
"public_timeline_description": "Apunts públics des d'aquesta instància",
|
||||||
"public_tl": "Línia de temps Pública",
|
"public_tl": "Línia de temps Pública",
|
||||||
|
@ -375,9 +407,12 @@
|
||||||
"private": "Aquest apunt serà visible només per els teus seguidors",
|
"private": "Aquest apunt serà visible només per els teus seguidors",
|
||||||
"public": "Aquest apunt serà visible per a tothom",
|
"public": "Aquest apunt serà visible per a tothom",
|
||||||
"unlisted": "Aquest apunt no es veurà ni a la Línia de temps Pública ni a Tota la Xarxa Coneguda"
|
"unlisted": "Aquest apunt no es veurà ni a la Línia de temps Pública ni a Tota la Xarxa Coneguda"
|
||||||
}
|
},
|
||||||
|
"toggle_content_warning": "Des/activa l'avís de contingut"
|
||||||
},
|
},
|
||||||
"registration": {
|
"registration": {
|
||||||
|
"awaiting_email_confirmation": "S'ha registrat el teu compte i s'ha enviat un correu a la teva adreça. Consulta el correu per completar el registre.",
|
||||||
|
"awaiting_email_confirmation_title": "Pendent de confirmar l'adreça de correu",
|
||||||
"bio": "Bio",
|
"bio": "Bio",
|
||||||
"bio_placeholder": "p.e.\nHola! Benvingut a la meva bio.\nM'encanta veure anime i jugar a jocs. Espero que podrem ser amics!",
|
"bio_placeholder": "p.e.\nHola! Benvingut a la meva bio.\nM'encanta veure anime i jugar a jocs. Espero que podrem ser amics!",
|
||||||
"captcha": "CAPTCHA",
|
"captcha": "CAPTCHA",
|
||||||
|
@ -391,6 +426,8 @@
|
||||||
"reason_placeholder": "Aquesta instància aprova els registres manualment.\nExplica a l'administració per què vols registrar-te.",
|
"reason_placeholder": "Aquesta instància aprova els registres manualment.\nExplica a l'administració per què vols registrar-te.",
|
||||||
"register": "Registre",
|
"register": "Registre",
|
||||||
"registration": "Registre",
|
"registration": "Registre",
|
||||||
|
"request_sent": "La teva soŀlicitud de registre s'ha enviat. Rebràs un correu quan sigui aprovada.",
|
||||||
|
"request_sent_title": "Soŀlicitud de registre",
|
||||||
"token": "Codi d'invitació",
|
"token": "Codi d'invitació",
|
||||||
"username_placeholder": "p. ex. akko",
|
"username_placeholder": "p. ex. akko",
|
||||||
"validations": {
|
"validations": {
|
||||||
|
@ -500,6 +537,8 @@
|
||||||
"enable_web_push_notifications": "Habilitar notificacions del navegador",
|
"enable_web_push_notifications": "Habilitar notificacions del navegador",
|
||||||
"enter_current_password_to_confirm": "Posa la teva contrasenya actual per a confirmar la teva identitat",
|
"enter_current_password_to_confirm": "Posa la teva contrasenya actual per a confirmar la teva identitat",
|
||||||
"expert_mode": "Mostra avançat",
|
"expert_mode": "Mostra avançat",
|
||||||
|
"expire_posts_enabled": "Esborra les publicacions després d'un cert nombre de dies",
|
||||||
|
"expire_posts_input_placeholder": "Nombre de dies",
|
||||||
"export_theme": "Desa el tema",
|
"export_theme": "Desa el tema",
|
||||||
"file_export_import": {
|
"file_export_import": {
|
||||||
"backup_restore": "Còpia de seguretat de la configuració",
|
"backup_restore": "Còpia de seguretat de la configuració",
|
||||||
|
@ -641,6 +680,7 @@
|
||||||
"pad_emoji": "Acompanya els emojis amb espais al afegir-los des del selector",
|
"pad_emoji": "Acompanya els emojis amb espais al afegir-los des del selector",
|
||||||
"panelRadius": "Panells",
|
"panelRadius": "Panells",
|
||||||
"pause_on_unfocused": "Pausa quan la pestanya perdi el focus",
|
"pause_on_unfocused": "Pausa quan la pestanya perdi el focus",
|
||||||
|
"permit_followback_description": "Aprova automàticament les soŀlicituds de seguiment que vinguin d'usuàries que ja segueixes",
|
||||||
"play_videos_in_modal": "Reproduir vídeos en un marc emergent",
|
"play_videos_in_modal": "Reproduir vídeos en un marc emergent",
|
||||||
"post_look_feel": "Aspecte i Sensació dels apunts",
|
"post_look_feel": "Aspecte i Sensació dels apunts",
|
||||||
"post_status_content_type": "Tipus de contingut d'apunt predeterminat",
|
"post_status_content_type": "Tipus de contingut d'apunt predeterminat",
|
||||||
|
@ -709,6 +749,7 @@
|
||||||
"show_admin_badge": "Mostra l'insígnia \"Administrador\" en el meu perfil",
|
"show_admin_badge": "Mostra l'insígnia \"Administrador\" en el meu perfil",
|
||||||
"show_moderator_badge": "Mostra l'insígnia \"Moderador\" en el meu perfil",
|
"show_moderator_badge": "Mostra l'insígnia \"Moderador\" en el meu perfil",
|
||||||
"show_nav_shortcuts": "Mostra els accessos directes addicionals en el panell superior",
|
"show_nav_shortcuts": "Mostra els accessos directes addicionals en el panell superior",
|
||||||
|
"show_page_backgrounds": "Mostra fons de pantalla específics de pàgines, com en les pàgines de perfil d'usuari",
|
||||||
"show_panel_nav_shortcuts": "Mostra els accessos directes de navegació de la línia de temps en el panell superior",
|
"show_panel_nav_shortcuts": "Mostra els accessos directes de navegació de la línia de temps en el panell superior",
|
||||||
"show_scrollbars": "Mostra les barres de desplaçament de la columna lateral",
|
"show_scrollbars": "Mostra les barres de desplaçament de la columna lateral",
|
||||||
"show_wider_shortcuts": "Mostra més separats els accessos directes del panell superior",
|
"show_wider_shortcuts": "Mostra més separats els accessos directes del panell superior",
|
||||||
|
@ -884,9 +925,13 @@
|
||||||
"upload_a_photo": "Pujar una foto",
|
"upload_a_photo": "Pujar una foto",
|
||||||
"useStreamingApi": "Rebre apunts i notificacions en temps real",
|
"useStreamingApi": "Rebre apunts i notificacions en temps real",
|
||||||
"useStreamingApiWarning": "És genial emprar-lo. Si es trenca, refresca, suposo?",
|
"useStreamingApiWarning": "És genial emprar-lo. Si es trenca, refresca, suposo?",
|
||||||
"use_at_icon": "Mostra el símbol {'@'} com a icona enlloc de text",
|
"use_blurhash": "Fes borroses les miniatures d'imatges NSFW",
|
||||||
"use_contain_fit": "No retallar els adjunts en miniatures",
|
"use_contain_fit": "No retallar els adjunts en miniatures",
|
||||||
"use_one_click_nsfw": "Obre els adjunts NSFW amb només un clic",
|
"use_one_click_nsfw": "Obre els adjunts NSFW amb només un clic",
|
||||||
|
"user_accepts_direct_messages_from": "Accepta missatges directes de",
|
||||||
|
"user_accepts_direct_messages_from_everybody": "Qualsevol",
|
||||||
|
"user_accepts_direct_messages_from_nobody": "Ningú",
|
||||||
|
"user_accepts_direct_messages_from_people_i_follow": "Comptes que segueixo",
|
||||||
"user_mutes": "Usuaris",
|
"user_mutes": "Usuaris",
|
||||||
"user_profile_default_tab": "Pestanya per defecte en el Perfil d'Usuari",
|
"user_profile_default_tab": "Pestanya per defecte en el Perfil d'Usuari",
|
||||||
"user_profiles": "Perfils d'usuari",
|
"user_profiles": "Perfils d'usuari",
|
||||||
|
@ -1009,6 +1054,7 @@
|
||||||
"collapse": "Replega",
|
"collapse": "Replega",
|
||||||
"conversation": "Conversa",
|
"conversation": "Conversa",
|
||||||
"error": "Error carregant la línia de temps: {0}",
|
"error": "Error carregant la línia de temps: {0}",
|
||||||
|
"follow_tag": "Segueix l'etiqueta",
|
||||||
"load_older": "Carrega apunts anteriors",
|
"load_older": "Carrega apunts anteriors",
|
||||||
"no_more_statuses": "No hi ha més apunts",
|
"no_more_statuses": "No hi ha més apunts",
|
||||||
"no_retweet_hint": "L'apunt és només per a seguidors o és \"directe\" i no es pot repetir o citar",
|
"no_retweet_hint": "L'apunt és només per a seguidors o és \"directe\" i no es pot repetir o citar",
|
||||||
|
@ -1018,6 +1064,7 @@
|
||||||
"show_new": "Mostra els nous",
|
"show_new": "Mostra els nous",
|
||||||
"socket_broke": "Connexió a temps real perduda: codi CloseEvent {0}",
|
"socket_broke": "Connexió a temps real perduda: codi CloseEvent {0}",
|
||||||
"socket_reconnected": "Connexió a temps real establerta",
|
"socket_reconnected": "Connexió a temps real establerta",
|
||||||
|
"unfollow_tag": "Deixa de seguir l'etiqueta",
|
||||||
"up_to_date": "Actualitzat"
|
"up_to_date": "Actualitzat"
|
||||||
},
|
},
|
||||||
"toast": {
|
"toast": {
|
||||||
|
@ -1082,6 +1129,7 @@
|
||||||
"block_confirm_title": "Bloqueja l'usuari",
|
"block_confirm_title": "Bloqueja l'usuari",
|
||||||
"block_progress": "Bloquejant…",
|
"block_progress": "Bloquejant…",
|
||||||
"blocked": "Bloquejat!",
|
"blocked": "Bloquejat!",
|
||||||
|
"blocks_you": "Et té bloquejadi!",
|
||||||
"bot": "Bot",
|
"bot": "Bot",
|
||||||
"deactivated": "Desactivat",
|
"deactivated": "Desactivat",
|
||||||
"deny": "Denega",
|
"deny": "Denega",
|
||||||
|
@ -1096,7 +1144,10 @@
|
||||||
"follow_cancel": "Cancel·la la sol·licitud",
|
"follow_cancel": "Cancel·la la sol·licitud",
|
||||||
"follow_progress": "Sol·licitant…",
|
"follow_progress": "Sol·licitant…",
|
||||||
"follow_sent": "Petició enviada!",
|
"follow_sent": "Petició enviada!",
|
||||||
|
"follow_tag": "Segueix l'etiqueta",
|
||||||
"follow_unfollow": "Deixa de seguir",
|
"follow_unfollow": "Deixa de seguir",
|
||||||
|
"followed_tags": "Etiquetes que segueixes",
|
||||||
|
"followed_users": "Usuaris que segueixes",
|
||||||
"followees": "Seguint",
|
"followees": "Seguint",
|
||||||
"followers": "Seguidors",
|
"followers": "Seguidors",
|
||||||
"following": "Seguint!",
|
"following": "Seguint!",
|
||||||
|
@ -1121,12 +1172,14 @@
|
||||||
"mute_domain": "Bloqueja el domini",
|
"mute_domain": "Bloqueja el domini",
|
||||||
"mute_progress": "Silenciant…",
|
"mute_progress": "Silenciant…",
|
||||||
"muted": "Silenciat",
|
"muted": "Silenciat",
|
||||||
|
"not_following_any_hashtags": "No estàs seguint cap etiqueta",
|
||||||
"note": "Nota privada",
|
"note": "Nota privada",
|
||||||
"per_day": "per dia",
|
"per_day": "per dia",
|
||||||
"remote_follow": "Seguiment remot",
|
"remote_follow": "Seguiment remot",
|
||||||
"remove_follower": "Esborra seguidor",
|
"remove_follower": "Esborra seguidor",
|
||||||
"replies": "Amb respostes",
|
"replies": "Amb respostes",
|
||||||
"report": "Informa",
|
"report": "Informa",
|
||||||
|
"requested_by": "Et vol seguir",
|
||||||
"show_repeats": "Mostra les repeticions",
|
"show_repeats": "Mostra les repeticions",
|
||||||
"statuses": "Apunts",
|
"statuses": "Apunts",
|
||||||
"subscribe": "Subscriu-te",
|
"subscribe": "Subscriu-te",
|
||||||
|
@ -1136,11 +1189,13 @@
|
||||||
"unfollow_confirm_accept_button": "Sí, deixa'l de seguir",
|
"unfollow_confirm_accept_button": "Sí, deixa'l de seguir",
|
||||||
"unfollow_confirm_cancel_button": "No, no el deixis de seguir",
|
"unfollow_confirm_cancel_button": "No, no el deixis de seguir",
|
||||||
"unfollow_confirm_title": "Deixa de seguir l'usuari",
|
"unfollow_confirm_title": "Deixa de seguir l'usuari",
|
||||||
|
"unfollow_tag": "Deixa de seguir l'etiqueta",
|
||||||
"unmute": "Deixa de silenciar",
|
"unmute": "Deixa de silenciar",
|
||||||
"unmute_progress": "Deixant de silenciar…",
|
"unmute_progress": "Deixant de silenciar…",
|
||||||
"unsubscribe": "Anul·la la subscripció"
|
"unsubscribe": "Anul·la la subscripció"
|
||||||
},
|
},
|
||||||
"user_profile": {
|
"user_profile": {
|
||||||
|
"field_validated": "Enllaç verificat",
|
||||||
"profile_does_not_exist": "Disculpes, aquest perfil no existeix.",
|
"profile_does_not_exist": "Disculpes, aquest perfil no existeix.",
|
||||||
"profile_loading_error": "Disculpes, hi ha hagut un error carregant aquest perfil.",
|
"profile_loading_error": "Disculpes, hi ha hagut un error carregant aquest perfil.",
|
||||||
"timeline_title": "Línia de temps del usuari"
|
"timeline_title": "Línia de temps del usuari"
|
||||||
|
|
|
@ -916,7 +916,6 @@
|
||||||
"upload_a_photo": "Lade ein Foto hoch",
|
"upload_a_photo": "Lade ein Foto hoch",
|
||||||
"useStreamingApi": "Empfange Posts und Benachrichtigungen in Echtzeit",
|
"useStreamingApi": "Empfange Posts und Benachrichtigungen in Echtzeit",
|
||||||
"useStreamingApiWarning": "(Nicht empfohlen, experimentell, bekannt dafür, Posts zu überspringen)",
|
"useStreamingApiWarning": "(Nicht empfohlen, experimentell, bekannt dafür, Posts zu überspringen)",
|
||||||
"use_at_icon": "{'@'}-Symbol als Icon und nicht als Text anzeigen",
|
|
||||||
"use_blurhash": "Blurhash für NSFW-Vorschauen verwenden",
|
"use_blurhash": "Blurhash für NSFW-Vorschauen verwenden",
|
||||||
"use_contain_fit": "Vorschaubilder nicht zuschneiden",
|
"use_contain_fit": "Vorschaubilder nicht zuschneiden",
|
||||||
"use_one_click_nsfw": "Heikle Anhänge mit nur einem Klick öffnen",
|
"use_one_click_nsfw": "Heikle Anhänge mit nur einem Klick öffnen",
|
||||||
|
|
|
@ -18,7 +18,8 @@
|
||||||
"reason": "Λόγος",
|
"reason": "Λόγος",
|
||||||
"simple_policies": "Πολιτικές του instance"
|
"simple_policies": "Πολιτικές του instance"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"staff": "Προσωπικό"
|
||||||
},
|
},
|
||||||
"announcements": {
|
"announcements": {
|
||||||
"all_day_prompt": "Αυτό είναι ένα ολοήμερο συμβάν",
|
"all_day_prompt": "Αυτό είναι ένα ολοήμερο συμβάν",
|
||||||
|
@ -27,10 +28,14 @@
|
||||||
"delete_action": "Διαγραφή",
|
"delete_action": "Διαγραφή",
|
||||||
"edit_action": "Επεξεργασία",
|
"edit_action": "Επεξεργασία",
|
||||||
"end_time_display": "Λήγει στις {time}",
|
"end_time_display": "Λήγει στις {time}",
|
||||||
|
"end_time_prompt": "Λήξη: ",
|
||||||
|
"inactive_message": "Αυτή η ανακοίνωση είναι ανενεργή",
|
||||||
"page_header": "Ανακοινώσεις",
|
"page_header": "Ανακοινώσεις",
|
||||||
|
"post_action": "Ανάρτηση",
|
||||||
"title": "Ανακοίνωση"
|
"title": "Ανακοίνωση"
|
||||||
},
|
},
|
||||||
"chats": {
|
"chats": {
|
||||||
|
"delete_confirm": "Θέλετε σίγουρα να διαγράψετε αυτό το μήνυμα;",
|
||||||
"empty_message_error": "Δε μπορεί να σταλεί κενό μήνυμα",
|
"empty_message_error": "Δε μπορεί να σταλεί κενό μήνυμα",
|
||||||
"error_sending_message": "Κάτι πήγε λάθος κατά την αποστολή του μηνύματος.",
|
"error_sending_message": "Κάτι πήγε λάθος κατά την αποστολή του μηνύματος.",
|
||||||
"message_user": "Στείλε μήνυμα στον/στην {nickname}",
|
"message_user": "Στείλε μήνυμα στον/στην {nickname}",
|
||||||
|
|
|
@ -380,6 +380,7 @@
|
||||||
"text/x.misskeymarkdown": "MFM"
|
"text/x.misskeymarkdown": "MFM"
|
||||||
},
|
},
|
||||||
"content_warning": "Content Warning (optional)",
|
"content_warning": "Content Warning (optional)",
|
||||||
|
"toggle_content_warning": "Toggle content warning",
|
||||||
"default": "Just arrived at Luna Nova Academy",
|
"default": "Just arrived at Luna Nova Academy",
|
||||||
"direct_warning_to_all": "This post will be visible to all the mentioned users.",
|
"direct_warning_to_all": "This post will be visible to all the mentioned users.",
|
||||||
"direct_warning_to_first_only": "This post will only be visible to the mentioned users at the beginning of the message.",
|
"direct_warning_to_first_only": "This post will only be visible to the mentioned users at the beginning of the message.",
|
||||||
|
@ -600,6 +601,7 @@
|
||||||
"list_aliases_error": "Error fetching aliases: {error}",
|
"list_aliases_error": "Error fetching aliases: {error}",
|
||||||
"list_backups_error": "Error fetching backup list: {error}",
|
"list_backups_error": "Error fetching backup list: {error}",
|
||||||
"lock_account_description": "Restrict your account to approved followers only",
|
"lock_account_description": "Restrict your account to approved followers only",
|
||||||
|
"permit_followback_description": "Automatically approve requests from already followed users",
|
||||||
"loop_video": "Loop videos",
|
"loop_video": "Loop videos",
|
||||||
"loop_video_silent_only": "Loop only videos without sound (i.e. Mastodon's \"gifs\")",
|
"loop_video_silent_only": "Loop only videos without sound (i.e. Mastodon's \"gifs\")",
|
||||||
"mascot": "Mastodon FE Mascot",
|
"mascot": "Mastodon FE Mascot",
|
||||||
|
@ -682,6 +684,7 @@
|
||||||
"play_videos_in_modal": "Play videos in a popup frame",
|
"play_videos_in_modal": "Play videos in a popup frame",
|
||||||
"post_look_feel": "Posts Look & Feel",
|
"post_look_feel": "Posts Look & Feel",
|
||||||
"post_status_content_type": "Default post content type",
|
"post_status_content_type": "Default post content type",
|
||||||
|
"post_language": "Default post language",
|
||||||
"posts": "Posts",
|
"posts": "Posts",
|
||||||
"preload_images": "Preload images",
|
"preload_images": "Preload images",
|
||||||
"presets": "Presets",
|
"presets": "Presets",
|
||||||
|
@ -749,6 +752,7 @@
|
||||||
"show_nav_shortcuts": "Show extra navigation shortcuts in top panel",
|
"show_nav_shortcuts": "Show extra navigation shortcuts in top panel",
|
||||||
"show_panel_nav_shortcuts": "Show timeline navigation shortcuts at the top of the panel",
|
"show_panel_nav_shortcuts": "Show timeline navigation shortcuts at the top of the panel",
|
||||||
"show_scrollbars": "Show side column's scrollbars",
|
"show_scrollbars": "Show side column's scrollbars",
|
||||||
|
"show_page_backgrounds": "Show page-specific backgrounds, e.g. for user profiles",
|
||||||
"show_wider_shortcuts": "Show wider gap between top panel shortcuts",
|
"show_wider_shortcuts": "Show wider gap between top panel shortcuts",
|
||||||
"show_yous": "Show (You)s",
|
"show_yous": "Show (You)s",
|
||||||
"stop_gifs": "Pause animated images until you hover on them",
|
"stop_gifs": "Pause animated images until you hover on them",
|
||||||
|
@ -922,7 +926,6 @@
|
||||||
"upload_a_photo": "Upload a photo",
|
"upload_a_photo": "Upload a photo",
|
||||||
"useStreamingApi": "Receive posts and notifications real-time",
|
"useStreamingApi": "Receive posts and notifications real-time",
|
||||||
"useStreamingApiWarning": "It's cool use it. If it breaks refresh I guess?",
|
"useStreamingApiWarning": "It's cool use it. If it breaks refresh I guess?",
|
||||||
"use_at_icon": "Display {'@'} symbol as an icon instead of text",
|
|
||||||
"use_contain_fit": "Don't crop the attachment in thumbnails",
|
"use_contain_fit": "Don't crop the attachment in thumbnails",
|
||||||
"use_one_click_nsfw": "Open NSFW attachments with just one click",
|
"use_one_click_nsfw": "Open NSFW attachments with just one click",
|
||||||
"user_mutes": "Users",
|
"user_mutes": "Users",
|
||||||
|
|
|
@ -84,6 +84,7 @@
|
||||||
"keep_open": "Mantener el selector abierto",
|
"keep_open": "Mantener el selector abierto",
|
||||||
"load_all": "Cargando todos los {emojiAmount} emoji",
|
"load_all": "Cargando todos los {emojiAmount} emoji",
|
||||||
"load_all_hint": "Cargado el primer emoji {saneAmount}, cargar todos los emoji puede causar problemas de rendimiento.",
|
"load_all_hint": "Cargado el primer emoji {saneAmount}, cargar todos los emoji puede causar problemas de rendimiento.",
|
||||||
|
"recent": "Recientemente usado",
|
||||||
"search_emoji": "Buscar un emoji",
|
"search_emoji": "Buscar un emoji",
|
||||||
"stickers": "Pegatinas",
|
"stickers": "Pegatinas",
|
||||||
"unicode": "Emojis unicode"
|
"unicode": "Emojis unicode"
|
||||||
|
@ -302,7 +303,7 @@
|
||||||
"announcements": "Anuncios",
|
"announcements": "Anuncios",
|
||||||
"back": "Volver",
|
"back": "Volver",
|
||||||
"bookmarks": "Marcadores",
|
"bookmarks": "Marcadores",
|
||||||
"bubble_timeline": "Linea temporal burbuja",
|
"bubble_timeline": "Línea temporal burbuja",
|
||||||
"bubble_timeline_description": "Publicaciones de instancias cercanas a la tuya, recomendadas por los/las administradores/as",
|
"bubble_timeline_description": "Publicaciones de instancias cercanas a la tuya, recomendadas por los/las administradores/as",
|
||||||
"chats": "Chats",
|
"chats": "Chats",
|
||||||
"dms": "Mensajes directos",
|
"dms": "Mensajes directos",
|
||||||
|
@ -915,13 +916,20 @@
|
||||||
"token": "Token",
|
"token": "Token",
|
||||||
"tooltipRadius": "Información/alertas",
|
"tooltipRadius": "Información/alertas",
|
||||||
"translation_language": "Idioma de traducción automática",
|
"translation_language": "Idioma de traducción automática",
|
||||||
|
"tree_advanced": "Mostrar botones extras para abrir y cerrar la cadena de réplicas en los hilos",
|
||||||
"type_domains_to_mute": "Buscar dominios para silenciar",
|
"type_domains_to_mute": "Buscar dominios para silenciar",
|
||||||
"upload_a_photo": "Subir una foto",
|
"upload_a_photo": "Subir una foto",
|
||||||
"useStreamingApi": "Recibir publicaciones y notificaciones en tiempo real",
|
"useStreamingApi": "Recibir publicaciones y notificaciones en tiempo real",
|
||||||
"useStreamingApiWarning": "(no recomendado, experimental, puede omitir publicaciones)",
|
"useStreamingApiWarning": "(no recomendado, experimental, puede omitir publicaciones)",
|
||||||
|
"use_blurhash": "Usar miniaturas borrosas para las imágenes sensibles",
|
||||||
"use_contain_fit": "No recortar los adjuntos en miniaturas",
|
"use_contain_fit": "No recortar los adjuntos en miniaturas",
|
||||||
"use_one_click_nsfw": "Abrir los adjuntos NSFW con un solo click",
|
"use_one_click_nsfw": "Abrir los adjuntos NSFW con un solo click",
|
||||||
|
"user_accepts_direct_messages_from": "Aceptar mensajes directos de",
|
||||||
|
"user_accepts_direct_messages_from_everybody": "Todos",
|
||||||
|
"user_accepts_direct_messages_from_nobody": "Nadie",
|
||||||
|
"user_accepts_direct_messages_from_people_i_follow": "Personas que sigo",
|
||||||
"user_mutes": "Usuarios",
|
"user_mutes": "Usuarios",
|
||||||
|
"user_profiles": "Perfiles de usuario",
|
||||||
"user_settings": "Ajustes del Usuario",
|
"user_settings": "Ajustes del Usuario",
|
||||||
"valid_until": "Válido hasta",
|
"valid_until": "Válido hasta",
|
||||||
"values": {
|
"values": {
|
||||||
|
@ -934,26 +942,61 @@
|
||||||
"title": "Versión"
|
"title": "Versión"
|
||||||
},
|
},
|
||||||
"virtual_scrolling": "Optimizar la representación de la linea temporal",
|
"virtual_scrolling": "Optimizar la representación de la linea temporal",
|
||||||
"word_filter": "Filtro de palabras"
|
"word_filter": "Filtro de palabras",
|
||||||
|
"wordfilter": "Filtro de palabras"
|
||||||
|
},
|
||||||
|
"settings_profile": {
|
||||||
|
"creating": "Creando un nuevo perfil de configuración \"{profile}\"...",
|
||||||
|
"synchronization_error": "No se pudo sincronizar la configuración: {err}",
|
||||||
|
"synchronized": "¡Ajustes sincronizados!",
|
||||||
|
"synchronizing": "Sincronizando los ajustes de perfil \"{profile}\"..."
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
|
"ancestor_follow": "Vea {numReplies} respuesta en esta publicación | Ver otras {numReplies} respuestas en esta publicación",
|
||||||
|
"ancestor_follow_with_icon": "{icon} {text}",
|
||||||
|
"attachment_stop_flash": "Parar el reproductor Flash",
|
||||||
"bookmark": "Marcar",
|
"bookmark": "Marcar",
|
||||||
"copy_link": "Copiar el enlace al estado",
|
"collapse_attachments": "Minimizar adjuntos",
|
||||||
"delete": "Eliminar publicación",
|
"copy_link": "Copiar el enlace al mensaje",
|
||||||
"delete_confirm": "¿Realmente quieres borrar la publicación?",
|
"delete": "Eliminar mensaje",
|
||||||
|
"delete_confirm": "¿Realmente quieres borrar el mensaje?",
|
||||||
|
"delete_confirm_accept_button": "Sí, elimínelo",
|
||||||
|
"delete_confirm_cancel_button": "No, mantenerlo",
|
||||||
|
"delete_confirm_title": "Confirmar la eliminación",
|
||||||
|
"edit": "Editar",
|
||||||
|
"edit_history": "Editar el historial",
|
||||||
|
"edit_history_modal_title": "Editado {historyCount} vez | Editado {historyCount} veces",
|
||||||
|
"edited_at": "Editado {time}",
|
||||||
"expand": "Expandir",
|
"expand": "Expandir",
|
||||||
"external_source": "Fuente externa",
|
"external_source": "Fuente externa",
|
||||||
"favorites": "Favoritos",
|
"favorites": "Favoritos",
|
||||||
|
"hide_attachment": "Ocultar adjuntos",
|
||||||
"hide_content": "Ocultar el contenido",
|
"hide_content": "Ocultar el contenido",
|
||||||
"hide_full_subject": "Ocultar el tema completo",
|
"hide_full_subject": "Ocultar la advertencia de contenido",
|
||||||
|
"many_attachments": "El mensaje tiene {number} adjunto | El mensaje tiene {number} adjuntos",
|
||||||
"mentions": "Menciones",
|
"mentions": "Menciones",
|
||||||
|
"move_down": "Desplazar adjunto a la derecha",
|
||||||
|
"move_up": "Desplazar adjunto a la izquierda",
|
||||||
"mute_conversation": "Silenciar la conversación",
|
"mute_conversation": "Silenciar la conversación",
|
||||||
"nsfw": "NSFW (No apropiado para el trabajo)",
|
"nsfw": "NSFW (No apropiado para el trabajo)",
|
||||||
|
"open_gallery": "Abrir la galería",
|
||||||
|
"override_translation_source_language": "Anular el idioma de origen",
|
||||||
"pin": "Fijar en tu perfil",
|
"pin": "Fijar en tu perfil",
|
||||||
"pinned": "Fijado",
|
"pinned": "Fijado",
|
||||||
"plus_more": "+{number} más",
|
"plus_more": "+{number} más",
|
||||||
|
"redraft": "Eliminar y volver a redactar",
|
||||||
|
"redraft_confirm": "¿Realmente deseas eliminar y volver a redactar esta publicación? Las interacciones con la publicación original no se conservarán.",
|
||||||
|
"redraft_confirm_accept_button": "Sí, eliminar y volver a redactar",
|
||||||
|
"redraft_confirm_cancel_button": "No, conserva el original",
|
||||||
|
"redraft_confirm_title": "Confirmar eliminación y volver a redactar",
|
||||||
|
"remove_attachment": "Quitar archivo adjunto",
|
||||||
|
"repeat_confirm": "¿De verdad quieres repetir esta entrada?",
|
||||||
|
"repeat_confirm_accept_button": "Si, repítela",
|
||||||
|
"repeat_confirm_cancel_button": "No, no repitas",
|
||||||
|
"repeat_confirm_title": "Confirmar repetir",
|
||||||
"repeats": "Repetidos",
|
"repeats": "Repetidos",
|
||||||
"replies_list": "Respuestas:",
|
"replies_list": "Respuestas:",
|
||||||
|
"replies_list_with_others": "Ver {numReplies} respuesta | Ver {numReplies} respuestas más",
|
||||||
"reply_to": "Respondiendo a",
|
"reply_to": "Respondiendo a",
|
||||||
"show_content": "Mostrar el contenido",
|
"show_content": "Mostrar el contenido",
|
||||||
"show_full_subject": "Mostrar el tema completo",
|
"show_full_subject": "Mostrar el tema completo",
|
||||||
|
|
|
@ -920,7 +920,6 @@
|
||||||
"upload_a_photo": "Envoyer une photo",
|
"upload_a_photo": "Envoyer une photo",
|
||||||
"useStreamingApi": "Recevoir les messages et notifications en temps réel",
|
"useStreamingApi": "Recevoir les messages et notifications en temps réel",
|
||||||
"useStreamingApiWarning": "(Non recommandé, expérimental, connu pour rater des messages)",
|
"useStreamingApiWarning": "(Non recommandé, expérimental, connu pour rater des messages)",
|
||||||
"use_at_icon": "Afficher le symbol {'@'} comme une image",
|
|
||||||
"use_contain_fit": "Ne pas rogner les miniatures des pièces-jointes",
|
"use_contain_fit": "Ne pas rogner les miniatures des pièces-jointes",
|
||||||
"use_one_click_nsfw": "Ouvrir les pièces-jointes sensibles avec un seul clic",
|
"use_one_click_nsfw": "Ouvrir les pièces-jointes sensibles avec un seul clic",
|
||||||
"user_mutes": "Comptes",
|
"user_mutes": "Comptes",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"about": {
|
"about": {
|
||||||
"bubble_instances": "Instance Bubble Lokal",
|
"bubble_instances": "Instance Bubble Lokal",
|
||||||
"bubble_instances_description": "Instansi yang dipilih oleh admin untuk mewakili instance ini",
|
"bubble_instances_description": "Instansi yang dipilih oleh admin untuk mewakili daerah lokal instansi ini",
|
||||||
"mrf": {
|
"mrf": {
|
||||||
"federation": "Federasi",
|
"federation": "Federasi",
|
||||||
"keyword": {
|
"keyword": {
|
||||||
|
@ -456,8 +456,10 @@
|
||||||
"settings": {
|
"settings": {
|
||||||
"accent": "Aksen",
|
"accent": "Aksen",
|
||||||
"account_alias": "Akun alias",
|
"account_alias": "Akun alias",
|
||||||
|
"account_alias_table_head": "Alias",
|
||||||
"account_backup": "Pencadangan akun",
|
"account_backup": "Pencadangan akun",
|
||||||
"account_backup_description": "Ini memungkinkan kamu untuk mengunduh arsip yang berisi informasi tentang akun dan postingan kamu, namun belum bisa diimpor ke akun Pleroma.",
|
"account_backup_description": "Ini memungkinkan kamu untuk mengunduh arsip yang berisi informasi tentang akun dan postingan kamu, namun belum bisa diimpor ke akun Pleroma.",
|
||||||
|
"account_backup_table_head": "Cadangan",
|
||||||
"account_privacy": "Privasi",
|
"account_privacy": "Privasi",
|
||||||
"add_alias_error": "Gagal menambahkan alias: {error}",
|
"add_alias_error": "Gagal menambahkan alias: {error}",
|
||||||
"add_backup": "Buat cadangan baru",
|
"add_backup": "Buat cadangan baru",
|
||||||
|
@ -555,7 +557,8 @@
|
||||||
"follow_export_button": "Export yang kamu ikuti ke dalam file csv",
|
"follow_export_button": "Export yang kamu ikuti ke dalam file csv",
|
||||||
"follow_import": "Import pengikut",
|
"follow_import": "Import pengikut",
|
||||||
"follow_import_error": "Terjadi kesalahan ketika mengimpor pengikut",
|
"follow_import_error": "Terjadi kesalahan ketika mengimpor pengikut",
|
||||||
"follows_imported": "Pengguna yang diikuti telak diimpor! Proses mungkin membutuhkan beberapa saat.",
|
"follows_imported": "Daftar mengikuti telah diimpor! Proses mungkin membutuhkan beberapa saat.",
|
||||||
|
"foreground": "Latar depan",
|
||||||
"fun": "Seru",
|
"fun": "Seru",
|
||||||
"general": "Umum",
|
"general": "Umum",
|
||||||
"greentext": "Panah meme",
|
"greentext": "Panah meme",
|
||||||
|
@ -563,17 +566,30 @@
|
||||||
"hide_attachments_in_convo": "Sembunyikan lampiran pada percakapan",
|
"hide_attachments_in_convo": "Sembunyikan lampiran pada percakapan",
|
||||||
"hide_attachments_in_tl": "Sembunyikan lampiran di linimasa",
|
"hide_attachments_in_tl": "Sembunyikan lampiran di linimasa",
|
||||||
"hide_bot_indication": "Sembunyikan tanda bot pada postingan",
|
"hide_bot_indication": "Sembunyikan tanda bot pada postingan",
|
||||||
|
"hide_favorites_description": "Jangan tunjukkan daftar kesukaan saya (orang masih mendapatkan notifikasi)",
|
||||||
"hide_filtered_statuses": "Sembunyikan semua postingan yang tersaring",
|
"hide_filtered_statuses": "Sembunyikan semua postingan yang tersaring",
|
||||||
"hide_followers_count_description": "Jangan tampilkan jumlah pengikut",
|
"hide_followers_count_description": "Jangan tampilkan jumlah pengikut",
|
||||||
"hide_followers_description": "Jangan tampilkan siapa yang mengikutiku",
|
"hide_followers_description": "Jangan tampilkan siapa yang mengikutiku",
|
||||||
"hide_follows_count_description": "Jangan tampilkan jumlah mengikuti",
|
"hide_follows_count_description": "Jangan tampilkan jumlah mengikuti",
|
||||||
"hide_follows_description": "Jangan tampilkan siapa yang aku ikuti",
|
"hide_follows_description": "Jangan tampilkan siapa yang aku ikuti",
|
||||||
|
"hide_isp": "Sembunyikan panel spesifik instansi",
|
||||||
|
"hide_list_aliases_error_action": "Tutup",
|
||||||
|
"hide_media_previews": "Sembunyikan pratinjau media",
|
||||||
"hide_muted_posts": "Sembunyikan postingan-postingan dari pengguna yang dibisukan",
|
"hide_muted_posts": "Sembunyikan postingan-postingan dari pengguna yang dibisukan",
|
||||||
|
"hide_muted_threads": "Sembunyikan thread yang dibisukan",
|
||||||
"hide_post_stats": "Sembunyikan statistik postingan (seperti jumlah favorit)",
|
"hide_post_stats": "Sembunyikan statistik postingan (seperti jumlah favorit)",
|
||||||
"hide_shoutbox": "Sembunyikan kotak suara instansi",
|
"hide_shoutbox": "Sembunyikan kotak suara instansi",
|
||||||
|
"hide_site_favicon": "Sembunyikan favicon instansi di panel atas",
|
||||||
|
"hide_site_name": "Sembunyikan nama instansi di panel atas",
|
||||||
|
"hide_threads_with_blocked_users": "Sembunyikan thread yang menyebut orang yang diblok",
|
||||||
"hide_user_stats": "Sembunyikan statistik pengguna (seperti jumlah pengikut)",
|
"hide_user_stats": "Sembunyikan statistik pengguna (seperti jumlah pengikut)",
|
||||||
"hide_wallpaper": "Sembunyikan latar belakang instansi",
|
"hide_wallpaper": "Sembunyikan latar belakang instansi",
|
||||||
|
"hide_wordfiltered_statuses": "Sembunyikan post yang disaring dengan kata",
|
||||||
"import_blocks_from_a_csv_file": "Impor blokiran dari berkas csv",
|
"import_blocks_from_a_csv_file": "Impor blokiran dari berkas csv",
|
||||||
|
"import_followers_from_a_csv_file": "Impor daftar mengikuti dari berkas csv",
|
||||||
|
"import_mutes_from_a_csv_file": "Impor daftar pembisuan dari berkas csv",
|
||||||
|
"import_theme": "Muat preset",
|
||||||
|
"inputRadius": "Bidang masukan",
|
||||||
"instance_default": "(bawaan: {value})",
|
"instance_default": "(bawaan: {value})",
|
||||||
"instance_default_simple": "(bawaan)",
|
"instance_default_simple": "(bawaan)",
|
||||||
"interface": "Antarmuka",
|
"interface": "Antarmuka",
|
||||||
|
@ -581,16 +597,23 @@
|
||||||
"invalid_theme_imported": "Berkas yang dipilih bukan sebuah tema yang didukung Pleroma. Tidak ada perubahan yang dibuat pada tema kamu.",
|
"invalid_theme_imported": "Berkas yang dipilih bukan sebuah tema yang didukung Pleroma. Tidak ada perubahan yang dibuat pada tema kamu.",
|
||||||
"limited_availability": "Tidak tersedia di browser kamu",
|
"limited_availability": "Tidak tersedia di browser kamu",
|
||||||
"links": "Tautan",
|
"links": "Tautan",
|
||||||
|
"list_aliases_error": "Gagal mengambil alias: {error}",
|
||||||
|
"list_backups_error": "Gagal mengambil daftar cadangan: {error}",
|
||||||
"lock_account_description": "Batasi akunmu kepada pengikut yang sudah disetujui saja",
|
"lock_account_description": "Batasi akunmu kepada pengikut yang sudah disetujui saja",
|
||||||
"loop_video": "Ulang-ulang video",
|
"loop_video": "Ulang-ulang video",
|
||||||
"loop_video_silent_only": "Ulang-ulang video tanpa suara (seperti \"gif\" Mastodon)",
|
"loop_video_silent_only": "Ulang-ulang video tanpa suara (seperti \"gif\" Mastodon)",
|
||||||
|
"mascot": "Maskot Mastodon FE",
|
||||||
|
"max_depth_in_thread": "Tingat thread maksimum yang ditampilkan oleh bawaan",
|
||||||
"max_thumbnails": "Jumlah thumbnail maksimum per postingan (kosong = tidak terbatas)",
|
"max_thumbnails": "Jumlah thumbnail maksimum per postingan (kosong = tidak terbatas)",
|
||||||
"mention_link_bolden_you": "Sorot sebutan kamu apabila kamu disebut",
|
"mention_link_bolden_you": "Sorot sebutan kamu apabila kamu disebut",
|
||||||
"mention_link_display": "Tampilkan tautan sebutan",
|
"mention_link_display": "Tampilkan tautan sebutan",
|
||||||
"mention_link_display_full": "selalu sebagai nama lengkap (cth. {'@'}foo{'@'}example.org)",
|
"mention_link_display_full": "selalu sebagai nama lengkap (cth. {'@'}foo{'@'}example.org)",
|
||||||
"mention_link_display_full_for_remote": "sebagai nama lengkap hanya untuk pengguna di instansi lain (cth. {'@'}foo{'@'}example.org)",
|
"mention_link_display_full_for_remote": "sebagai nama lengkap hanya untuk pengguna di instansi lain (cth. {'@'}foo{'@'}example.org)",
|
||||||
"mention_link_display_short": "selalu sebagai nama pendek (cth. {'@'}foo)",
|
"mention_link_display_short": "selalu sebagai nama pendek (cth. {'@'}foo)",
|
||||||
|
"mention_link_fade_domain": "Pudarkan domain (contoh: {'@'}example.org di {'@'}foo{'@'}example.org)",
|
||||||
"mention_link_show_avatar": "Tampilkan avatar pengguna di samping tautan",
|
"mention_link_show_avatar": "Tampilkan avatar pengguna di samping tautan",
|
||||||
|
"mention_link_show_tooltip": "Tunjukkan nama penuh pengguna sebagai tooltip untuk pengguna jauh",
|
||||||
|
"mention_links": "Tautan sebutan",
|
||||||
"mfa": {
|
"mfa": {
|
||||||
"authentication_methods": "Metode otentikasi",
|
"authentication_methods": "Metode otentikasi",
|
||||||
"confirm_and_enable": "Konfirmasi & aktifkan OTP",
|
"confirm_and_enable": "Konfirmasi & aktifkan OTP",
|
||||||
|
@ -599,6 +622,8 @@
|
||||||
"recovery_codes": "Kode pemulihan.",
|
"recovery_codes": "Kode pemulihan.",
|
||||||
"recovery_codes_warning": "Tulis kodenya atau simpan mereka di tempat yang aman - jika tidak kamu tidak akan melihat mereka lagi. Jika kamu tidak dapat mengakses aplikasi 2FA kamu dan kode pemulihanmu hilang, kamu tidak akan bisa mengakses akun kamu.",
|
"recovery_codes_warning": "Tulis kodenya atau simpan mereka di tempat yang aman - jika tidak kamu tidak akan melihat mereka lagi. Jika kamu tidak dapat mengakses aplikasi 2FA kamu dan kode pemulihanmu hilang, kamu tidak akan bisa mengakses akun kamu.",
|
||||||
"scan": {
|
"scan": {
|
||||||
|
"desc": "Menggunakan aplikasi dua-faktor kamu, pindai kode QR ini atau masukkan kunci teks:",
|
||||||
|
"secret_code": "Kunci",
|
||||||
"title": "Pindai"
|
"title": "Pindai"
|
||||||
},
|
},
|
||||||
"setup_otp": "Siapkan OTP",
|
"setup_otp": "Siapkan OTP",
|
||||||
|
@ -606,10 +631,19 @@
|
||||||
"verify": {
|
"verify": {
|
||||||
"desc": "Untuk mengaktifkan otentikasi dua-faktor, masukkan kode dari aplikasi dua-faktor kamu:"
|
"desc": "Untuk mengaktifkan otentikasi dua-faktor, masukkan kode dari aplikasi dua-faktor kamu:"
|
||||||
},
|
},
|
||||||
|
"wait_pre_setup_otp": "Pengaturan awal OTP",
|
||||||
"waiting_a_recovery_codes": "Menerima kode cadangan…",
|
"waiting_a_recovery_codes": "Menerima kode cadangan…",
|
||||||
"warning_of_generate_new_codes": "Ketika kamu menghasilkan kode pemulihan baru, kode lama kamu berhenti bekerja."
|
"warning_of_generate_new_codes": "Ketika kamu menghasilkan kode pemulihan baru, kode lama kamu berhenti bekerja."
|
||||||
},
|
},
|
||||||
|
"minimal_scopes_mode": "Minimalkan pilihan seleksi lingkup posting",
|
||||||
"more_settings": "Lebih banyak pengaturan",
|
"more_settings": "Lebih banyak pengaturan",
|
||||||
|
"move_account": "Pindahkan akun",
|
||||||
|
"move_account_error": "Gagal memindahkan akun: {error}",
|
||||||
|
"move_account_notes": "Jika kamu ingin memindahkan akun ini ke tempat lain, kamu harus pergi ke akun tujuan kamu dan menambahkan alias yang mengarah ke sini.",
|
||||||
|
"move_account_target": "Akun tujuan (contoh {example})",
|
||||||
|
"moved_account": "Akun telah dipindahkan.",
|
||||||
|
"mute_bot_posts": "Bisukan posting dari bot",
|
||||||
|
"mute_export": "Expor pembisuan",
|
||||||
"mutes_and_blocks": "Bisuan dan Blokiran",
|
"mutes_and_blocks": "Bisuan dan Blokiran",
|
||||||
"name": "Nama",
|
"name": "Nama",
|
||||||
"name_bio": "Nama & bio",
|
"name_bio": "Nama & bio",
|
||||||
|
@ -699,7 +733,7 @@
|
||||||
"fine_print": "Baca {0} kami untuk belajar sesuatu yang tak ada gunanya!",
|
"fine_print": "Baca {0} kami untuk belajar sesuatu yang tak ada gunanya!",
|
||||||
"header": "Pratinjau",
|
"header": "Pratinjau",
|
||||||
"header_faint": "Ini baik-baik saja",
|
"header_faint": "Ini baik-baik saja",
|
||||||
"input": "Baru saja mendarat di L.A.",
|
"input": "Baru saja mendarat di Luna Nova Academy",
|
||||||
"link": "sebuah tautan yang kecil nan bagus"
|
"link": "sebuah tautan yang kecil nan bagus"
|
||||||
},
|
},
|
||||||
"shadows": {
|
"shadows": {
|
||||||
|
@ -720,15 +754,15 @@
|
||||||
"use_source": "Versi baru"
|
"use_source": "Versi baru"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"subject_line_behavior": "Salin subyek ketika membalas",
|
"subject_line_behavior": "Salin peringatan isi ketika membalas",
|
||||||
"subject_line_email": "Seperti surel: \"re: subyek\"",
|
"subject_line_email": "Seperti surel: \"re: peringatan\"",
|
||||||
"subject_line_mastodon": "Seperti mastodon: salin saja",
|
"subject_line_mastodon": "Seperti mastodon: salin saja",
|
||||||
"subject_line_noop": "Jangan salin",
|
"subject_line_noop": "Jangan salin",
|
||||||
"text": "Teks",
|
"text": "Teks",
|
||||||
"theme": "Tema",
|
"theme": "Tema",
|
||||||
"token": "Token",
|
"token": "Token",
|
||||||
"upload_a_photo": "Unggah foto",
|
"upload_a_photo": "Unggah foto",
|
||||||
"useStreamingApiWarning": "(Tidak disarankan, eksperimental, diketahui dapat melewati postingan-postingan)",
|
"useStreamingApiWarning": "Ini bagus, gunakan. Kalau tidak jalan, mungkin segarkan halaman?",
|
||||||
"use_one_click_nsfw": "Buka lampiran NSFW hanya dengan satu klik",
|
"use_one_click_nsfw": "Buka lampiran NSFW hanya dengan satu klik",
|
||||||
"user_settings": "Pengaturan Pengguna",
|
"user_settings": "Pengaturan Pengguna",
|
||||||
"valid_until": "Valid hingga",
|
"valid_until": "Valid hingga",
|
||||||
|
@ -744,7 +778,7 @@
|
||||||
"word_filter": "Penyaring kata"
|
"word_filter": "Penyaring kata"
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
"delete": "Hapus status",
|
"delete": "Hapus post",
|
||||||
"delete_confirm": "Apakah kamu benar-benar ingin menghapus postingan ini?",
|
"delete_confirm": "Apakah kamu benar-benar ingin menghapus postingan ini?",
|
||||||
"favorites": "Favorit",
|
"favorites": "Favorit",
|
||||||
"hide_content": "",
|
"hide_content": "",
|
||||||
|
@ -757,7 +791,7 @@
|
||||||
"reply_to": "Balas ke",
|
"reply_to": "Balas ke",
|
||||||
"show_content": "",
|
"show_content": "",
|
||||||
"status_deleted": "Postingan ini telah dihapus",
|
"status_deleted": "Postingan ini telah dihapus",
|
||||||
"status_unavailable": "Status tidak tersedia",
|
"status_unavailable": "Post tidak tersedia",
|
||||||
"thread_muted_and_words": ", memiliki kata:",
|
"thread_muted_and_words": ", memiliki kata:",
|
||||||
"unmute_conversation": "Berhenti membisikan percakapan",
|
"unmute_conversation": "Berhenti membisikan percakapan",
|
||||||
"unpin": "Berhenti menyematkan dari profil"
|
"unpin": "Berhenti menyematkan dari profil"
|
||||||
|
@ -787,9 +821,9 @@
|
||||||
"timeline": {
|
"timeline": {
|
||||||
"conversation": "Percakapan",
|
"conversation": "Percakapan",
|
||||||
"error": "Terjadi kesalahan memuat linimasa: {0}",
|
"error": "Terjadi kesalahan memuat linimasa: {0}",
|
||||||
"no_more_statuses": "Tidak ada status lagi",
|
"no_more_statuses": "Tidak ada post lagi",
|
||||||
"no_retweet_hint": "Postingan ditandai sebagai hanya-pengikut atau langsung dan tidak dapat diulang atau dikutip",
|
"no_retweet_hint": "Postingan ditandai sebagai hanya-pengikut atau langsung dan tidak dapat diulang atau dikutip",
|
||||||
"no_statuses": "Tidak ada status",
|
"no_statuses": "Tidak ada post",
|
||||||
"reload": "Muat ulang",
|
"reload": "Muat ulang",
|
||||||
"repeated": "diulangi"
|
"repeated": "diulangi"
|
||||||
},
|
},
|
||||||
|
@ -853,7 +887,7 @@
|
||||||
"per_day": "per hari",
|
"per_day": "per hari",
|
||||||
"report": "Laporkan",
|
"report": "Laporkan",
|
||||||
"show_repeats": "Tampilkan ulangan",
|
"show_repeats": "Tampilkan ulangan",
|
||||||
"statuses": "Status",
|
"statuses": "Postingan",
|
||||||
"unblock": "Berhenti memblokir",
|
"unblock": "Berhenti memblokir",
|
||||||
"unmute": "Berhenti membisukan"
|
"unmute": "Berhenti membisukan"
|
||||||
},
|
},
|
||||||
|
|
190
src/i18n/it.json
190
src/i18n/it.json
|
@ -1,5 +1,7 @@
|
||||||
{
|
{
|
||||||
"about": {
|
"about": {
|
||||||
|
"bubble_instances": "Istanze della Bolla Locale",
|
||||||
|
"bubble_instances_description": "Istanze selezionate dagli amministratori per rappresentare l'area d'interesse dell'istanza",
|
||||||
"mrf": {
|
"mrf": {
|
||||||
"federation": "Federazione",
|
"federation": "Federazione",
|
||||||
"keyword": {
|
"keyword": {
|
||||||
|
@ -16,12 +18,15 @@
|
||||||
"accept_desc": "Questa stanza accetta messaggi solo dalle seguenti altre:",
|
"accept_desc": "Questa stanza accetta messaggi solo dalle seguenti altre:",
|
||||||
"ftl_removal": "Rimozione dalla sequenza federale",
|
"ftl_removal": "Rimozione dalla sequenza federale",
|
||||||
"ftl_removal_desc": "Questa stanza rimuove le seguenti dalla sequenza federale:",
|
"ftl_removal_desc": "Questa stanza rimuove le seguenti dalla sequenza federale:",
|
||||||
|
"instance": "Istanza",
|
||||||
"media_nsfw": "Allegati oscurati d'ufficio",
|
"media_nsfw": "Allegati oscurati d'ufficio",
|
||||||
"media_nsfw_desc": "Questa stanza oscura gli allegati dei messaggi provenienti da queste stanze:",
|
"media_nsfw_desc": "Questa stanza oscura gli allegati dei messaggi provenienti da queste stanze:",
|
||||||
"media_removal": "Rimozione multimedia",
|
"media_removal": "Rimozione multimedia",
|
||||||
"media_removal_desc": "Questa istanza rimuove gli allegati dalle seguenti stanze:",
|
"media_removal_desc": "Questa istanza rimuove gli allegati dalle seguenti stanze:",
|
||||||
|
"not_applicable": "N/D",
|
||||||
"quarantine": "Quarantena",
|
"quarantine": "Quarantena",
|
||||||
"quarantine_desc": "Questa stanza inoltrerà solo messaggi pubblici alle seguenti:",
|
"quarantine_desc": "Questa istanza non invierà post alle seguenti istanze:",
|
||||||
|
"reason": "Motivazione",
|
||||||
"reject": "Rifiuta",
|
"reject": "Rifiuta",
|
||||||
"reject_desc": "Questa stanza rifiuterà i messaggi provenienti dalle seguenti:",
|
"reject_desc": "Questa stanza rifiuterà i messaggi provenienti dalle seguenti:",
|
||||||
"simple_policies": "Regole specifiche alla stanza"
|
"simple_policies": "Regole specifiche alla stanza"
|
||||||
|
@ -29,6 +34,27 @@
|
||||||
},
|
},
|
||||||
"staff": "Responsabili"
|
"staff": "Responsabili"
|
||||||
},
|
},
|
||||||
|
"announcements": {
|
||||||
|
"all_day_prompt": "Evento lungo tutto il giorno",
|
||||||
|
"cancel_edit_action": "Annulla",
|
||||||
|
"close_error": "Chiudi",
|
||||||
|
"delete_action": "Elimina",
|
||||||
|
"edit_action": "Modifica",
|
||||||
|
"end_time_display": "Finisce alle {time}",
|
||||||
|
"end_time_prompt": "Ora di fine: ",
|
||||||
|
"inactive_message": "Questo annuncio è inattivo",
|
||||||
|
"mark_as_read_action": "Segna come già letto",
|
||||||
|
"page_header": "Annunci",
|
||||||
|
"post_action": "Post",
|
||||||
|
"post_error": "Errore: {error}",
|
||||||
|
"post_form_header": "Posta annuncio",
|
||||||
|
"post_placeholder": "Contenuto dell'annuncio",
|
||||||
|
"published_time_display": "Pubblicato alle {time}",
|
||||||
|
"start_time_display": "Inizia alle {time}",
|
||||||
|
"start_time_prompt": "Ora di inizio: ",
|
||||||
|
"submit_edit_action": "Invia",
|
||||||
|
"title": "Annuncio"
|
||||||
|
},
|
||||||
"chats": {
|
"chats": {
|
||||||
"chats": "Conversazioni",
|
"chats": "Conversazioni",
|
||||||
"delete": "Elimina",
|
"delete": "Elimina",
|
||||||
|
@ -58,6 +84,7 @@
|
||||||
"keep_open": "Tieni aperto il menù",
|
"keep_open": "Tieni aperto il menù",
|
||||||
"load_all": "Carico tutti i {emojiAmount} emoji",
|
"load_all": "Carico tutti i {emojiAmount} emoji",
|
||||||
"load_all_hint": "Primi {saneAmount} emoji caricati, caricarli tutti potrebbe causare rallentamenti.",
|
"load_all_hint": "Primi {saneAmount} emoji caricati, caricarli tutti potrebbe causare rallentamenti.",
|
||||||
|
"recent": "Usato di recente",
|
||||||
"search_emoji": "Cerca un emoji",
|
"search_emoji": "Cerca un emoji",
|
||||||
"stickers": "Adesivi",
|
"stickers": "Adesivi",
|
||||||
"unicode": "Emoji Unicode"
|
"unicode": "Emoji Unicode"
|
||||||
|
@ -109,6 +136,13 @@
|
||||||
"admin": "Amministratore",
|
"admin": "Amministratore",
|
||||||
"moderator": "Moderatore"
|
"moderator": "Moderatore"
|
||||||
},
|
},
|
||||||
|
"scope_in_timeline": {
|
||||||
|
"direct": "Diretto",
|
||||||
|
"local": "Locale - Solo la tua istanza può vedere questo post",
|
||||||
|
"private": "Solo per i seguaci",
|
||||||
|
"public": "Pubblico",
|
||||||
|
"unlisted": "Non elencato"
|
||||||
|
},
|
||||||
"show_less": "Ripiega",
|
"show_less": "Ripiega",
|
||||||
"show_more": "Mostra tutto",
|
"show_more": "Mostra tutto",
|
||||||
"submit": "Invia",
|
"submit": "Invia",
|
||||||
|
@ -131,6 +165,84 @@
|
||||||
"load_older": "Carica interazioni precedenti",
|
"load_older": "Carica interazioni precedenti",
|
||||||
"moves": "Utenti migrati"
|
"moves": "Utenti migrati"
|
||||||
},
|
},
|
||||||
|
"languages": {
|
||||||
|
"ar": "Arabo",
|
||||||
|
"az": "Azero",
|
||||||
|
"bg": "Bulgaro",
|
||||||
|
"cs": "Ceco",
|
||||||
|
"da": "Danese",
|
||||||
|
"de": "Tedesco",
|
||||||
|
"el": "Greco",
|
||||||
|
"en": "Inglese",
|
||||||
|
"eo": "Esperanto",
|
||||||
|
"es": "Spagnolo",
|
||||||
|
"fa": "Persiano",
|
||||||
|
"fi": "Finlandese",
|
||||||
|
"fr": "Francese",
|
||||||
|
"ga": "Irlandese",
|
||||||
|
"he": "Ebreo",
|
||||||
|
"hi": "Hindi",
|
||||||
|
"hu": "Ungherese",
|
||||||
|
"id": "Indonesiano",
|
||||||
|
"it": "Italiano",
|
||||||
|
"ja": "Giapponese",
|
||||||
|
"ko": "Coreano",
|
||||||
|
"lt": "Lituano",
|
||||||
|
"lv": "Lettone",
|
||||||
|
"nl": "Olandese",
|
||||||
|
"pl": "Polacco",
|
||||||
|
"pt": "Portoghese",
|
||||||
|
"ru": "Russo",
|
||||||
|
"sk": "Slovacco",
|
||||||
|
"sv": "Svedese",
|
||||||
|
"tr": "Turco",
|
||||||
|
"translated_from": {
|
||||||
|
"ar": "Tradotto dall' @:languages.ar",
|
||||||
|
"az": "Tradotto dall' @:languages.az",
|
||||||
|
"bg": "Tradotto dal @:languages.bg",
|
||||||
|
"cs": "Tradotto dal @:languages.cs",
|
||||||
|
"da": "Tradotto dal @:languages.da",
|
||||||
|
"de": "Tradotto dal @:languages.de",
|
||||||
|
"el": "Tradotto dal @:languages.el",
|
||||||
|
"en": "Tradotto dall' @:languages.en",
|
||||||
|
"eo": "Tradotto dal @:languages.eo",
|
||||||
|
"es": "Tradotto dallo @:languages.es",
|
||||||
|
"fa": "Tradotto dal @:languages.fa",
|
||||||
|
"fi": "Tradotto dal @:languages.fi",
|
||||||
|
"fr": "Tradotto dal @:languages.fr",
|
||||||
|
"ga": "Tradotto dal @:languages.ga",
|
||||||
|
"he": "Tradotto dal @:languages.he",
|
||||||
|
"hi": "Tradotto dal @:languages.hi",
|
||||||
|
"hu": "Tradotto dal @:languages.hu",
|
||||||
|
"id": "Tradotto dal @:languages.id",
|
||||||
|
"it": "Tradotto dall' @:languages.it",
|
||||||
|
"ja": "Tradotto dal @:languages.ja",
|
||||||
|
"ko": "Tradotto dal @:languages.ko",
|
||||||
|
"lt": "Tradotto dal @:languages.lt",
|
||||||
|
"lv": "Tradotto dal @:languages.lv",
|
||||||
|
"nl": "Tradotto dall' @:languages.nl",
|
||||||
|
"pl": "Tradotto dal @:languages.pl",
|
||||||
|
"pt": "Tradotto dal @:languages.pt",
|
||||||
|
"ru": "Tradotto dal @:languages.ru",
|
||||||
|
"sk": "Tradotto dal @:languages.sk",
|
||||||
|
"sv": "Tradotto dal @:languages.sv",
|
||||||
|
"tr": "Tradotto dal @:languages.tr",
|
||||||
|
"uk": "Tradotto dal @:languages.uk",
|
||||||
|
"zh": "Tradotto dal @:languages.zh"
|
||||||
|
},
|
||||||
|
"uk": "Ucraino",
|
||||||
|
"zh": "Cinese"
|
||||||
|
},
|
||||||
|
"lists": {
|
||||||
|
"create": "Crea",
|
||||||
|
"delete": "Elimina lista",
|
||||||
|
"following_only": "Limita a chi segui",
|
||||||
|
"lists": "Liste",
|
||||||
|
"new": "Nuova Lista",
|
||||||
|
"save": "Salva cambiamenti",
|
||||||
|
"search": "Cerca utenti",
|
||||||
|
"title": "Titolo della lista"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"authentication_code": "Codice di autenticazione",
|
"authentication_code": "Codice di autenticazione",
|
||||||
"description": "Accedi con OAuth",
|
"description": "Accedi con OAuth",
|
||||||
|
@ -143,6 +255,10 @@
|
||||||
"hint": "Accedi per conversare",
|
"hint": "Accedi per conversare",
|
||||||
"login": "Accedi",
|
"login": "Accedi",
|
||||||
"logout": "Disconnettiti",
|
"logout": "Disconnettiti",
|
||||||
|
"logout_confirm": "Sicuro di disconnetterti?",
|
||||||
|
"logout_confirm_accept_button": "Disconnetti",
|
||||||
|
"logout_confirm_cancel_button": "Annulla",
|
||||||
|
"logout_confirm_title": "Disconnetti",
|
||||||
"password": "Password",
|
"password": "Password",
|
||||||
"placeholder": "es. Lupo Lucio",
|
"placeholder": "es. Lupo Lucio",
|
||||||
"recovery_code": "Codice di recupero",
|
"recovery_code": "Codice di recupero",
|
||||||
|
@ -150,31 +266,67 @@
|
||||||
"username": "Nome utente"
|
"username": "Nome utente"
|
||||||
},
|
},
|
||||||
"media_modal": {
|
"media_modal": {
|
||||||
|
"counter": "{current} / {total}",
|
||||||
|
"hide": "Chiudi visualizzatore multimediale",
|
||||||
"next": "Prossimo",
|
"next": "Prossimo",
|
||||||
"previous": "Precedente"
|
"previous": "Precedente"
|
||||||
},
|
},
|
||||||
|
"moderation": {
|
||||||
|
"moderation": "Moderazione",
|
||||||
|
"reports": {
|
||||||
|
"add_note": "Aggiungi nota",
|
||||||
|
"close": "Chiudi",
|
||||||
|
"delete_note": "Elimina",
|
||||||
|
"delete_note_accept": "Si, eliminalo",
|
||||||
|
"delete_note_cancel": "No, lascialo stare",
|
||||||
|
"delete_note_confirm": "Sei sicurə di voler eliminare questa nota?",
|
||||||
|
"delete_note_title": "Conferma eliminazione",
|
||||||
|
"no_content": "Nessuna descrizione",
|
||||||
|
"no_reports": "Nessun report da mostrare",
|
||||||
|
"note_placeholder": "Lascia una nota",
|
||||||
|
"notes": "{ count } nota | { count } note",
|
||||||
|
"reopen": "Riapri",
|
||||||
|
"report": "Riporta su",
|
||||||
|
"reports": "Rapporti",
|
||||||
|
"resolve": "Risolvi",
|
||||||
|
"show_closed": "Mostra chiusi",
|
||||||
|
"statuses": "{ count } post| { count } post",
|
||||||
|
"tag_policy_notice": "Abilita il TagPolicy MRF per poter impostare restrizioni sui post",
|
||||||
|
"tags": "Imposta restrizioni sui post"
|
||||||
|
},
|
||||||
|
"statuses": "Post",
|
||||||
|
"users": "Utenti"
|
||||||
|
},
|
||||||
"nav": {
|
"nav": {
|
||||||
"about": "Informazioni",
|
"about": "Informazioni",
|
||||||
"administration": "Amministrazione",
|
"administration": "Amministrazione",
|
||||||
|
"announcements": "Annunci",
|
||||||
"back": "Indietro",
|
"back": "Indietro",
|
||||||
"bookmarks": "Segnalibri",
|
"bookmarks": "Segnalibri",
|
||||||
|
"bubble_timeline": "Timeline della Bolla Locale",
|
||||||
|
"bubble_timeline_description": "Post da istanze vicine alla tua e raccomandate dagli amministratori",
|
||||||
"chats": "Conversazioni",
|
"chats": "Conversazioni",
|
||||||
"dms": "Messaggi privati",
|
"dms": "Messaggi privati",
|
||||||
"friend_requests": "Vogliono seguirti",
|
"friend_requests": "Vogliono seguirti",
|
||||||
"home_timeline": "Sequenza personale",
|
"home_timeline": "Sequenza personale",
|
||||||
|
"home_timeline_description": "Post dalle persone che segui",
|
||||||
"interactions": "Interazioni",
|
"interactions": "Interazioni",
|
||||||
|
"lists": "Liste",
|
||||||
"mentions": "Menzioni",
|
"mentions": "Menzioni",
|
||||||
|
"moderation": "Moderazione",
|
||||||
"preferences": "Preferenze",
|
"preferences": "Preferenze",
|
||||||
|
"public_timeline_description": "Post pubblici da questa istanza",
|
||||||
"public_tl": "Sequenza pubblica",
|
"public_tl": "Sequenza pubblica",
|
||||||
"search": "Ricerca",
|
"search": "Ricerca",
|
||||||
"timeline": "Sequenza personale",
|
"timeline": "Sequenza personale",
|
||||||
"timelines": "Sequenze",
|
"timelines": "Sequenze",
|
||||||
"twkn": "Sequenza federale",
|
"twkn": "Sequenza federale",
|
||||||
|
"twkn_timeline_description": "Post da tutta la rete",
|
||||||
"user_search": "Ricerca utenti",
|
"user_search": "Ricerca utenti",
|
||||||
"who_to_follow": "Chi seguire"
|
"who_to_follow": "Chi seguire"
|
||||||
},
|
},
|
||||||
"notifications": {
|
"notifications": {
|
||||||
"broken_favorite": "Stato sconosciuto, lo sto cercando…",
|
"broken_favorite": "Post sconosciuto, lo sto cercando…",
|
||||||
"error": "Errore nel caricare le notifiche: {0}",
|
"error": "Errore nel caricare le notifiche: {0}",
|
||||||
"favorited_you": "ha gradito",
|
"favorited_you": "ha gradito",
|
||||||
"follow_request": "vuole seguirti",
|
"follow_request": "vuole seguirti",
|
||||||
|
@ -183,9 +335,10 @@
|
||||||
"migrated_to": "è migrato verso",
|
"migrated_to": "è migrato verso",
|
||||||
"no_more_notifications": "Fine delle notifiche",
|
"no_more_notifications": "Fine delle notifiche",
|
||||||
"notifications": "Notifiche",
|
"notifications": "Notifiche",
|
||||||
|
"poll_ended": "sondaggio terminato",
|
||||||
"reacted_with": "ha reagito con {0}",
|
"reacted_with": "ha reagito con {0}",
|
||||||
"read": "Letto!",
|
"read": "Letto!",
|
||||||
"repeated_you": "ha condiviso il tuo messaggio"
|
"repeated_you": "ha condiviso il tuo post"
|
||||||
},
|
},
|
||||||
"password_reset": {
|
"password_reset": {
|
||||||
"check_email": "Controlla la tua posta elettronica.",
|
"check_email": "Controlla la tua posta elettronica.",
|
||||||
|
@ -223,15 +376,20 @@
|
||||||
"text/bbcode": "BBCode",
|
"text/bbcode": "BBCode",
|
||||||
"text/html": "HTML",
|
"text/html": "HTML",
|
||||||
"text/markdown": "Markdown",
|
"text/markdown": "Markdown",
|
||||||
"text/plain": "Testo normale"
|
"text/plain": "Testo normale",
|
||||||
|
"text/x.misskeymarkdown": "MFM"
|
||||||
},
|
},
|
||||||
"content_warning": "Oggetto (facoltativo)",
|
"content_warning": "Contenuto Sensibile (facoltativo)",
|
||||||
"default": "Sono appena atterrato a Città Laggiù.",
|
"default": "Sono appena atterrato a Città Laggiù.",
|
||||||
"direct_warning_to_all": "Questo messaggio sarà visibile a tutti i menzionati.",
|
"direct_warning_to_all": "Questo messaggio sarà visibile a tutti i menzionati.",
|
||||||
"direct_warning_to_first_only": "Questo messaggio sarà visibile solo agli utenti menzionati in testa.",
|
"direct_warning_to_first_only": "Questo messaggio sarà visibile solo agli utenti menzionati in testa.",
|
||||||
|
"edit_remote_warning": "Le modifiche fatte al messaggio potrebbero non essere visibili su alcune istanze!",
|
||||||
|
"edit_status": "Modifica Stato",
|
||||||
|
"edit_unsupported_warning": "Sondaggi e menzioni non verranno cambiati in fase di modifica.",
|
||||||
"empty_status_error": "Aggiungi del testo o degli allegati",
|
"empty_status_error": "Aggiungi del testo o degli allegati",
|
||||||
"media_description": "Descrizione allegati",
|
"media_description": "Descrizione allegati",
|
||||||
"media_description_error": "Allegati non caricati, riprova",
|
"media_description_error": "Allegati non caricati, riprova",
|
||||||
|
"media_not_sensitive_warning": "C'è un Contenuto Sensibile, ma gli allegati non sono contrassegnati come sensibili!",
|
||||||
"new_status": "Nuovo messaggio",
|
"new_status": "Nuovo messaggio",
|
||||||
"post": "Pubblica",
|
"post": "Pubblica",
|
||||||
"posting": "Sto pubblicando",
|
"posting": "Sto pubblicando",
|
||||||
|
@ -239,21 +397,26 @@
|
||||||
"preview_empty": "Vuoto",
|
"preview_empty": "Vuoto",
|
||||||
"scope": {
|
"scope": {
|
||||||
"direct": "Diretto - Visibile solo agli utenti menzionati",
|
"direct": "Diretto - Visibile solo agli utenti menzionati",
|
||||||
|
"local": "Locale - non federare questo messaggio",
|
||||||
"private": "Solo per seguaci - Visibile solo dai tuoi seguaci",
|
"private": "Solo per seguaci - Visibile solo dai tuoi seguaci",
|
||||||
"public": "Pubblico - Visibile sulla sequenza pubblica",
|
"public": "Pubblico - Visibile sulla sequenza pubblica",
|
||||||
"unlisted": "Nascosto - Non visibile sulla sequenza pubblica"
|
"unlisted": "Nascosto - Non visibile sulla sequenza pubblica"
|
||||||
},
|
},
|
||||||
"scope_notice": {
|
"scope_notice": {
|
||||||
|
"local": "Questo messaggio non sarà visibile sulle altre istanze",
|
||||||
"private": "Questo messaggio sarà visibile solo ai tuoi seguaci",
|
"private": "Questo messaggio sarà visibile solo ai tuoi seguaci",
|
||||||
"public": "Questo messaggio sarà visibile a tutti",
|
"public": "Questo messaggio sarà visibile a tutti",
|
||||||
"unlisted": "Questo messaggio non sarà visibile sulla sequenza locale né su quella pubblica"
|
"unlisted": "Questo messaggio non sarà visibile sulla sequenza locale né su quella pubblica"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"registration": {
|
"registration": {
|
||||||
|
"awaiting_email_confirmation": "Il tuo account è stato registrato e un'email è stata inviata al tuo indirizzo. Controllala per completare la registrazione.",
|
||||||
|
"awaiting_email_confirmation_title": "Attendo la conferma dell'email",
|
||||||
"bio": "Introduzione",
|
"bio": "Introduzione",
|
||||||
"bio_placeholder": "es.\nCiao, sono Lupo Lucio.\nSono un lupo fantastico che vive nel Fantabosco. Forse mi hai visto alla Melevisione.",
|
"bio_placeholder": "es.\nCiao, sono Lupo Lucio.\nSono un lupo fantastico che vive nel Fantabosco. Forse mi hai visto alla Melevisione.",
|
||||||
"captcha": "CAPTCHA",
|
"captcha": "CAPTCHA",
|
||||||
"email": "Email",
|
"email": "Email",
|
||||||
|
"email_language": "In quale lingua vuoi ricevere email dal server?",
|
||||||
"fullname": "Nome visualizzato",
|
"fullname": "Nome visualizzato",
|
||||||
"fullname_placeholder": "es. Lupo Lucio",
|
"fullname_placeholder": "es. Lupo Lucio",
|
||||||
"new_captcha": "Clicca il captcha per averne uno nuovo",
|
"new_captcha": "Clicca il captcha per averne uno nuovo",
|
||||||
|
@ -262,6 +425,8 @@
|
||||||
"reason_placeholder": "L'amministratore esamina ciascuna richiesta.\nFornisci il motivo della tua iscrizione.",
|
"reason_placeholder": "L'amministratore esamina ciascuna richiesta.\nFornisci il motivo della tua iscrizione.",
|
||||||
"register": "Registrati",
|
"register": "Registrati",
|
||||||
"registration": "Registrazione",
|
"registration": "Registrazione",
|
||||||
|
"request_sent": "La richiesta di registrazione è stata inoltrata ad un amministratore. Riceverai un'email non appena il tuo account verrà approvato.",
|
||||||
|
"request_sent_title": "Richiesta di registrazione inviata",
|
||||||
"token": "Codice d'invito",
|
"token": "Codice d'invito",
|
||||||
"username_placeholder": "es. mister_wolf",
|
"username_placeholder": "es. mister_wolf",
|
||||||
"validations": {
|
"validations": {
|
||||||
|
@ -290,6 +455,17 @@
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"accent": "Accento",
|
"accent": "Accento",
|
||||||
|
"account_alias": "Alias dell'account",
|
||||||
|
"account_alias_table_head": "Alias",
|
||||||
|
"account_backup": "Backup dell'account",
|
||||||
|
"account_backup_description": "Puoi scaricare un archivio con le tue informazioni ed i tuoi messaggi, ma non possono essere importati in un account Akkoma.",
|
||||||
|
"account_backup_table_head": "Backup",
|
||||||
|
"account_privacy": "Privacy",
|
||||||
|
"add_alias_error": "Errore durante l'aggiunta dell'alias: {error}",
|
||||||
|
"add_backup": "Crea un nuovo backup",
|
||||||
|
"add_backup_error": "Errore durante l'aggiunta di un nuovo backup: {error}",
|
||||||
|
"added_alias": "Alias aggiunto.",
|
||||||
|
"added_backup": "Nuovo backup aggiunto.",
|
||||||
"allow_following_move": "Consenti l'iscrizione automatica ai profili traslocati",
|
"allow_following_move": "Consenti l'iscrizione automatica ai profili traslocati",
|
||||||
"always_show_post_button": "Non nascondere il pulsante di composizione",
|
"always_show_post_button": "Non nascondere il pulsante di composizione",
|
||||||
"app_name": "Nome applicazione",
|
"app_name": "Nome applicazione",
|
||||||
|
@ -301,6 +477,7 @@
|
||||||
"avatarRadius": "Icone utente",
|
"avatarRadius": "Icone utente",
|
||||||
"avatar_size_instruction": "La taglia minima per l'icona personale è 150x150 pixel.",
|
"avatar_size_instruction": "La taglia minima per l'icona personale è 150x150 pixel.",
|
||||||
"background": "Sfondo",
|
"background": "Sfondo",
|
||||||
|
"backup_not_ready": "Questo backup non è ancora pronto.",
|
||||||
"bio": "Introduzione",
|
"bio": "Introduzione",
|
||||||
"block_export": "Esporta blocchi",
|
"block_export": "Esporta blocchi",
|
||||||
"block_export_button": "Esporta i tuoi blocchi in un file CSV",
|
"block_export_button": "Esporta i tuoi blocchi in un file CSV",
|
||||||
|
@ -322,7 +499,8 @@
|
||||||
"changed_password": "Password cambiata correttamente!",
|
"changed_password": "Password cambiata correttamente!",
|
||||||
"chatMessageRadius": "Messaggi istantanei",
|
"chatMessageRadius": "Messaggi istantanei",
|
||||||
"checkboxRadius": "Caselle di selezione",
|
"checkboxRadius": "Caselle di selezione",
|
||||||
"collapse_subject": "Ripiega messaggi con oggetto",
|
"collapse_subject": "Ripiega messaggi con Contenuto Sensibile",
|
||||||
|
"columns": "Colonne",
|
||||||
"composing": "Composizione",
|
"composing": "Composizione",
|
||||||
"confirm_new_password": "Conferma la nuova password",
|
"confirm_new_password": "Conferma la nuova password",
|
||||||
"current_avatar": "La tua icona attuale",
|
"current_avatar": "La tua icona attuale",
|
||||||
|
|
11
src/i18n/ja.json
Normal file
11
src/i18n/ja.json
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"about": {
|
||||||
|
"mrf": {
|
||||||
|
"keyword": {
|
||||||
|
"is_replaced_by": "→",
|
||||||
|
"replace": "置き換える"
|
||||||
|
},
|
||||||
|
"mrf_policies": "有効なMRFポリシー"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -523,7 +523,7 @@
|
||||||
"delete_account_description": "あなたのアカウントとメッセージが、きえます。",
|
"delete_account_description": "あなたのアカウントとメッセージが、きえます。",
|
||||||
"delete_account_error": "アカウントをけすことが、できなかったかもしれません。インスタンスのアドミニストレーターに、おといあわせください。",
|
"delete_account_error": "アカウントをけすことが、できなかったかもしれません。インスタンスのアドミニストレーターに、おといあわせください。",
|
||||||
"delete_account_instructions": "ほんとうにアカウントをけしてもいいなら、パスワードをかいてください。",
|
"delete_account_instructions": "ほんとうにアカウントをけしてもいいなら、パスワードをかいてください。",
|
||||||
"disable_sticky_headers": "カラムヘッダーを、がめんのいちばんうえにくっつけない",
|
"disable_sticky_headers": "カラムヘッダーをがめんのいちばんうえにくっつけない",
|
||||||
"discoverable": "けんさくなどのサービスで、このアカウントをみつけてもよい",
|
"discoverable": "けんさくなどのサービスで、このアカウントをみつけてもよい",
|
||||||
"domain_mutes": "ドメイン",
|
"domain_mutes": "ドメイン",
|
||||||
"download_backup": "ダウンロード",
|
"download_backup": "ダウンロード",
|
||||||
|
|
|
@ -921,7 +921,6 @@
|
||||||
"upload_a_photo": "画像をアップロード",
|
"upload_a_photo": "画像をアップロード",
|
||||||
"useStreamingApi": "投稿と通知を、すぐに受け取る",
|
"useStreamingApi": "投稿と通知を、すぐに受け取る",
|
||||||
"useStreamingApiWarning": "(実験中で、投稿を取りこぼすかもしれないので、おすすめしません)",
|
"useStreamingApiWarning": "(実験中で、投稿を取りこぼすかもしれないので、おすすめしません)",
|
||||||
"use_at_icon": "{'@'}マークをアイコンにする",
|
|
||||||
"use_contain_fit": "画像のサムネイルを、切り抜かない",
|
"use_contain_fit": "画像のサムネイルを、切り抜かない",
|
||||||
"use_one_click_nsfw": "NSFWなファイルを1クリックで開く",
|
"use_one_click_nsfw": "NSFWなファイルを1クリックで開く",
|
||||||
"user_mutes": "ユーザー",
|
"user_mutes": "ユーザー",
|
||||||
|
|
|
@ -21,6 +21,7 @@ const loaders = {
|
||||||
ga: () => import('./ga.json'),
|
ga: () => import('./ga.json'),
|
||||||
he: () => import('./he.json'),
|
he: () => import('./he.json'),
|
||||||
hu: () => import('./hu.json'),
|
hu: () => import('./hu.json'),
|
||||||
|
id: () => import('./id.json'),
|
||||||
it: () => import('./it.json'),
|
it: () => import('./it.json'),
|
||||||
ja: () => import('./ja_pedantic.json'),
|
ja: () => import('./ja_pedantic.json'),
|
||||||
ja_easy: () => import('./ja_easy.json'),
|
ja_easy: () => import('./ja_easy.json'),
|
||||||
|
@ -35,6 +36,7 @@ const loaders = {
|
||||||
sk: () => import('./sk.json'),
|
sk: () => import('./sk.json'),
|
||||||
te: () => import('./te.json'),
|
te: () => import('./te.json'),
|
||||||
uk: () => import('./uk.json'),
|
uk: () => import('./uk.json'),
|
||||||
|
vi: () => import('./vi.json'),
|
||||||
zh: () => import('./zh.json'),
|
zh: () => import('./zh.json'),
|
||||||
zh_Hant: () => import('./zh_Hant.json')
|
zh_Hant: () => import('./zh_Hant.json')
|
||||||
}
|
}
|
||||||
|
|
|
@ -918,7 +918,6 @@
|
||||||
"upload_a_photo": "Foto uploaden",
|
"upload_a_photo": "Foto uploaden",
|
||||||
"useStreamingApi": "Berichten en meldingen in real-time ontvangen",
|
"useStreamingApi": "Berichten en meldingen in real-time ontvangen",
|
||||||
"useStreamingApiWarning": "Iets experimenteels met berichten streamen uwu miss kun je beter uit laten ofzo?",
|
"useStreamingApiWarning": "Iets experimenteels met berichten streamen uwu miss kun je beter uit laten ofzo?",
|
||||||
"use_at_icon": "{'@'} symbool als icoon tonen in plaats van tekst",
|
|
||||||
"use_blurhash": "Waas tonen over NSFW-miniaturen",
|
"use_blurhash": "Waas tonen over NSFW-miniaturen",
|
||||||
"use_contain_fit": "Bijlage in miniaturen niet bijsnijden",
|
"use_contain_fit": "Bijlage in miniaturen niet bijsnijden",
|
||||||
"use_one_click_nsfw": "Gevoelige bijlagen met slechts één klik openen",
|
"use_one_click_nsfw": "Gevoelige bijlagen met slechts één klik openen",
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue