Add gettext-based translations
Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
This commit is contained in:
Родитель
9aa29623f8
Коммит
bd268e3d0e
|
@ -7,7 +7,8 @@ module.exports = {
|
||||||
jest: true
|
jest: true
|
||||||
},
|
},
|
||||||
globals: {
|
globals: {
|
||||||
SCOPE_VERSION: true
|
SCOPE_VERSION: true,
|
||||||
|
TRANSLATIONS: true
|
||||||
},
|
},
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
parser: 'babel-eslint',
|
parser: 'babel-eslint',
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
name: L10n
|
||||||
|
on: pull_request
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
l10n-extract-check:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Pot check
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@master
|
||||||
|
- name: Set up Node
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: 12.x
|
||||||
|
- name: npm install
|
||||||
|
run: npm ci
|
||||||
|
- name: extract l10n files
|
||||||
|
run: npm run l10n:extract
|
||||||
|
- name: Check l10n file changes
|
||||||
|
run: bash -c "[[ ! \"`git status --porcelain l10n`\" ]] || ( echo 'Uncommited l10n changes. Run `npm l10n:extract`.' && git status && exit 1 )"
|
|
@ -0,0 +1,21 @@
|
||||||
|
name: Transifex
|
||||||
|
on: pull_request
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
approve:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Approve
|
||||||
|
steps:
|
||||||
|
- uses: hmarr/auto-approve-action@v2.0.0
|
||||||
|
if: github.actor == 'Transifex-localization-platform[bot]' || github.actor == 'transifex-integration[bot]'
|
||||||
|
with:
|
||||||
|
github-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
|
automerge:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Auto-merge
|
||||||
|
steps:
|
||||||
|
- uses: "pascalgn/automerge-action@ecb16453ce68e85b1e23596c8caa7e7499698a84"
|
||||||
|
if: github.actor == 'Transifex-localization-platform[bot]' || github.actor == 'transifex-integration[bot]'
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
|
MERGE_LABELS: ""
|
|
@ -1 +1,3 @@
|
||||||
node_modules
|
/build
|
||||||
|
/l10n
|
||||||
|
/node_modules
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
const { GettextExtractor, JsExtractors } = require('gettext-extractor');
|
||||||
|
|
||||||
|
let extractor = new GettextExtractor();
|
||||||
|
|
||||||
|
extractor
|
||||||
|
.createJsParser([
|
||||||
|
JsExtractors.callExpression('t', {
|
||||||
|
arguments: {
|
||||||
|
text: 0,
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
JsExtractors.callExpression('n', {
|
||||||
|
arguments: {
|
||||||
|
text: 1,
|
||||||
|
textPlural: 2,
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
.parseFilesGlob('./src/**/*.@(ts|js|vue)');
|
||||||
|
|
||||||
|
extractor.savePotFile('./l10n/messages.pot');
|
||||||
|
|
||||||
|
extractor.printStats();
|
|
@ -0,0 +1,48 @@
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
|
||||||
|
#: src/components/MultiselectTags/MultiselectTags.vue:169
|
||||||
|
msgid "{tag} (invisible)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/MultiselectTags/MultiselectTags.vue:172
|
||||||
|
msgid "{tag} (restricted)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/ColorPicker/ColorPicker.vue:145
|
||||||
|
msgid "Choose"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/Modal/Modal.vue:109
|
||||||
|
msgid "Close"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/Modal/Modal.vue:154
|
||||||
|
msgid "Next"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/Multiselect/Multiselect.vue:169
|
||||||
|
#: src/components/MultiselectTags/MultiselectTags.vue:78
|
||||||
|
msgid "No results"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/Modal/Modal.vue:290
|
||||||
|
msgid "Pause slideshow"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/Modal/Modal.vue:134
|
||||||
|
msgid "Previous"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/MultiselectTags/MultiselectTags.vue:100
|
||||||
|
msgid "Select a tag"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/AppNavigationSettings/AppNavigationSettings.vue:53
|
||||||
|
msgid "Settings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/Modal/Modal.vue:290
|
||||||
|
msgid "Start slideshow"
|
||||||
|
msgstr ""
|
|
@ -3022,6 +3022,15 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@nextcloud/l10n": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@nextcloud/l10n/-/l10n-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-MywbaSb31JH5LNUsC98RrMwzHdsjDELf+nL5BVtHBQWq2r0cDP0nPd7Ve+knRVdGMegnigXW+F2VXbxFBLb6mQ==",
|
||||||
|
"requires": {
|
||||||
|
"core-js": "3.6.4",
|
||||||
|
"node-gettext": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@nextcloud/router": {
|
"@nextcloud/router": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@nextcloud/router/-/router-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@nextcloud/router/-/router-1.0.0.tgz",
|
||||||
|
@ -3186,6 +3195,12 @@
|
||||||
"integrity": "sha512-Zq8gcQGmn4txQEJeiXo/KiLpon8TzAl0kmKH4zdWctPj05nWwp1ClMdAVEloqrQKfaC48PNLdgN/aVaLqUrluA==",
|
"integrity": "sha512-Zq8gcQGmn4txQEJeiXo/KiLpon8TzAl0kmKH4zdWctPj05nWwp1ClMdAVEloqrQKfaC48PNLdgN/aVaLqUrluA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@types/parse5": {
|
||||||
|
"version": "5.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-5.0.2.tgz",
|
||||||
|
"integrity": "sha512-BOl+6KDs4ItndUWUFchy3aEqGdHhw0BC4Uu+qoDonN/f0rbUnJbm71Ulj8Tt9jLFRaAxPLKvdS1bBLfx1qXR9g==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@types/semver": {
|
"@types/semver": {
|
||||||
"version": "6.2.0",
|
"version": "6.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-6.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-6.2.0.tgz",
|
||||||
|
@ -5970,6 +5985,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"css-selector-parser": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-1.3.0.tgz",
|
||||||
|
"integrity": "sha1-XxrUPi2O77/cME/NOaUhZklD4+s=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"cssesc": {
|
"cssesc": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
|
||||||
|
@ -6545,6 +6566,15 @@
|
||||||
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
|
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"encoding": {
|
||||||
|
"version": "0.1.12",
|
||||||
|
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
|
||||||
|
"integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"iconv-lite": "~0.4.13"
|
||||||
|
}
|
||||||
|
},
|
||||||
"end-of-stream": {
|
"end-of-stream": {
|
||||||
"version": "1.4.1",
|
"version": "1.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
|
||||||
|
@ -8640,6 +8670,61 @@
|
||||||
"assert-plus": "^1.0.0"
|
"assert-plus": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"gettext-extractor": {
|
||||||
|
"version": "3.5.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/gettext-extractor/-/gettext-extractor-3.5.2.tgz",
|
||||||
|
"integrity": "sha512-4fJViJvAkWBUV8BHwAaY2T1oirsIEAYgYfYm/+x/gF2xWxOXgn4f7Cjsdq+xuuoA9HZga+fx2PIDP+07zbmP6g==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/glob": "5 - 7",
|
||||||
|
"@types/parse5": "^5",
|
||||||
|
"css-selector-parser": "^1.3",
|
||||||
|
"glob": "5 - 7",
|
||||||
|
"parse5": "^5",
|
||||||
|
"pofile": "1.0.x",
|
||||||
|
"typescript": "2 - 3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"gettext-parser": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/gettext-parser/-/gettext-parser-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-JPCBpGzm01te+nTenJwWqKDzixYPY4pInedixpcMl4GPEJeia/cH2TJCh32IggDrrLYrzqA8OitXZLpBdrx4Gg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"content-type": "^1.0.4",
|
||||||
|
"encoding": "^0.1.12",
|
||||||
|
"readable-stream": "^3.4.0",
|
||||||
|
"safe-buffer": "^5.2.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"readable-stream": {
|
||||||
|
"version": "3.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.5.0.tgz",
|
||||||
|
"integrity": "sha512-gSz026xs2LfxBPudDuI41V1lka8cxg64E66SGe78zJlsUofOg/yqwezdIcdfwik6B4h8LFmWPA9ef9X3FiNFLA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"inherits": "^2.0.3",
|
||||||
|
"string_decoder": "^1.1.1",
|
||||||
|
"util-deprecate": "^1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
|
||||||
|
"integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"string_decoder": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"safe-buffer": "~5.2.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"github-slugger": {
|
"github-slugger": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.2.1.tgz",
|
||||||
|
@ -12780,6 +12865,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.14.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.14.tgz",
|
||||||
"integrity": "sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw=="
|
"integrity": "sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw=="
|
||||||
},
|
},
|
||||||
|
"lodash.get": {
|
||||||
|
"version": "4.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
|
||||||
|
"integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk="
|
||||||
|
},
|
||||||
"lodash.merge": {
|
"lodash.merge": {
|
||||||
"version": "4.6.2",
|
"version": "4.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
||||||
|
@ -13589,6 +13679,14 @@
|
||||||
"integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==",
|
"integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node-gettext": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-gettext/-/node-gettext-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-8dwSN83FRvUVk9o0AwS4vrpbhSU=",
|
||||||
|
"requires": {
|
||||||
|
"lodash.get": "^4.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node-gyp": {
|
"node-gyp": {
|
||||||
"version": "3.8.0",
|
"version": "3.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz",
|
||||||
|
@ -14702,6 +14800,12 @@
|
||||||
"integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==",
|
"integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"pofile": {
|
||||||
|
"version": "1.0.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/pofile/-/pofile-1.0.11.tgz",
|
||||||
|
"integrity": "sha512-Vy9eH1dRD9wHjYt/QqXcTz+RnX/zg53xK+KljFSX30PvdDMb2z+c6uDUeblUGqqJgz3QFsdlA0IJvHziPmWtQg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"popper.js": {
|
"popper.js": {
|
||||||
"version": "1.16.1",
|
"version": "1.16.1",
|
||||||
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
|
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
"dev": "webpack --config webpack.dev.js",
|
"dev": "webpack --config webpack.dev.js",
|
||||||
"watch": "webpack --progress --watch --config webpack.dev.js",
|
"watch": "webpack --progress --watch --config webpack.dev.js",
|
||||||
"build": "NODE_ENV=production webpack --progress --hide-modules --config webpack.prod.js",
|
"build": "NODE_ENV=production webpack --progress --hide-modules --config webpack.prod.js",
|
||||||
|
"l10n:extract": "node build/extract-l10n.js",
|
||||||
"lint": "eslint --ext .js,.vue src",
|
"lint": "eslint --ext .js,.vue src",
|
||||||
"lint:fix": "eslint --ext .js,.vue src --fix",
|
"lint:fix": "eslint --ext .js,.vue src --fix",
|
||||||
"test": "jest --verbose",
|
"test": "jest --verbose",
|
||||||
|
@ -33,6 +34,7 @@
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nextcloud/axios": "^1.1.0",
|
"@nextcloud/axios": "^1.1.0",
|
||||||
|
"@nextcloud/l10n": "^1.1.0",
|
||||||
"@nextcloud/router": "^1.0.0",
|
"@nextcloud/router": "^1.0.0",
|
||||||
"core-js": "^3.4.4",
|
"core-js": "^3.4.4",
|
||||||
"escape-html": "^1.0.3",
|
"escape-html": "^1.0.3",
|
||||||
|
@ -70,6 +72,8 @@
|
||||||
"eslint-plugin-standard": "^4.0.0",
|
"eslint-plugin-standard": "^4.0.0",
|
||||||
"eslint-plugin-vue": "^6.0.1",
|
"eslint-plugin-vue": "^6.0.1",
|
||||||
"file-loader": "^5.0.2",
|
"file-loader": "^5.0.2",
|
||||||
|
"gettext-extractor": "^3.5.2",
|
||||||
|
"gettext-parser": "^4.0.2",
|
||||||
"iconfont-plugin-webpack": "^1.1.4",
|
"iconfont-plugin-webpack": "^1.1.4",
|
||||||
"jest": "^25.1.0",
|
"jest": "^25.1.0",
|
||||||
"jest-environment-jsdom-sixteen": "^1.0.0",
|
"jest-environment-jsdom-sixteen": "^1.0.0",
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { directive as ClickOutside } from 'v-click-outside'
|
import { directive as ClickOutside } from 'v-click-outside'
|
||||||
|
import { t } from '../../l10n'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
directives: {
|
directives: {
|
||||||
|
@ -49,8 +50,7 @@ export default {
|
||||||
title: {
|
title: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
// TODO: translate
|
default: t('Settings')
|
||||||
default: t('core', 'Settings')
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|
|
@ -93,7 +93,7 @@
|
||||||
'app-sidebar-header--compact': compact
|
'app-sidebar-header--compact': compact
|
||||||
}" class="app-sidebar-header">
|
}" class="app-sidebar-header">
|
||||||
<!-- close sidebar button -->
|
<!-- close sidebar button -->
|
||||||
<a href="#" class="app-sidebar__close icon-close" :title="t('core', 'close')"
|
<a href="#" class="app-sidebar__close icon-close" :title="t('close')"
|
||||||
@click.prevent="closeSidebar" />
|
@click.prevent="closeSidebar" />
|
||||||
|
|
||||||
<!-- sidebar header illustration/figure -->
|
<!-- sidebar header illustration/figure -->
|
||||||
|
@ -188,6 +188,7 @@
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import Actions from 'Components/Actions'
|
import Actions from 'Components/Actions'
|
||||||
import Focus from 'Directives/Focus'
|
import Focus from 'Directives/Focus'
|
||||||
|
import l10n from '../../mixins/l10n'
|
||||||
|
|
||||||
const IsValidString = function(value) {
|
const IsValidString = function(value) {
|
||||||
return value && typeof value === 'string' && value.trim() !== '' && value.indexOf(' ') === -1
|
return value && typeof value === 'string' && value.trim() !== '' && value.indexOf(' ') === -1
|
||||||
|
@ -201,6 +202,7 @@ export default {
|
||||||
directives: {
|
directives: {
|
||||||
focus: Focus
|
focus: Focus
|
||||||
},
|
},
|
||||||
|
mixins: [l10n],
|
||||||
props: {
|
props: {
|
||||||
active: {
|
active: {
|
||||||
type: String,
|
type: String,
|
||||||
|
|
|
@ -142,7 +142,7 @@ export default {
|
||||||
v-if="advanced"
|
v-if="advanced"
|
||||||
class="color-picker-navigation-button confirm"
|
class="color-picker-navigation-button confirm"
|
||||||
@click="handleConfirm">
|
@click="handleConfirm">
|
||||||
{{ t('core', 'Choose') }}
|
{{ t('Choose') }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -152,6 +152,7 @@ export default {
|
||||||
<script>
|
<script>
|
||||||
import { Chrome } from 'vue-color'
|
import { Chrome } from 'vue-color'
|
||||||
import GenColors from 'Utils/GenColors'
|
import GenColors from 'Utils/GenColors'
|
||||||
|
import l10n from '../../mixins/l10n'
|
||||||
import Popover from '../Popover'
|
import Popover from '../Popover'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -160,6 +161,7 @@ export default {
|
||||||
Chrome,
|
Chrome,
|
||||||
Popover
|
Popover
|
||||||
},
|
},
|
||||||
|
mixins: [l10n],
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -106,7 +106,7 @@ export default {
|
||||||
<!-- Close modal -->
|
<!-- Close modal -->
|
||||||
<Actions v-if="canClose" class="header-close">
|
<Actions v-if="canClose" class="header-close">
|
||||||
<ActionButton icon="icon-close" @click="close">
|
<ActionButton icon="icon-close" @click="close">
|
||||||
{{ t('core', 'Close') }}
|
{{ t('Close') }}
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
</Actions>
|
</Actions>
|
||||||
</div>
|
</div>
|
||||||
|
@ -131,7 +131,7 @@ export default {
|
||||||
@click="previous">
|
@click="previous">
|
||||||
<div class="icon icon-previous">
|
<div class="icon icon-previous">
|
||||||
<span class="hidden-visually">
|
<span class="hidden-visually">
|
||||||
{{ t('core', 'Previous') }}
|
{{ t('Previous') }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
@ -151,7 +151,7 @@ export default {
|
||||||
@click="next">
|
@click="next">
|
||||||
<div class="icon icon-next">
|
<div class="icon icon-next">
|
||||||
<span class="hidden-visually">
|
<span class="hidden-visually">
|
||||||
{{ t('core', 'Next') }}
|
{{ t('Next') }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
@ -166,6 +166,8 @@ export default {
|
||||||
import Hammer from 'hammerjs'
|
import Hammer from 'hammerjs'
|
||||||
import Actions from 'Components/Actions'
|
import Actions from 'Components/Actions'
|
||||||
import ActionButton from 'Components/ActionButton'
|
import ActionButton from 'Components/ActionButton'
|
||||||
|
import l10n from '../../mixins/l10n'
|
||||||
|
import t from '../../l10n'
|
||||||
import Tooltip from 'Directives/Tooltip'
|
import Tooltip from 'Directives/Tooltip'
|
||||||
import Timer from 'Utils/Timer'
|
import Timer from 'Utils/Timer'
|
||||||
|
|
||||||
|
@ -181,6 +183,8 @@ export default {
|
||||||
tooltip: Tooltip
|
tooltip: Tooltip
|
||||||
},
|
},
|
||||||
|
|
||||||
|
mixins: [l10n],
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
/**
|
/**
|
||||||
* Title to be shown with the modal
|
* Title to be shown with the modal
|
||||||
|
@ -283,7 +287,7 @@ export default {
|
||||||
return `modal-${this.outTransition ? 'out' : 'in'}`
|
return `modal-${this.outTransition ? 'out' : 'in'}`
|
||||||
},
|
},
|
||||||
playPauseTitle() {
|
playPauseTitle() {
|
||||||
return this.playing ? t('core', 'Pause slideshow') : t('core', 'Start slideshow')
|
return this.playing ? t('Pause slideshow') : t('Start slideshow')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -166,14 +166,14 @@ Please see the [AvatarSelectOption](#AvatarSelectOption) component
|
||||||
<slot :name="slot" v-bind="scope" />
|
<slot :name="slot" v-bind="scope" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- TODO add translation system
|
<span slot="noResult">{{ t('No results') }}</span>
|
||||||
<span slot="noResult">{{ t('core', 'No results') }}</span> -->
|
|
||||||
</VueMultiselect>
|
</VueMultiselect>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import AvatarSelectOption from './AvatarSelectOption'
|
import AvatarSelectOption from './AvatarSelectOption'
|
||||||
import EllipsisedOption from './EllipsisedOption'
|
import EllipsisedOption from './EllipsisedOption'
|
||||||
|
import l10n from '../../mixins/l10n'
|
||||||
import Tooltip from 'Directives/Tooltip'
|
import Tooltip from 'Directives/Tooltip'
|
||||||
import VueMultiselect from 'vue-multiselect'
|
import VueMultiselect from 'vue-multiselect'
|
||||||
|
|
||||||
|
@ -187,6 +187,7 @@ export default {
|
||||||
directives: {
|
directives: {
|
||||||
tooltip: Tooltip
|
tooltip: Tooltip
|
||||||
},
|
},
|
||||||
|
mixins: [l10n],
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -75,7 +75,7 @@ export default {
|
||||||
:tag-width="60"
|
:tag-width="60"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
@input="update">
|
@input="update">
|
||||||
<span slot="noResult">{{ t('core', 'No results') }}</span>
|
<span slot="noResult">{{ t('No results') }}</span>
|
||||||
<template #option="scope">
|
<template #option="scope">
|
||||||
{{ tagLabel(scope.option) }}
|
{{ tagLabel(scope.option) }}
|
||||||
</template>
|
</template>
|
||||||
|
@ -83,18 +83,21 @@ export default {
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import l10n from '../../mixins/l10n'
|
||||||
import { Multiselect } from 'Components/Multiselect'
|
import { Multiselect } from 'Components/Multiselect'
|
||||||
import { searchTags } from './api'
|
import { searchTags } from './api'
|
||||||
|
import { t } from '../../l10n'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'MultiselectTags',
|
name: 'MultiselectTags',
|
||||||
components: {
|
components: {
|
||||||
Multiselect
|
Multiselect
|
||||||
},
|
},
|
||||||
|
mixins: [l10n],
|
||||||
props: {
|
props: {
|
||||||
label: {
|
label: {
|
||||||
type: String,
|
type: String,
|
||||||
default: t('systemtags', 'Select a tag')
|
default: t('Select a tag')
|
||||||
},
|
},
|
||||||
value: {
|
value: {
|
||||||
type: [Number, Array],
|
type: [Number, Array],
|
||||||
|
@ -163,12 +166,10 @@ export default {
|
||||||
*/
|
*/
|
||||||
tagLabel({ displayName, userVisible, userAssignable }) {
|
tagLabel({ displayName, userVisible, userAssignable }) {
|
||||||
if (userVisible === false) {
|
if (userVisible === false) {
|
||||||
// TODO Use proper parameters once the translation is updated in the systemtags app
|
return t('{tag} (invisible)', { tag: displayName })
|
||||||
return t('systemtags', '%s (invisible)').replace('%s', displayName)
|
|
||||||
}
|
}
|
||||||
if (userAssignable === false) {
|
if (userAssignable === false) {
|
||||||
// TODO Use proper parameters once the translation is updated in the systemtags app
|
return t('{tag} (restricted)', { tag: displayName })
|
||||||
return t('systemtags', '%s (restricted)').replace('%s', displayName)
|
|
||||||
}
|
}
|
||||||
return displayName
|
return displayName
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { getGettextBuilder } from '@nextcloud/l10n/dist/gettext'
|
||||||
|
|
||||||
|
const gtBuilder = getGettextBuilder()
|
||||||
|
.detectLocale()
|
||||||
|
TRANSLATIONS.map(data => gtBuilder.addTranslation(data.locale, data.json))
|
||||||
|
const gt = gtBuilder.build()
|
||||||
|
|
||||||
|
export const n = gt.ngettext.bind(gt)
|
||||||
|
export const t = gt.gettext.bind(gt)
|
|
@ -0,0 +1,8 @@
|
||||||
|
import { n, t } from '../l10n'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
methods: {
|
||||||
|
n,
|
||||||
|
t
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,19 +20,5 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { config } from '@vue/test-utils'
|
global.TRANSLATIONS = []
|
||||||
|
|
||||||
// Mock nextcloud translate functions
|
|
||||||
config.mocks.$t = function(app, string) {
|
|
||||||
return string
|
|
||||||
}
|
|
||||||
config.mocks.t = config.mocks.$t
|
|
||||||
global.t = config.mocks.$t
|
|
||||||
|
|
||||||
config.mocks.$n = function(app, singular, plural, count) {
|
|
||||||
return singular
|
|
||||||
}
|
|
||||||
config.mocks.n = config.mocks.$n
|
|
||||||
global.n = config.mocks.$n
|
|
||||||
|
|
||||||
global.SCOPE_VERSION = 1
|
global.SCOPE_VERSION = 1
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
const path = require('path')
|
const fs = require('fs')
|
||||||
|
const gettextParser = require('gettext-parser')
|
||||||
const glob = require('glob')
|
const glob = require('glob')
|
||||||
const { VueLoaderPlugin } = require('vue-loader')
|
const md5 = require('md5')
|
||||||
|
const path = require('path')
|
||||||
const StyleLintPlugin = require('stylelint-webpack-plugin')
|
const StyleLintPlugin = require('stylelint-webpack-plugin')
|
||||||
|
const { VueLoaderPlugin } = require('vue-loader')
|
||||||
|
|
||||||
const IconfontPlugin = require('iconfont-plugin-webpack')
|
const IconfontPlugin = require('iconfont-plugin-webpack')
|
||||||
|
|
||||||
|
@ -10,7 +13,6 @@ const { DefinePlugin } = require('webpack')
|
||||||
const nodeExternals = require('webpack-node-externals')
|
const nodeExternals = require('webpack-node-externals')
|
||||||
|
|
||||||
// scope variable
|
// scope variable
|
||||||
const md5 = require('md5')
|
|
||||||
const appVersion = JSON.stringify(process.env.npm_package_version)
|
const appVersion = JSON.stringify(process.env.npm_package_version)
|
||||||
const versionHash = md5(appVersion).substr(0, 7)
|
const versionHash = md5(appVersion).substr(0, 7)
|
||||||
const SCOPE_VERSION = JSON.stringify(versionHash)
|
const SCOPE_VERSION = JSON.stringify(versionHash)
|
||||||
|
@ -18,6 +20,23 @@ const ICONFONT_NAME = `iconfont-vue-${versionHash}`
|
||||||
|
|
||||||
console.info('This build version hash is', versionHash, '\n')
|
console.info('This build version hash is', versionHash, '\n')
|
||||||
|
|
||||||
|
// https://github.com/alexanderwallin/node-gettext#usage
|
||||||
|
// https://github.com/alexanderwallin/node-gettext#load-and-add-translations-from-mo-or-po-files
|
||||||
|
const translations = fs
|
||||||
|
.readdirSync('./l10n')
|
||||||
|
.filter(name => name !== 'messages.pot' && name.endsWith('.pot'))
|
||||||
|
.map(file => {
|
||||||
|
const path = './l10n/' + file
|
||||||
|
const locale = file.substr(0, file.length -'.pot'.length)
|
||||||
|
|
||||||
|
const po = fs.readFileSync(path)
|
||||||
|
const json = gettextParser.po.parse(po)
|
||||||
|
return {
|
||||||
|
locale,
|
||||||
|
json
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
entry: {
|
entry: {
|
||||||
ncvuecomponents: path.join(__dirname, 'src', 'index.js'),
|
ncvuecomponents: path.join(__dirname, 'src', 'index.js'),
|
||||||
|
@ -111,7 +130,10 @@ module.exports = {
|
||||||
new StyleLintPlugin({
|
new StyleLintPlugin({
|
||||||
files: ['src/**/*.vue', 'src/**/*.scss', 'src/**/*.css']
|
files: ['src/**/*.vue', 'src/**/*.scss', 'src/**/*.css']
|
||||||
}),
|
}),
|
||||||
new DefinePlugin({ SCOPE_VERSION })
|
new DefinePlugin({
|
||||||
|
SCOPE_VERSION,
|
||||||
|
TRANSLATIONS: JSON.stringify(translations)
|
||||||
|
})
|
||||||
],
|
],
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче