Compare commits

...

40 Commits

Author SHA1 Message Date
Hafiz 52fbb677f9 update group-plans info card styles 2026-02-17 15:12:12 -06:00
Hafiz cfaf317b35 Fix emoji autocomplete overlapping actual text
position dropdown below text
2026-02-17 14:18:34 -06:00
Hafiz ca92208c28 update habitica-markdown package version (v3.0.0 -> v4.0.0) 2026-02-17 14:16:25 -06:00
Hafiz d2f611bd7e trying another github actions fix 2026-02-17 13:56:49 -06:00
Hafiz 016c43d0d1 try upping github-action fix 2026-02-17 13:54:02 -06:00
Hafiz ea93bfdbde emoji autocomplete to chat, messages, tasks, and profile
add :emoji shortcode autocomplete dropdown (reusing existing autocomplete mixin w/new helper)
2026-02-17 13:42:03 -06:00
Hafiz c2e8118852 size emoji in markdown 2026-02-17 13:16:12 -06:00
Hafiz 32c99a498f update habitica-markdown to include v3 emoji dataset (pointed towards test branch) 2026-02-06 14:51:10 -06:00
Hafiz f27a0581d9 fix indented code block detection for markdown-it v14 2026-02-06 14:30:32 -06:00
Hafiz 39d2431b32 Fix line endings in habiticaMarkdown test 2026-02-06 14:15:10 -06:00
Hafiz 235c0da38d Update emoji system to native Unicode rendering 2026-02-06 14:12:04 -06:00
Hafiz 9b0800c74b Merge remote-tracking branch 'origin/develop' into qa/monkey 2026-02-06 12:22:22 -06:00
Kalista Payne 5dd9711413 Update local dev MongoDB versions (#15334)
* chore(mongodb): update local dev MongoDB versions

* fix(github): update mongodb-github-action

* test(api): attempt to gather more detail on failures

* Revert "test(api): attempt to gather more detail on failures"

This reverts commit 215e768e90.

* WIP mongodb-memory-serve

* fix(mongo): start replica set

* run mongo as gh action service

* remove matrix for mongo

* try npm -> docker instead of services

* try "docker compose"

* disable mongo bootstrap from build

* try gh action again

* try newer action version

* working mongo docker compose 🎉

* fix(lint): leave out unused imports

* update lock

* cleanup previous workflow changes

* remove previous code, dont share mongo data folders on runtype (rs and docker)

* mongo docker for testing; align mongodb directory naming

* remove run-rs, add docker:aio script call, use healthcheck to initiate again

* merge docker-compose.yml, fix client port listening

* fix oudated healthcheck param

* chore(mongodb): update local dev MongoDB versions

* fix(github): update mongodb-github-action

* test(api): attempt to gather more detail on failures

* Revert "test(api): attempt to gather more detail on failures"

This reverts commit 215e768e90.

* WIP mongodb-memory-serve

* run mongo as gh action service

* fix(mongo): start replica set

* remove matrix for mongo

* try npm -> docker instead of services

* try "docker compose"

* disable mongo bootstrap from build

* try gh action again

* try newer action version

* working mongo docker compose 🎉

* fix(lint): leave out unused imports

* update lock

* cleanup previous workflow changes

* remove previous code, dont share mongo data folders on runtype (rs and docker)

* mongo docker for testing; align mongodb directory naming

* remove run-rs, add docker:aio script call, use healthcheck to initiate again

* merge docker-compose.yml, fix client port listening

* fix oudated healthcheck param

* fix(config): remove dup keys

* using npx vite during docker aio run

---------

Co-authored-by: negue <eugen.bolz@gmail.com>
2026-01-30 17:19:35 -06:00
Kalista Payne a542277a41 5.44.2 2026-01-26 11:46:03 -06:00
Phillip Thelen cdf8556fd6 Improve performance in production setup (#15594)
* build cached content files for mobile during gulp build

* load already cached content files during startup

* add option for mongoose to define minPoolSize

* cache client index.html for 10 minutes. Improves initial load times

* add option to auth to use lean version of user doc

* add a way to produce a heapdump from the command line

* fix lint
2026-01-26 11:45:44 -06:00
Kalista Payne 3d93390a7a fix(languages): update template characters 2026-01-23 13:09:14 -06:00
Kalista Payne 59f9cfa0f4 5.44.1 2026-01-23 13:03:30 -06:00
Kalista Payne 80d7804f69 fix(strings): use consistent template characters 2026-01-23 12:53:29 -06:00
Kalista Payne 4e5efe09a3 5.44.0 2026-01-22 11:53:20 -06:00
Fiz d42a597672 Merge pull request #15590 from HabitRPG/kalista/paypal-debug
PayPal debug
2026-01-21 16:11:41 -06:00
Phillip Thelen ea17b2e9c7 Rework how strings are localized (#15589)
* replace lodash template usage with micromustache

* remove function brackets from translations

* add newline

* remove old test

* split core translations from content translations

* fix directory not existing

* fix lint
2026-01-21 14:34:25 -06:00
Phillip Thelen f56708cd88 fix most customizations not being pinnable (#15578)
* fix most customizations not being pinnable

* set correct pinTypes

* fix(pinning): correct purchase types for base hair and mustaches

* automatically unpin purchased customizations

* ability to pin customization items

* Fix pin not showing on buy modal

* Pin on buy modal tweak

---------

Co-authored-by: Kalista Payne <kalista@habitica.com>
Co-authored-by: Hafiz <hafizbhamidi@gmail.com>
2026-01-21 13:57:42 -06:00
Kalista Payne 8fdbfb9dc6 fix(lint): import order 2026-01-16 17:47:05 -06:00
Kalista Payne 057a642baa fix(logger): path 2026-01-16 17:43:54 -06:00
Kalista Payne 6c522157a7 feat(payments): log some anonymous data to chase a bug 2026-01-16 17:38:16 -06:00
Hafiz 5e1770246d Clear upgradingGroup state after group plan payment 2026-01-15 12:04:08 -06:00
Hafiz a6a18e56d8 suppress error toasts for group modal, and UI tweaks for group modal
suppress error toast for 404 on party fetch for users without a party (for group modal), Increase check SVG size in selectableCard, and show "Previously upgraded" label for parties that were canceled group plans
2026-01-15 11:08:44 -06:00
Hafiz 7a06263cf4 Show warning for pending party invites when upgrading to paid group plan
Show warning for pending party invites when upgrading to paid group plan. If user upgrades from party to group, remove any pending invites
2026-01-14 19:43:29 -06:00
Hafiz e2e1d1e6be format member count 2026-01-14 09:31:30 -06:00
Hafiz 6d2b896bf5 set initial selected group plan, and fix card rounding 2026-01-14 09:28:44 -06:00
Hafiz 780d67c3de Remove comment 2026-01-13 13:54:26 -06:00
Hafiz aa4d26a5ae replace chaining (?.) w/null check 2026-01-13 13:49:12 -06:00
Hafiz 1a9707445f Fix eslint error in push notification import 2026-01-13 13:43:24 -06:00
Hafiz 3a91fde01d Update group plan eligibility check 2026-01-13 13:39:27 -06:00
Hafiz dcb3b1633b force flag when fetching group plans 2026-01-13 13:21:55 -06:00
Hafiz fa43484a1b Add includeExpiredPlans option to group fetching 2026-01-13 13:05:35 -06:00
Hafiz 9712d78fd3 Update group plan selection to include expired plans 2026-01-13 12:40:20 -06:00
Hafiz f6cc11771f set selection of group plan
Also tiny UI fixes
2026-01-12 12:32:22 -06:00
Hafiz 08c51b0908 crlf -> lf lint 2026-01-12 12:02:37 -06:00
Hafiz b4aa018699 Add group plan selection modal for upgrades
Allow users to select an existing group to upgrade before creating a new one.
2026-01-12 11:54:08 -06:00
231 changed files with 7958 additions and 4432 deletions
+30 -20
View File
@@ -82,7 +82,7 @@ jobs:
CI: true
NODE_ENV: test
- run: npm run test:sanity
common:
runs-on: ubuntu-latest
strategy:
@@ -129,13 +129,12 @@ jobs:
CI: true
NODE_ENV: test
- run: npm run test:content
api-unit:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [21.x]
mongodb-version: [4.2]
steps:
- uses: actions/checkout@v4
with:
@@ -144,11 +143,14 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Start MongoDB ${{ matrix.mongodb-version }} Replica Set
uses: supercharge/mongodb-github-action@1.3.0
with:
mongodb-version: ${{ matrix.mongodb-version }}
mongodb-replica-set: rs
- name: Start MongoDB 7.0 Replica Set
run: |
docker run -d --name mongodb -p 27017:27017 mongo:7.0 --replSet rs
sleep 5
docker exec mongodb mongosh --quiet --eval "rs.initiate({_id: 'rs', members: [{_id: 0, host: 'localhost:27017'}]})"
sleep 3
- run: sudo apt update
- run: sudo apt -y install libkrb5-dev
- run: cp config.json.example config.json
@@ -158,15 +160,16 @@ jobs:
env:
CI: true
NODE_ENV: test
- run: npm run test:api:unit
env:
REQUIRES_SERVER=true: true
api-v3-integration:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [21.x]
mongodb-version: [4.2]
steps:
- uses: actions/checkout@v4
with:
@@ -175,11 +178,13 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Start MongoDB ${{ matrix.mongodb-version }} Replica Set
uses: supercharge/mongodb-github-action@1.3.0
with:
mongodb-version: ${{ matrix.mongodb-version }}
mongodb-replica-set: rs
- name: Start MongoDB 7.0 Replica Set
run: |
docker run -d --name mongodb -p 27017:27017 mongo:7.0 --replSet rs
sleep 5
docker exec mongodb mongosh --quiet --eval "rs.initiate({_id: 'rs', members: [{_id: 0, host: 'localhost:27017'}]})"
sleep 3
- run: sudo apt update
- run: sudo apt -y install libkrb5-dev
- run: cp config.json.example config.json
@@ -189,15 +194,17 @@ jobs:
env:
CI: true
NODE_ENV: test
- run: npm run test:api-v3:integration
env:
REQUIRES_SERVER=true: true
api-v4-integration:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [21.x]
mongodb-version: [4.2]
steps:
- uses: actions/checkout@v4
with:
@@ -206,11 +213,13 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Start MongoDB ${{ matrix.mongodb-version }} Replica Set
uses: supercharge/mongodb-github-action@1.3.0
with:
mongodb-version: ${{ matrix.mongodb-version }}
mongodb-replica-set: rs
- name: Start MongoDB 7.0 Replica Set
run: |
docker run -d --name mongodb -p 27017:27017 mongo:7.0 --replSet rs
sleep 5
docker exec mongodb mongosh --quiet --eval "rs.initiate({_id: 'rs', members: [{_id: 0, host: 'localhost:27017'}]})"
sleep 3
- run: sudo apt update
- run: sudo apt -y install libkrb5-dev
- run: cp config.json.example config.json
@@ -220,6 +229,7 @@ jobs:
env:
CI: true
NODE_ENV: test
- run: npm run test:api-v4:integration
env:
REQUIRES_SERVER=true: true
+1 -1
View File
@@ -47,5 +47,5 @@ webpack.webstorm.config
# mongodb replica set for local dev
mongodb-*.tgz
/mongodb-data*
/mongodb-*
/.nyc_output
+2 -2
View File
@@ -46,7 +46,7 @@
"MAINTENANCE_MODE": "false",
"MONGODB_POOL_SIZE": "10",
"MONGODB_SOCKET_TIMEOUT": "20000",
"NODE_DB_URI": "mongodb://localhost:27017/habitica-dev?replicaSet=rs",
"NODE_DB_URI": "mongodb://localhost:27017/habitica-dev?replicaSet=rs&directConnection=true&readPreference=secondary",
"NODE_ENV": "development",
"PATH": "bin:node_modules/.bin:/usr/local/bin:/usr/bin:/bin",
"PAYPAL_BILLING_PLANS_basic_12mo": "basic_12mo",
@@ -90,7 +90,7 @@
"STRIPE_API_KEY": "aaaabbbbccccddddeeeeffff00001111",
"STRIPE_PUB_KEY": "22223333444455556666777788889999",
"STRIPE_WEBHOOKS_ENDPOINT_SECRET": "111111",
"TEST_DB_URI": "mongodb://localhost:27017/habitica-test?replicaSet=rs",
"TEST_DB_URI": "mongodb://localhost:27017/habitica-test?replicaSet=rs&directConnection=true&readPreference=secondary",
"TIME_TRAVEL_ENABLED": "false",
"TRUSTED_DOMAINS": "localhost,https://habitica.com",
"WEB_CONCURRENCY": 1
-53
View File
@@ -1,53 +0,0 @@
services:
client:
build:
context: .
dockerfile: ./Dockerfile-Dev
command: ["npm", "run", "client:dev"]
depends_on:
- server
environment:
- BASE_URL=http://server:3000
networks:
- habitica
ports:
- "8080:8080"
volumes:
- .:/usr/src/habitica
- /usr/src/habitica/node_modules
- /usr/src/habitica/website/client/node_modules
server:
build:
context: .
dockerfile: ./Dockerfile-Dev
command: ["npm", "start"]
depends_on:
mongo:
condition: service_healthy
environment:
- NODE_DB_URI=mongodb://mongo/habitrpg
networks:
- habitica
ports:
- "3000:3000"
volumes:
- .:/usr/src/habitica
- /usr/src/habitica/node_modules
mongo:
image: mongo:5.0.23
restart: unless-stopped
command: ["--replSet", "rs", "--bind_ip_all", "--port", "27017"]
healthcheck:
test: echo "try { rs.status() } catch (err) { rs.initiate() }" | mongosh --port 27017 --quiet
interval: 10s
timeout: 30s
start_period: 0s
start_interval: 1s
retries: 30
networks:
- habitica
ports:
- "27017:27017"
networks:
habitica:
driver: bridge
+23
View File
@@ -0,0 +1,23 @@
networks:
mongodb-network:
name: "mongodb-network"
driver: bridge
services:
mongodb:
image: "mongo:7.0"
container_name: "habitica-mongodb-only"
networks:
- mongodb-network
hostname: "mongodb"
ports:
- "27017:27017"
restart: "unless-stopped"
volumes:
- "./mongodb-data-docker:/data/db"
entrypoint: [ "/usr/bin/mongod", "--bind_ip_all", "--replSet", "rs" ]
healthcheck:
test: echo "try { rs.status() } catch (err) { rs.initiate() }" | mongosh --port 27017 --quiet
interval: 10s
timeout: 30s
start_period: 0s
retries: 30
+23
View File
@@ -0,0 +1,23 @@
networks:
mongodb-network:
name: "mongodb-network"
driver: bridge
services:
mongodb:
image: "mongo:7.0"
container_name: "habitica-mongodb-test"
networks:
- mongodb-network
hostname: "mongodb"
ports:
- "27017:27017"
restart: "unless-stopped"
volumes:
- "./mongodb-data-docker-testing:/data/db"
entrypoint: [ "/usr/bin/mongod", "--bind_ip_all", "--replSet", "rs" ]
healthcheck:
test: echo "try { rs.status() } catch (err) { rs.initiate() }" | mongosh --port 27017 --quiet
interval: 10s
timeout: 30s
start_period: 0s
retries: 30
+43 -22
View File
@@ -1,35 +1,56 @@
version: "3"
services:
client:
build: .
networks:
- habitica
environment:
- BASE_URL=http://server:3000
ports:
- "8080:8080"
command: ["npm", "run", "client:dev"]
build:
context: .
dockerfile: ./Dockerfile-Dev
command: ["npm", "run", "client:dev:docker"]
depends_on:
- server
server:
build: .
ports:
- "3000:3000"
environment:
- BASE_URL=http://server:3000
networks:
- habitica
ports:
- "5173:5173"
volumes:
- .:/usr/src/habitica
- /usr/src/habitica/node_modules
- /usr/src/habitica/website/client/node_modules
server:
build:
context: .
dockerfile: ./Dockerfile-Dev
command: ["npm", "start"]
depends_on:
mongo:
condition: service_healthy
environment:
- NODE_DB_URI=mongodb://mongo/habitrpg
depends_on:
- mongo
mongo:
image: mongo:3.6
ports:
- "27017:27017"
networks:
- habitica
ports:
- "3000:3000"
volumes:
- .:/usr/src/habitica
- /usr/src/habitica/node_modules
mongo:
image: "mongo:7.0"
container_name: "habitica-mongodb"
networks:
- habitica
hostname: "mongodb"
ports:
- "27017:27017"
restart: "unless-stopped"
volumes:
- "./mongodb-data-docker:/data/db"
entrypoint: [ "/usr/bin/mongod", "--bind_ip_all", "--replSet", "rs" ]
healthcheck:
test: echo "try { rs.status() } catch (err) { rs.initiate() }" | mongosh --port 27017 --quiet
interval: 10s
timeout: 30s
start_period: 0s
retries: 30
networks:
habitica:
+12 -9
View File
@@ -5,7 +5,7 @@ import path from 'path';
import babel from 'gulp-babel';
import os from 'os';
import fs from 'fs';
import spawn from 'cross-spawn'; // eslint-disable-line import/no-extraneous-dependencies
import spawn from 'cross-spawn';
import clean from 'rimraf';
gulp.task('build:babel:server', () => gulp.src('website/server/**/*.js')
@@ -35,7 +35,7 @@ gulp.task('build:prod', gulp.series(
// When used on windows `run-rs` must first be run without the `--keep` option
// in order to be setup correctly, afterwards it can be used.
const MONGO_PATH = path.join(__dirname, '/../mongodb-data/');
const MONGO_PATH = path.join(__dirname, '/../mongodb-data-docker/');
gulp.task('build:prepare-mongo', async () => {
if (fs.existsSync(MONGO_PATH)) {
@@ -51,29 +51,32 @@ gulp.task('build:prepare-mongo', async () => {
console.log('MongoDB data folder is missing, setting up.'); // eslint-disable-line no-console
// use run-rs without --keep, kill it as soon as the replica set starts
const runRsProcess = spawn('run-rs', ['-v', '4.1.1', '-l', 'ubuntu1804', '--dbpath', 'mongodb-data', '--number', '1', '--quiet']);
const dockerMongoProcess = spawn('npm', ['run', 'docker:mongo:dev']);
for await (const chunk of runRsProcess.stdout) {
let manuallyStopped = false;
for await (const chunk of dockerMongoProcess.stdout) {
const stringChunk = chunk.toString();
console.log(stringChunk); // eslint-disable-line no-console
// kills the process after the replica set is setup
if (stringChunk.includes('Started replica set')) {
if (stringChunk.includes('mongod startup complete')) {
console.log('MongoDB setup correctly.'); // eslint-disable-line no-console
runRsProcess.kill();
dockerMongoProcess.kill();
manuallyStopped = true;
}
}
let error = '';
for await (const chunk of runRsProcess.stderr) {
for await (const chunk of dockerMongoProcess.stderr) {
const stringChunk = chunk.toString();
error += stringChunk;
}
const exitCode = await new Promise(resolve => {
runRsProcess.on('close', resolve);
dockerMongoProcess.on('close', resolve);
});
if (exitCode || error.length > 0) {
if (!manuallyStopped && (exitCode || error.length > 0)) {
// remove any leftover files
clean.sync(MONGO_PATH);
+61 -26
View File
@@ -6,9 +6,21 @@ gulp.task('cache:content', done => {
// Requiring at runtime because these files access `common`
// code which in production works only if transpiled so after
// gulp build:babel:common has run
const { CONTENT_CACHE_PATH, getLocalizedContentResponse } = require('../website/server/libs/content'); // eslint-disable-line global-require
const {
CONTENT_CACHE_PATH,
getLocalizedContentResponse,
IOS_FILTER,
ANDROID_FILTER,
buildFilterObject,
hashForFilter,
} = require('../website/server/libs/content'); // eslint-disable-line global-require
const { langCodes } = require('../website/server/libs/i18n'); // eslint-disable-line global-require
const iosHash = hashForFilter(IOS_FILTER);
const iosFilterObj = buildFilterObject(IOS_FILTER);
const androidHash = hashForFilter(ANDROID_FILTER);
const androidFilterObj = buildFilterObject(ANDROID_FILTER);
try {
// create the cache folder (if it doesn't exist)
try {
@@ -26,33 +38,56 @@ gulp.task('cache:content', done => {
getLocalizedContentResponse(langCode),
'utf8',
);
});
done();
} catch (err) {
done(err);
}
});
gulp.task('cache:i18n', done => {
// Requiring at runtime because these files access `common`
// code which in production works only if transpiled so after
// gulp build:babel:common has run
const { BROWSER_SCRIPT_CACHE_PATH, geti18nBrowserScript } = require('../website/server/libs/i18n'); // eslint-disable-line global-require
const { langCodes } = require('../website/server/libs/i18n'); // eslint-disable-line global-require
try {
// create the cache folder (if it doesn't exist)
try {
fs.mkdirSync(BROWSER_SCRIPT_CACHE_PATH);
} catch (err) {
if (err.code !== 'EEXIST') throw err;
}
// create and save the i18n browser script for each language
langCodes.forEach(languageCode => {
fs.writeFileSync(
`${BROWSER_SCRIPT_CACHE_PATH}${languageCode}.js`,
geti18nBrowserScript(languageCode),
`${CONTENT_CACHE_PATH}${langCode}${iosHash}.json`,
getLocalizedContentResponse(langCode, iosFilterObj),
'utf8',
);
fs.writeFileSync(
`${CONTENT_CACHE_PATH}${langCode}${androidHash}.json`,
getLocalizedContentResponse(langCode, androidFilterObj),
'utf8',
);
});
done();
} catch (err) {
done(err);
}
});
function safeMkdir (path) {
try {
fs.mkdirSync(path);
} catch (err) {
if (err.code !== 'EEXIST') throw err;
}
}
gulp.task('cache:i18n', done => {
// Requiring at runtime because these files access `common`
// code which in production works only if transpiled so after
// gulp build:babel:common has run
const { BROWSER_SCRIPT_CACHE_PATH, geti18nCoreBrowserScript, geti18nContentBrowserScript } = require('../website/server/libs/i18n'); // eslint-disable-line global-require
const { langCodes } = require('../website/server/libs/i18n'); // eslint-disable-line global-require
try {
// create the cache folders (if they doesn't exist)
safeMkdir(BROWSER_SCRIPT_CACHE_PATH);
safeMkdir(`${BROWSER_SCRIPT_CACHE_PATH}core/`);
safeMkdir(`${BROWSER_SCRIPT_CACHE_PATH}content/`);
// create and save the i18n browser script for each language
langCodes.forEach(languageCode => {
fs.writeFileSync(
`${BROWSER_SCRIPT_CACHE_PATH}core/${languageCode}.js`,
geti18nCoreBrowserScript(languageCode),
'utf8',
);
fs.writeFileSync(
`${BROWSER_SCRIPT_CACHE_PATH}content/${languageCode}.js`,
geti18nContentBrowserScript(languageCode),
'utf8',
);
});
+5
View File
@@ -53,6 +53,11 @@ gulp.task('test:prepare:mongo', cb => {
const mongooseOptions = getDefaultConnectionOptions();
const connectionUrl = getDevelopmentConnectionUrl(TEST_DB_URI);
console.info({
mongooseOptions,
connectionUrl,
});
mongoose.connect(connectionUrl, mongooseOptions)
.then(() => mongoose.connection.dropDatabase())
.then(() => mongoose.connection.close()).then(() => {
+564 -684
View File
File diff suppressed because it is too large Load Diff
+11 -6
View File
@@ -1,7 +1,7 @@
{
"name": "habitica",
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
"version": "5.43.4",
"version": "5.44.2",
"main": "./website/server/index.js",
"dependencies": {
"@babel/core": "^7.22.10",
@@ -39,7 +39,8 @@
"gulp-filter": "^7.0.0",
"gulp-imagemin": "^7.1.0",
"gulp.spritesmith": "^6.13.0",
"habitica-markdown": "^3.0.0",
"habitica-markdown": "^4.0.0",
"heapdump": "^0.3.15",
"helmet": "^4.6.0",
"in-app-purchase": "^1.11.3",
"js2xmlparser": "^5.0.0",
@@ -48,10 +49,12 @@
"lodash": "^4.17.21",
"merge-stream": "^2.0.0",
"method-override": "^3.0.0",
"micromustache": "^8.0.3",
"moment": "^2.29.4",
"moment-recur": "git://github.com/HabitRPG/moment-recur.git#d3e8e6da0806f13b74dd2e4d7d9053e6a63db119",
"mongoose": "^8.9.5",
"morgan": "^1.10.1",
"nan": "^2.25.0",
"nconf": "^0.12.1",
"node-gcm": "^1.0.5",
"on-headers": "^1.1.0",
@@ -100,13 +103,16 @@
"coverage": "nyc report --reporter=html --report-dir coverage/results; open coverage/results/index.html",
"sprites": "gulp sprites:compile",
"client:dev": "cd website/client && npm run serve",
"client:dev:docker": "cd website/client && npm run serve:docker",
"client:build": "cd website/client && npm run build",
"client:unit": "cd website/client && npm run test:unit",
"start": "node --watch ./website/server/index.js",
"start:simple": "node ./website/server/index.js",
"debug": "node --watch --inspect ./website/server/index.js",
"mongo:dev": "run-rs -v 7.0.23 -l ubuntu2214 --keep --dbpath mongodb-data --number 1 --quiet",
"mongo:test": "run-rs -v 7.0.23 -l ubuntu2214 --keep --dbpath mongodb-data-testing --number 1 --quiet",
"docker:aio": "docker compose -f docker-compose.yml up",
"docker:mongo:dev": "docker compose -f docker-compose.mongo-only.yml up",
"docker:mongo:dev:down": "docker compose -f docker-compose.mongo-only.yml down",
"docker:mongo:test": "docker compose -f docker-compose.mongo-test-local.yml up",
"mongo:test": "node scripts/start-local-mongo.mjs --test-db",
"postinstall": "git config --global url.\"https://\".insteadOf git:// && gulp build && cd website/client && npm install",
"apidoc": "gulp apidoc",
"heroku-postbuild": ".heroku/report_deploy.sh"
@@ -122,7 +128,6 @@
"monk": "^7.3.4",
"nyc": "^15.1.0",
"require-again": "^2.0.0",
"run-rs": "^0.7.7",
"sinon-chai": "^3.7.0",
"sinon-stub-promise": "^4.0.0"
}
@@ -38,7 +38,7 @@ describe('GET /export/inbox.html', () => {
it('renders the markdown messages as html', async () => {
const res = await user.get('/export/inbox.html');
expect(res).to.include('img class="habitica-emoji"');
expect(res).to.include('😄');
expect(res).to.include('<h1>Hello!</h1>');
expect(res).to.include('<li>list 1</li>');
});
@@ -46,7 +46,7 @@ describe('GET /export/inbox.html', () => {
it('sorts messages from newest to oldest', async () => {
const res = await user.get('/export/inbox.html');
const emojiPosition = res.indexOf('img class="habitica-emoji"');
const emojiPosition = res.indexOf('😄');
const headingPosition = res.indexOf('<h1>Hello!</h1>');
const listPosition = res.indexOf('<li>list 1</li>');
+67
View File
@@ -0,0 +1,67 @@
import md from 'habitica-markdown';
describe('habiticaMarkdown emoji plugin', () => {
it('renders standard emoji as Unicode', () => {
const result = md.render(':smile:');
expect(result).to.include('😄');
expect(result).not.to.include('img');
});
it('renders thumbsup emoji as Unicode', () => {
const result = md.render(':thumbsup:');
expect(result).to.include('👍');
});
it('renders +1 emoji as Unicode', () => {
const result = md.render(':+1:');
expect(result).to.include('👍');
});
it('renders melior as an img tag', () => {
const result = md.render(':melior:');
expect(result).to.include('<img class="habitica-emoji"');
expect(result).to.include('src="https://s3.amazonaws.com/habitica-assets/cdn/emoji/melior.png"');
expect(result).to.include('alt="melior"');
});
it('does NOT convert emoji inside markdown links', () => {
const result = md.render('[:smile: link](http://example.com)');
expect(result).to.include(':smile: link');
expect(result).not.to.include('😄');
});
it('converts emoji outside of links normally', () => {
const result = md.render(':smile: [link](http://example.com)');
expect(result).to.include('😄');
expect(result).to.include('link');
});
it('leaves removed custom emoji (bowtie) as literal text', () => {
const result = md.render(':bowtie:');
expect(result).to.include(':bowtie:');
expect(result).not.to.include('img');
});
it('leaves unknown shortcodes as literal text', () => {
const result = md.render(':nonexistent_emoji_xyz:');
expect(result).to.include(':nonexistent_emoji_xyz:');
});
it('renders new emoji not in the old dataset', () => {
const result = md.render(':yawning_face:');
expect(result).to.include('🥱');
});
it('supports unsafeHTMLRender', () => {
const result = md.unsafeHTMLRender('<b>bold</b> :smile:');
expect(result).to.include('<b>bold</b>');
expect(result).to.include('😄');
});
it('supports renderWithMentions', () => {
const result = md.renderWithMentions(':smile: @testuser', { userName: 'testuser' });
expect(result).to.include('😄');
expect(result).to.include('at-text');
expect(result).to.include('at-highlight');
});
});
+9 -1
View File
@@ -20,6 +20,9 @@ describe('shared.ops.unlock', () => {
beforeEach(() => {
user = generateUser();
user.balance = usersStartingGems;
user.pinnedItems.push({ type: 'background', path: 'backgrounds.backgrounds042016.giant_florals' });
user.pinnedItems.push({ type: 'haircolor', path: 'hair.color.rainbow' });
user.pinnedItems.push({ type: 'shirt', path: 'shirt.convict' });
clock = sandbox.useFakeTimers(new Date('2024-04-10'));
});
@@ -272,6 +275,7 @@ describe('shared.ops.unlock', () => {
});
it('unlocks an item (appearance)', async () => {
expect(user.pinnedItems.findIndex(item => item.type === 'shirt')).to.not.equal(-1);
const path = unlockPath.split(',')[0];
const initialShirts = Object.keys(user.purchased.shirt).length;
const [, message] = await unlock(user, { query: { path } });
@@ -282,11 +286,12 @@ describe('shared.ops.unlock', () => {
);
expect(get(user.purchased, path)).to.be.true;
expect(user.balance).to.equal(usersStartingGems - 0.5);
expect(user.pinnedItems.findIndex(item => item.type === 'shirt')).to.equal(-1);
});
it('unlocks an item (hair color)', async () => {
user.purchased.hair.color = {};
expect(user.pinnedItems.findIndex(item => item.type === 'haircolor')).to.not.equal(-1);
const path = hairUnlockPath.split(',')[0];
const initialColorHair = Object.keys(user.purchased.hair.color).length;
const [, message] = await unlock(user, { query: { path } });
@@ -297,6 +302,7 @@ describe('shared.ops.unlock', () => {
);
expect(get(user.purchased, path)).to.be.true;
expect(user.balance).to.equal(usersStartingGems - 0.5);
expect(user.pinnedItems.findIndex(item => item.type === 'haircolor')).to.equal(-1);
});
it('unlocks an item (facial hair)', async () => {
@@ -334,6 +340,7 @@ describe('shared.ops.unlock', () => {
it('unlocks an item (background)', async () => {
const initialBackgrounds = Object.keys(user.purchased.background).length;
expect(user.pinnedItems.findIndex(item => item.type === 'background')).to.not.equal(-1);
const [, message] = await unlock(user, {
query: { path: backgroundUnlockPath },
});
@@ -344,6 +351,7 @@ describe('shared.ops.unlock', () => {
);
expect(get(user.purchased, backgroundUnlockPath)).to.be.true;
expect(user.balance).to.equal(usersStartingGems - 1.75);
expect(user.pinnedItems.findIndex(item => item.type === 'background')).to.equal(-1);
});
it('handles an invalid hair path gracefully', async () => {
+1 -6
View File
@@ -1,12 +1,7 @@
import { STRING_ERROR_MSG, STRING_DOES_NOT_EXIST_MSG } from '../helpers/content.helper';
import { STRING_DOES_NOT_EXIST_MSG } from '../helpers/content.helper';
import translator from '../../website/common/script/content/translation';
describe('Translator', () => {
it('returns error message if string is not properly formatted', () => {
const improperlyFormattedString = translator('petName', { attr: 0 })();
expect(improperlyFormattedString).to.match(STRING_ERROR_MSG);
});
it('returns an error message if string does not exist', () => {
const stringDoesNotExist = translator('stringDoesNotExist')();
expect(stringDoesNotExist).to.match(STRING_DOES_NOT_EXIST_MSG);
+2 -2
View File
@@ -1,8 +1,8 @@
import i18n from '../../website/common/script/i18n';
import './globals.helper';
import { translations } from '../../website/server/libs/i18n';
import { contentTranslations } from '../../website/server/libs/i18n';
i18n.translations = translations;
i18n.translations = contentTranslations;
export const STRING_ERROR_MSG = /^Error processing the string ".*". Please see Help > Report a Bug.$/;
export const STRING_DOES_NOT_EXIST_MSG = /^String '.*' not found.$/;
+1
View File
@@ -21,6 +21,7 @@ export async function getProperty (collectionName, id, path) {
// Specifically helpful for the GET /groups tests,
// resets the db to an empty state and creates a tavern document
export async function resetHabiticaDB () {
console.info('Resetting Habitica DB');
const groups = mongoose.connection.db.collection('groups');
const users = mongoose.connection.db.collection('users');
return mongoose.connection.dropDatabase()
+1 -1
View File
@@ -32,6 +32,6 @@
<script type="text/javascript" src="//cloudfront.loggly.com/js/loggly.tracker-latest.min.js" async></script>
<!-- Translations -->
<script type='text/javascript' src='/api/v4/i18n/browser-script' vite-ignore></script>
<script type='text/javascript' src='/api/v4/i18n/core' vite-ignore></script>
</body>
</html>
+4968 -2726
View File
File diff suppressed because it is too large Load Diff
+3 -1
View File
@@ -4,6 +4,7 @@
"private": true,
"scripts": {
"serve": "vite",
"serve:docker": "npx vite --host 0.0.0.0",
"build": "vite build",
"preview": "vite preview",
"test:unit": "vitest run",
@@ -27,12 +28,13 @@
"eslint-config-habitrpg": "6.2.0",
"eslint-plugin-mocha": "5.3.0",
"eslint-plugin-vue": "7.20.0",
"habitica-markdown": "^3.0.0",
"habitica-markdown": "^4.0.0",
"hellojs": "^1.20.0",
"intro.js": "^7.2.0",
"jquery": "^3.7.1",
"lodash": "^4.17.21",
"markdown-it": "^14.0.0",
"micromustache": "^8.0.3",
"moment": "^2.29.4",
"nconf": "^0.12.1",
"sass": "^1.63.4",
+5
View File
@@ -229,6 +229,11 @@ export default {
}
return Promise.resolve(error);
}
if (error.response.status === 404
&& error.response.config.method === 'get'
&& error.response.config.url.indexOf('/api/v4/groups/party') !== -1) {
return Promise.reject(error);
}
}
const errorData = error.response.data;
@@ -58,6 +58,11 @@ h3.markdown {
img {
max-width: 100%;
}
.emoji-native {
font-size: 0.85em;
vertical-align: middle;
}
blockquote {
padding: 0 16px;
@@ -0,0 +1,186 @@
<template>
<div
v-if="searchResults.length > 0"
class="autocomplete-selection"
:style="autocompleteStyle"
>
<div
v-for="result in searchResults"
:key="result.shortcode"
class="autocomplete-results d-flex align-items-center"
:class="{'hover-background': result.hover}"
@click="select(result)"
@mouseenter="setHover(result)"
@mouseleave="resetSelection()"
>
<span class="emoji-char">{{ result.emoji }}</span>
<span
class="shortcode ml-2"
:class="{'hover-foreground': result.hover}"
>:{{ result.shortcode }}:</span>
</div>
</div>
</template>
<style lang="scss" scoped>
@import '@/assets/scss/colors.scss';
.autocomplete-results {
padding: .5em;
}
.autocomplete-selection {
box-shadow: 1px 1px 1px #efefef;
}
.hover-background {
background-color: rgba(213, 200, 255, 0.32);
cursor: pointer;
}
.hover-foreground {
color: $purple-300 !important;
}
.emoji-char {
font-size: 20px;
line-height: 1;
}
.shortcode {
color: $gray-200;
font-size: 14px;
}
</style>
<script>
import emojiDefs from 'markdown-it-emoji/lib/data/full.json';
export default {
props: ['text', 'caretPosition', 'coords', 'textbox'],
data () {
return {
colonRegex: /:([a-zA-Z0-9_+]*)$/,
currentSearch: '',
searchActive: false,
searchResults: [],
selected: null,
emojiList: [],
};
},
computed: {
autocompleteStyle () {
const top = this.textbox.offsetTop + this.textbox.offsetHeight + 2;
return {
top: `${top}px`,
left: `${this.textbox.offsetLeft}px`,
position: 'absolute',
minWidth: '150px',
zIndex: 100,
backgroundColor: 'white',
};
},
},
watch: {
text (newText, prevText) {
if (!this.textbox) return;
const delCharsBool = prevText.length > newText.length;
const caretPosition = this.textbox.selectionEnd;
const lastFocusChar = delCharsBool ? prevText[caretPosition] : newText[caretPosition - 1];
if (
newText.length === 0
|| (lastFocusChar === ':' && delCharsBool)
) {
this.cancel();
} else {
if (lastFocusChar === ':') this.searchActive = true;
if (this.searchActive) {
this.searchResults = this.solveSearchResults(newText.substring(0, caretPosition));
}
}
},
},
created () {
const list = [];
const keys = Object.keys(emojiDefs);
keys.sort();
for (const key of keys) {
list.push({ shortcode: key, emoji: emojiDefs[key], hover: false });
}
this.emojiList = list;
},
methods: {
solveSearchResults (textFocus) {
const regexRes = this.colonRegex.exec(textFocus);
if (!regexRes) {
this.cancel();
return [];
}
this.currentSearch = regexRes[1];
if (this.currentSearch.length === 0) return [];
const lowerSearch = this.currentSearch.toLowerCase();
return this.emojiList
.filter(entry => entry.shortcode.startsWith(lowerSearch))
.slice(0, 6)
.map(entry => ({ ...entry, hover: false }));
},
select (result) {
const { text } = this;
const targetName = `${result.shortcode}: `;
const oldCaret = this.caretPosition;
const escapedSearch = this.currentSearch.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
let newText = text.substring(0, this.caretPosition)
.replace(new RegExp(`${escapedSearch}$`), targetName);
const newCaret = newText.length;
newText += text.substring(oldCaret, text.length);
this.$emit('select', newText, newCaret);
this.cancel();
},
setHover (result) {
this.resetSelection();
result.hover = true;
},
clearHover () {
for (const selection of this.searchResults) {
selection.hover = false;
}
},
resetSelection () {
this.clearHover();
this.selected = null;
},
selectNext () {
if (this.searchResults.length > 0) {
this.clearHover();
this.selected = this.selected === null
? 0
: (this.selected + 1) % this.searchResults.length;
this.searchResults[this.selected].hover = true;
}
},
selectPrevious () {
if (this.searchResults.length > 0) {
this.clearHover();
this.selected = this.selected === null
? this.searchResults.length - 1
: (this.selected - 1 + this.searchResults.length) % this.searchResults.length;
this.searchResults[this.selected].hover = true;
}
},
makeSelection () {
if (this.searchResults.length > 0 && this.selected !== null) {
const result = this.searchResults[this.selected];
this.select(result);
}
},
cancel () {
this.searchActive = false;
this.searchResults = [];
this.resetSelection();
},
},
};
</script>
@@ -0,0 +1,577 @@
<template>
<b-modal
id="group-plan-selection"
:hide-footer="true"
:hide-header="true"
size="md"
@show="loadData"
@hide="onHide"
>
<div class="selection-modal">
<div class="modal-header-row">
<h2 class="title">
{{ $t('chooseAnOption') }}
</h2>
<div class="header-actions">
<span
class="cancel-text"
@click="close"
>
{{ $t('cancel') }}
</span>
<button
class="btn btn-primary next-button"
:class="{ disabled: !selectedOption }"
:disabled="!selectedOption"
@click="continueFlow"
>
{{ $t('next') }}
</button>
</div>
</div>
<div
v-if="loading"
class="loading-container"
>
<div class="spinner-border text-secondary"></div>
</div>
<template v-else>
<div
v-if="hasUpgradeableGroups"
class="section-header"
>
{{ $t('upgradeExistingGroup') }}
</div>
<selectable-card
v-for="group in upgradeableGuilds"
:key="group._id"
class="option-card"
:selected="isSelected(group)"
@click="selectOption(group)"
>
<div class="option-content">
<div class="option-info">
<div class="option-name">
{{ group.name }}
</div>
<div class="option-members">
{{ formatMemberCount(group.memberCount) }}
</div>
<div class="option-label previously-upgraded">
<div
class="svg-icon sparkle-icon"
v-html="icons.sparkles"
></div>
{{ $t('previouslyUpgradedGroup') }}
</div>
</div>
<div class="option-price">
${{ calculatePrice(group.memberCount) }}.00/mo
</div>
</div>
</selectable-card>
<selectable-card
v-if="upgradeableParty"
class="option-card"
:class="{ 'has-pending-warning': partyPendingInviteCount > 0 }"
:selected="isSelected(upgradeableParty)"
@click="selectOption(upgradeableParty)"
>
<div class="option-content">
<div class="option-info">
<div class="option-name">
{{ upgradeableParty.name }}
</div>
<div class="option-members">
{{ formatMemberCount(upgradeableParty.memberCount) }}
<span
v-if="partyPendingInviteCount > 0"
class="pending-count"
>
{{ $t('pendingCount', { count: partyPendingInviteCount }) }}
</span>
</div>
<div
v-if="isPartyPreviouslyUpgraded"
class="option-label previously-upgraded"
>
<div
class="svg-icon sparkle-icon"
v-html="icons.sparkles"
></div>
{{ $t('previouslyUpgradedGroup') }}
</div>
<div
v-else
class="option-label your-party"
>
<div
class="svg-icon member-icon"
v-html="icons.member"
></div>
{{ $t('yourParty') }}
</div>
</div>
<div class="option-price">
${{ calculatePrice(upgradeableParty.memberCount) }}.00/mo
</div>
</div>
<div
v-if="partyPendingInviteCount > 0"
class="pending-warning-banner"
>
<div
class="svg-icon alert-icon"
v-html="icons.alert"
></div>
<span class="warning-text">{{ $t('upgradeCancelsPendingInvites') }}</span>
</div>
</selectable-card>
<div
v-if="hasUpgradeableGroups"
class="or-divider"
>
<div class="divider-line"></div>
<span class="or-text">{{ $t('or') }}</span>
<div class="divider-line"></div>
</div>
<selectable-card
class="option-card create-new"
:selected="selectedOption === 'new'"
@click="selectOption('new')"
>
<div class="option-content">
<div class="option-info">
<div class="option-name">
{{ $t('createNewGroup') }}
</div>
<div class="option-description">
{{ $t('inviteOthersForAdditional') }}
<span class="price-highlight">${{ perMemberPrice }}.00</span>
{{ $t('perMember') }}.
</div>
</div>
<div class="option-price">
${{ basePrice }}.00/mo
</div>
</div>
</selectable-card>
<div class="footer-note">
{{ $t('additionalMembersProrated') }}
</div>
</template>
</div>
</b-modal>
</template>
<style lang="scss" scoped>
@import '@/assets/scss/colors.scss';
.selection-modal {
padding: 24px;
}
.modal-header-row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24px;
}
.title {
font-family: 'Roboto Condensed', sans-serif;
font-weight: 700;
font-size: 20px;
line-height: 28px;
color: $purple-200;
margin: 0;
}
.header-actions {
display: flex;
align-items: center;
}
.cancel-text {
color: $blue-10;
font-size: 0.875rem;
margin-right: 16px;
cursor: pointer;
}
.next-button {
min-width: 64px;
&.disabled {
background-color: $gray-300;
border-color: $gray-300;
cursor: not-allowed;
}
}
.loading-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 200px;
}
.section-header {
font-family: 'Roboto', sans-serif;
font-weight: 700;
font-size: 14px;
line-height: 24px;
color: $gray-10;
margin-bottom: 12px;
}
.option-card {
margin-bottom: 12px;
::v-deep .option-name {
color: $gray-50;
}
&.selected ::v-deep .option-name {
color: $purple-200;
}
}
.pending-warning-banner {
display: flex;
align-items: center;
justify-content: center;
height: 32px;
background-color: $yellow-50;
border-radius: 0 0 6px 6px;
margin: 16px -16px 0 -16px;
gap: 4px;
.selected & {
margin: 15px -15px 0 -15px;
}
.alert-icon {
width: 16px;
height: 16px;
flex-shrink: 0;
::v-deep path {
fill: $gray-10;
}
}
.warning-text {
font-family: 'Roboto', sans-serif;
font-weight: 400;
font-size: 12px;
line-height: 16px;
color: $gray-10;
}
}
.option-content {
display: flex;
justify-content: space-between;
align-items: flex-start;
padding-left: 32px;
padding-right: 8px;
}
.option-info {
flex: 1;
}
.option-name {
font-family: 'Roboto', sans-serif;
font-size: 14px;
font-weight: 700;
line-height: 24px;
margin-bottom: 4px;
}
.option-members {
font-family: 'Roboto', sans-serif;
font-weight: 400;
font-size: 12px;
line-height: 16px;
color: $gray-100;
margin-bottom: 8px;
.pending-count {
font-weight: 700;
color: $yellow-5;
}
}
.option-label {
display: flex;
align-items: center;
font-family: 'Roboto', sans-serif;
font-size: 12px;
line-height: 16px;
gap: 4px;
&.previously-upgraded {
font-weight: 700;
color: $blue-10;
}
&.your-party {
font-weight: 700;
color: $gray-100;
}
.svg-icon {
width: 14px;
height: 14px;
}
.sparkle-icon {
color: $blue-10;
}
.member-icon {
color: $gray-100;
::v-deep path {
fill: $gray-100;
stroke: $gray-100;
stroke-width: 0.5px;
}
}
}
.option-description {
font-family: 'Roboto', sans-serif;
font-weight: 400;
font-size: 12px;
line-height: 16px;
color: $gray-100;
.price-highlight {
font-weight: 700;
}
}
.option-price {
font-family: 'Roboto', sans-serif;
font-weight: 700;
font-size: 20px;
line-height: 24px;
color: $purple-200;
white-space: nowrap;
}
.or-divider {
display: flex;
align-items: center;
margin: 20px 0;
.divider-line {
flex: 1;
height: 1px;
background-color: $gray-500;
}
.or-text {
padding: 0 16px;
font-family: 'Roboto', sans-serif;
font-weight: 700;
font-size: 12px;
line-height: 16px;
letter-spacing: 0.2em;
text-transform: uppercase;
color: $gray-100;
}
}
.create-new {
.option-name {
margin-bottom: 8px;
}
}
.footer-note {
font-family: 'Roboto', sans-serif;
font-weight: 400;
font-size: 12px;
line-height: 16px;
color: $gray-100;
text-align: center;
margin-top: 16px;
margin-left: 24px;
margin-right: 24px;
}
</style>
<style lang="scss">
#group-plan-selection {
.modal-dialog {
max-width: 504px;
}
.modal-content {
border-radius: 8px;
box-shadow: 0 14px 28px 0 rgba(26, 24, 29, 0.24), 0 10px 10px 0 rgba(26, 24, 29, 0.28);
}
.modal-body {
padding: 0;
}
.option-card.has-pending-warning.selectable-card {
padding-bottom: 0;
}
}
</style>
<script>
import axios from 'axios';
import paymentsMixin from '@/mixins/payments';
import { mapState } from '@/libs/store';
import SelectableCard from '@/components/ui/selectableCard.vue';
import svgSparkles from '@/assets/svg/sparkles.svg?raw';
import svgMember from '@/assets/svg/member-icon.svg?raw';
import svgAlert from '@/assets/svg/for-css/alert.svg?raw';
export default {
components: {
SelectableCard,
},
mixins: [paymentsMixin],
data () {
return {
selectedOption: null,
userGuilds: [],
userParty: null,
activeGroupPlanIds: [],
loading: true,
basePrice: 9,
perMemberPrice: 3,
icons: Object.freeze({
sparkles: svgSparkles,
member: svgMember,
alert: svgAlert,
}),
partyPendingInviteCount: 0,
};
},
computed: {
...mapState({ user: 'user.data' }),
upgradeableGuilds () {
return this.userGuilds.filter(group => {
const leaderId = group.leader?._id || group.leader;
if (leaderId !== this.user._id) return false;
const purchased = group.purchased;
if (!purchased?.wasUpgraded) return false;
if (this.activeGroupPlanIds.includes(group._id)) return false;
if (!purchased.dateTerminated) return false;
return new Date(purchased.dateTerminated) < new Date();
});
},
upgradeableParty () {
if (!this.userParty) return null;
const leaderId = this.userParty.leader?._id || this.userParty.leader;
if (leaderId !== this.user._id) return null;
if (this.activeGroupPlanIds.includes(this.userParty._id)) return null;
return this.userParty;
},
hasUpgradeableGroups () {
return this.upgradeableGuilds.length > 0 || this.upgradeableParty !== null;
},
isPartyPreviouslyUpgraded () {
if (!this.userParty) return false;
const purchased = this.userParty.purchased;
if (!purchased?.wasUpgraded) return false;
if (!purchased.dateTerminated) return false;
return new Date(purchased.dateTerminated) < new Date();
},
},
methods: {
async loadData () {
this.loading = true;
this.selectedOption = null;
this.partyPendingInviteCount = 0;
try {
const [guildsResponse, partyResponse] = await Promise.all([
axios.get('/api/v4/groups', { params: { type: 'guilds', includeExpiredPlans: 'true' } }),
axios.get('/api/v4/groups/party').catch(() => ({ data: { data: null } })),
]);
this.userGuilds = guildsResponse.data.data || [];
this.userParty = partyResponse.data.data;
if (this.userParty) {
try {
const invitesResponse = await axios.get(`/api/v4/groups/${this.userParty._id}/invites`);
this.partyPendingInviteCount = invitesResponse.data.data?.length || 0;
} catch (e) {
this.partyPendingInviteCount = 0;
}
}
await this.$store.dispatch('guilds:getGroupPlans', true);
const groupPlans = this.$store.state.groupPlans?.data || [];
this.activeGroupPlanIds = groupPlans.map(g => g._id);
} catch (e) {
console.error('Error loading group data:', e);
}
this.loading = false;
this.$nextTick(() => {
if (this.upgradeableGuilds.length > 0) {
this.selectedOption = this.upgradeableGuilds[0];
} else if (this.upgradeableParty) {
this.selectedOption = this.upgradeableParty;
} else {
this.selectedOption = 'new';
}
});
},
selectOption (option) {
this.selectedOption = option;
},
isSelected (group) {
if (!this.selectedOption || this.selectedOption === 'new') return false;
return this.selectedOption._id === group._id;
},
calculatePrice (memberCount) {
return this.basePrice + (this.perMemberPrice * (memberCount - 1));
},
formatMemberCount (count) {
return count === 1 ? this.$t('oneMember') : this.$t('membersCount', { count });
},
continueFlow () {
if (!this.selectedOption) return;
const selection = this.selectedOption;
this.close();
if (selection === 'new') {
this.$root.$emit('bv::show::modal', 'create-group');
} else {
this.stripeGroup({ group: selection, upgrade: true });
}
},
close () {
this.$root.$emit('bv::hide::modal', 'group-plan-selection');
},
onHide () {
this.selectedOption = null;
},
},
};
</script>
@@ -41,6 +41,14 @@
:chat="group.chat"
@select="selectedAutocomplete"
/>
<emoji-auto-complete
ref="emojiAutocomplete"
:text="newMessage"
:textbox="textbox"
:coords="mixinData.autoComplete.coords"
:caret-position="mixinData.autoComplete.caretPosition"
@select="selectedAutocomplete"
/>
</div>
<community-guidelines />
<div class="row chat-actions">
@@ -90,6 +98,7 @@ import { MAX_MESSAGE_LENGTH } from '@/../../common/script/constants';
import externalLinks from '../../mixins/externalLinks';
import autocomplete from '../chat/autoComplete';
import emojiAutoComplete from '../chat/emojiAutoComplete';
import communityGuidelines from './communityGuidelines';
import chatMessages from '../chat/chatMessages';
import { mapState } from '@/libs/store';
@@ -102,6 +111,7 @@ export default {
},
components: {
autocomplete,
emojiAutoComplete,
communityGuidelines,
chatMessages,
},
+82 -57
View File
@@ -25,53 +25,61 @@
<div class="col-12 col-md-6">
<div class="row icon-row">
<div
class="item-with-icon"
class="item-with-icon p-2"
tabindex="0"
role="button"
@keyup.enter="showMemberModal()"
@click="showMemberModal()"
>
<div
v-if="group.memberCount > 1000"
class="svg-icon shield"
v-html="icons.goldGuildBadgeIcon"
></div>
<div
v-if="group.memberCount > 100 && group.memberCount < 999"
class="svg-icon shield"
v-html="icons.silverGuildBadgeIcon"
></div>
<div
v-if="group.memberCount < 100"
class="svg-icon shield"
v-html="icons.bronzeGuildBadgeIcon"
></div>
<span class="number">{{ group.memberCount | abbrNum }}</span>
<div
v-once
class="member-list label"
>
{{ $t('memberList') }}
<div class="box-content">
<div class="icon-number-row">
<div
v-if="group.memberCount > 1000"
class="svg-icon shield"
v-html="icons.goldGuildBadgeIcon"
></div>
<div
v-if="group.memberCount > 100 && group.memberCount < 999"
class="svg-icon shield"
v-html="icons.silverGuildBadgeIcon"
></div>
<div
v-if="group.memberCount < 100"
class="svg-icon shield"
v-html="icons.bronzeGuildBadgeIcon"
></div>
<span class="number">{{ group.memberCount | abbrNum }}</span>
</div>
<div
v-once
class="details"
>
{{ $t('memberList') }}
</div>
</div>
</div>
<div v-if="!isParty">
<div
class="item-with-icon"
class="item-with-icon p-2"
tabindex="0"
role="button"
@keyup.enter="showGroupGems()"
@click="showGroupGems()"
>
<div
class="svg-icon gem"
v-html="icons.gem"
></div>
<span class="number">{{ group.balance * 4 }}</span>
<div
v-once
class="label"
>
{{ $t('guildBank') }}
<div class="box-content">
<div class="icon-number-row">
<div
class="svg-icon gem"
v-html="icons.gem"
></div>
<span class="number">{{ group.balance * 4 }}</span>
</div>
<div
v-once
class="details"
>
{{ $t('guildBank') }}
</div>
</div>
</div>
</div>
@@ -128,35 +136,57 @@
}
.item-with-icon {
display: inline-block;
border-radius: 2px;
background-color: #ffffff;
background-color: $white;
box-shadow: 0 2px 2px 0 rgba(26, 24, 29, 0.16), 0 1px 4px 0 rgba(26, 24, 29, 0.12);
padding: 1em;
text-align: center;
min-width: 120px;
margin-left: 1em;
width: 120px;
height: 76px;
margin-right: 1rem;
text-align: center;
font-size: 20px;
vertical-align: bottom;
overflow: hidden;
position: relative;
&:last-of-type {
margin-left: 0.5rem;
.box-content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
width: 100%;
}
.svg-icon.shield, .svg-icon.gem {
width: 28px;
height: auto;
margin: 0 auto;
.icon-number-row {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 0.1em;
.number {
font-size: 18px;
font-weight: normal;
margin-left: 0.2em;
}
}
.svg-icon {
width: 24px;
height: 24px;
display: inline-block;
vertical-align: bottom;
margin-right: 0.5em;
}
.number {
font-size: 22px;
font-weight: bold;
}
.label {
margin-top: .5em;
.details {
font-size: 11px;
color: $gray-200;
width: 100%;
padding: 0 4px;
line-height: 1.1;
word-break: break-word;
max-height: 2.2em;
overflow: visible;
}
}
@@ -215,11 +245,6 @@
.icon-row {
margin-top: 1em;
justify-content: flex-end;
.number {
font-size: 22px;
font-weight: bold;
}
}
.chat-row {
@@ -281,6 +281,11 @@
.badge-dialog {
left: -8px;
top: -8px;
.badge-pin {
width: 32px;
height: 32px;
}
}
.avatar {
@@ -903,8 +908,8 @@ export default {
purchaseGems () {
this.$root.$emit('bv::show::modal', 'buy-gems');
},
togglePinned () {
this.isPinned = this.$store.dispatch('user:togglePinnedItem', { type: this.item.pinType, path: this.item.path });
async togglePinned () {
this.isPinned = await this.$store.dispatch('user:togglePinnedItem', { type: this.item.pinType, path: this.item.path });
if (!this.isPinned) {
this.text(this.$t('unpinnedItem', { item: this.item.text }));
@@ -76,7 +76,21 @@
:empty-item="false"
:show-popover="Boolean(ctx.item.text)"
@click="selectItem(ctx.item)"
/>
>
<template
slot="itemBadge"
slot-scope="slotProps"
>
<span
class="badge-top"
@click.prevent.stop="togglePinned(slotProps.item)"
>
<pin-badge
:pinned="slotProps.item.pinned"
/>
</span>
</template>
</shop-item>
</template>
</item-rows>
</div>
@@ -108,6 +122,16 @@
}
</style>
<style lang="scss">
.market .badge-pin:not(.pinned) {
display: none;
}
.market .item:hover .badge-pin {
display: block;
}
</style>
<script>
import find from 'lodash/find';
import shops from '@/../../common/script/libs/shops';
@@ -118,7 +142,9 @@ import Checkbox from '@/components/ui/checkbox';
import FilterGroup from '@/components/ui/filterGroup';
import FilterSidebar from '@/components/ui/filterSidebar';
import ItemRows from '@/components/ui/itemRows';
import PinBadge from '@/components/ui/pinBadge';
import ShopItem from '../shopItem';
import pinUtils from '@/mixins/pinUtils';
export default {
components: {
@@ -126,8 +152,10 @@ export default {
FilterGroup,
FilterSidebar,
ItemRows,
PinBadge,
ShopItem,
},
mixins: [pinUtils],
data () {
return {
searchText: null,
@@ -184,8 +212,12 @@ export default {
methods: {
customizationsItems (options = {}) {
const { category, searchBy } = options;
return category.items.filter(item => !searchBy
|| item.text.toLowerCase().includes(searchBy));
return category.items
.filter(item => !searchBy || item.text.toLowerCase().includes(searchBy))
.map(item => ({
...item,
pinned: this.isPinned(item),
}));
},
emptyClick (identifier, event) {
if (event.target.tagName !== 'A') return;
@@ -180,6 +180,11 @@
.badge-dialog {
left: -8px;
top: -8px;
.badge-pin {
width: 32px;
height: 32px;
}
}
.modal-content {
@@ -1,5 +1,6 @@
<template>
<div>
<group-plan-selection-modal />
<group-plan-creation-modal />
<div class="d-flex justify-content-center">
<div
@@ -315,10 +316,12 @@
import { setup as setupPayments } from '@/libs/payments';
import paymentsMixin from '../../mixins/payments';
import GroupPlanCreationModal from '../group-plans/groupPlanCreationModal.vue';
import GroupPlanSelectionModal from '../group-plans/groupPlanSelectionModal.vue';
export default {
components: {
GroupPlanCreationModal,
GroupPlanSelectionModal,
},
mixins: [paymentsMixin],
data () {
@@ -359,7 +362,7 @@ export default {
if (this.upgradingGroup._id) {
return this.stripeGroup({ group: this.upgradingGroup, upgrade: true });
}
return this.$root.$emit('bv::show::modal', 'create-group');
return this.$root.$emit('bv::show::modal', 'group-plan-selection');
},
},
};
@@ -70,6 +70,13 @@
spellcheck="true"
:disabled="challengeAccessRequired"
:placeholder="$t('addATitle')"
@focus="setActiveField('title')"
@keydown="autoCompleteMixinUpdateCarretPosition"
@keydown.tab="autoCompleteMixinHandleTab($event)"
@keydown.up="autoCompleteMixinSelectPreviousAutocomplete($event)"
@keydown.down="autoCompleteMixinSelectNextAutocomplete($event)"
@keypress.enter="titleEnterHandler($event)"
@keydown.esc="autoCompleteMixinHandleEscape($event)"
>
</div>
<div
@@ -92,11 +99,27 @@
</small>
</div>
<textarea
ref="notesTextarea"
v-model="task.notes"
class="form-control input-notes"
:class="cssClass('input')"
:placeholder="$t('addNotes')"
@focus="setActiveField('notes')"
@keydown="autoCompleteMixinUpdateCarretPosition"
@keydown.tab="autoCompleteMixinHandleTab($event)"
@keydown.up="autoCompleteMixinSelectPreviousAutocomplete($event)"
@keydown.down="autoCompleteMixinSelectNextAutocomplete($event)"
@keypress.enter="autoCompleteMixinSelectAutocomplete($event)"
@keydown.esc="autoCompleteMixinHandleEscape($event)"
></textarea>
<emoji-auto-complete
ref="emojiAutocomplete"
:text="activeFieldText"
:textbox="textbox"
:coords="mixinData.autoComplete.coords"
:caret-position="mixinData.autoComplete.caretPosition"
@select="selectedAutocomplete"
/>
</div>
</div>
<div
@@ -712,6 +735,7 @@
}
.task-modal-header {
position: relative;
color: $white;
width: 100%;
border-top-left-radius: 8px;
@@ -1160,6 +1184,8 @@ import lockableLabel from '@/components/tasks/modal-controls/lockableLabel';
import selectList from '@/components/ui/selectList';
import syncTask from '../../mixins/syncTask';
import emojiAutoComplete from '@/components/chat/emojiAutoComplete';
import { autoCompleteHelperMixin } from '@/mixins/autoCompleteHelper';
import positiveIcon from '@/assets/svg/positive.svg?raw';
import negativeIcon from '@/assets/svg/negative.svg?raw';
@@ -1182,15 +1208,18 @@ export default {
toggleCheckbox,
lockableLabel,
selectList,
emojiAutoComplete,
},
directives: {
markdown: markdownDirective,
},
mixins: [syncTask],
mixins: [syncTask, autoCompleteHelperMixin],
// purpose is either create or edit, task is the task created or edited
props: ['task', 'purpose', 'challengeId', 'groupId'],
data () {
return {
textbox: null,
activeField: 'title',
showAssignedSelect: false,
newChecklistItem: null,
icons: Object.freeze({
@@ -1314,6 +1343,10 @@ export default {
selectedTags () {
return this.getTagsFor(this.task);
},
activeFieldText () {
if (!this.task) return '';
return this.activeField === 'title' ? (this.task.text || '') : (this.task.notes || '');
},
showStatAssignment () {
return this.task.type !== 'reward'
&& !this.groupId
@@ -1489,6 +1522,35 @@ export default {
},
focusInput () {
this.$refs.inputToFocus.focus();
this.setActiveField('title');
},
setActiveField (field) {
this.activeField = field;
if (field === 'title') {
this.textbox = this.$refs.inputToFocus;
} else {
this.textbox = this.$refs.notesTextarea;
}
},
titleEnterHandler (e) {
const ac = this._getActiveAutocomplete();
if (ac && ac.selected !== null) {
e.preventDefault();
ac.makeSelection();
} else if (ac) {
ac.cancel();
}
},
selectedAutocomplete (newText, newCaret) {
if (this.activeField === 'title') {
this.task.text = newText;
} else {
this.task.notes = newText;
}
this.$nextTick(() => {
this.textbox.setSelectionRange(newCaret, newCaret);
this.textbox.focus();
});
},
async addTag (name) {
const tagResult = await this.createTag({ name });
@@ -16,7 +16,7 @@
.badge-pin {
background-color: $white;
color: $gray-200;
color: $gray-100;
transition: none;
display: flex;
cursor: pointer;
@@ -32,8 +32,8 @@
}
.svg-icon {
width: 100%;
height: 100%;
width: 16px;
height: 16px;
}
}
@@ -0,0 +1,92 @@
<template>
<div
class="selectable-card"
:class="{ selected }"
@click="$emit('click')"
>
<div
v-if="selected"
class="checkmark-corner"
>
<div
class="svg-icon check-icon"
v-html="icons.check"
></div>
</div>
<slot></slot>
</div>
</template>
<style lang="scss" scoped>
@import '@/assets/scss/colors.scss';
.selectable-card {
position: relative;
background: $white;
border: 1px solid $gray-400;
border-radius: 8px;
padding: 16px;
cursor: pointer;
box-shadow: 0px 1px 2px 0px rgba(26, 24, 29, 0.08);
&:hover {
box-shadow: 0px 3px 6px 0px rgba(26, 24, 29, 0.16), 0px 3px 6px 0px rgba(26, 24, 29, 0.24);
}
&.selected {
border: 2px solid $purple-300;
padding: 15px;
box-shadow: 0px 3px 6px 0px rgba(26, 24, 29, 0.16), 0px 3px 6px 0px rgba(26, 24, 29, 0.24);
}
}
.checkmark-corner {
position: absolute;
top: 0;
left: 0;
width: 48px;
height: 48px;
overflow: hidden;
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
border-style: solid;
border-width: 48px 48px 0 0;
border-color: $purple-300 transparent transparent transparent;
border-radius: 6px 0 0 0;
}
.check-icon {
position: absolute;
top: 8px;
left: 8px;
width: 16px;
height: 16px;
color: $white;
}
}
</style>
<script>
import svgCheck from '@/assets/svg/check.svg?raw';
export default {
props: {
selected: {
type: Boolean,
default: false,
},
},
emits: ['click'],
data () {
return {
icons: Object.freeze({
check: svgCheck,
}),
};
},
};
</script>
@@ -398,14 +398,29 @@
:placeholder="$t('imageUrl')"
>
</div>
<div class="form-group">
<div class="form-group" style="position: relative;">
<label>{{ $t('about') }}</label>
<textarea
ref="blurbTextarea"
v-model="editingProfile.blurb"
class="form-control"
rows="5"
:placeholder="$t('displayBlurbPlaceholder')"
@keydown="autoCompleteMixinUpdateCarretPosition"
@keydown.tab="autoCompleteMixinHandleTab($event)"
@keydown.up="autoCompleteMixinSelectPreviousAutocomplete($event)"
@keydown.down="autoCompleteMixinSelectNextAutocomplete($event)"
@keypress.enter="autoCompleteMixinSelectAutocomplete($event)"
@keydown.esc="autoCompleteMixinHandleEscape($event)"
></textarea>
<emoji-auto-complete
ref="emojiAutocomplete"
:text="editingProfile.blurb"
:textbox="textbox"
:coords="mixinData.autoComplete.coords"
:caret-position="mixinData.autoComplete.caretPosition"
@select="selectedAutocomplete"
/>
<!-- include ../../shared/formatting-help-->
</div>
</div>
@@ -1001,6 +1016,8 @@ import mute from '@/assets/svg/mute.svg?raw';
import shadowMute from '@/assets/svg/shadow-mute.svg?raw';
import externalLinks from '../../mixins/externalLinks';
import { userCustomStateMixin } from '../../mixins/userState';
import emojiAutoComplete from '@/components/chat/emojiAutoComplete';
import { autoCompleteHelperMixin } from '@/mixins/autoCompleteHelper';
// @TODO: EMAILS.COMMUNITY_MANAGER_EMAIL
const COMMUNITY_MANAGER_EMAIL = 'admin@habitica.com';
@@ -1012,8 +1029,9 @@ export default {
MemberDetails,
profileStats,
toggleSwitch,
emojiAutoComplete,
},
mixins: [externalLinks, userCustomStateMixin('userLoggedIn')],
mixins: [externalLinks, userCustomStateMixin('userLoggedIn'), autoCompleteHelperMixin],
props: ['userId', 'startingPage'],
data () {
return {
@@ -1033,6 +1051,7 @@ export default {
mute,
shadowMute,
}),
textbox: null,
userIdToMessage: '',
editing: false,
editingProfile: {
@@ -1121,6 +1140,13 @@ export default {
userLoggedIn () {
this.loadUser();
},
editing (val) {
if (val) {
this.$nextTick(() => {
this.textbox = this.$refs.blurbTextarea;
});
}
},
},
mounted () {
this.loadUser();
@@ -1331,6 +1357,13 @@ export default {
this.$emit('toggled', this.isOpened);
},
selectedAutocomplete (newText, newCaret) {
this.editingProfile.blurb = newText;
this.$nextTick(() => {
this.textbox.setSelectionRange(newCaret, newCaret);
this.textbox.focus();
});
},
reportPlayer () {
this.$root.$emit('habitica::report-profile', {
memberId: this.user._id,
+28 -14
View File
@@ -15,46 +15,60 @@ export const autoCompleteHelperMixin = {
};
},
methods: {
_getActiveAutocomplete () {
if (this.$refs.autocomplete && this.$refs.autocomplete.searchActive) {
return this.$refs.autocomplete;
}
if (this.$refs.emojiAutocomplete && this.$refs.emojiAutocomplete.searchActive) {
return this.$refs.emojiAutocomplete;
}
return null;
},
autoCompleteMixinHandleTab (e) {
if (this.$refs.autocomplete.searchActive) {
const ac = this._getActiveAutocomplete();
if (ac) {
e.preventDefault();
if (e.shiftKey) {
this.$refs.autocomplete.selectPrevious();
ac.selectPrevious();
} else {
this.$refs.autocomplete.selectNext();
ac.selectNext();
}
}
},
autoCompleteMixinHandleEscape (e) {
if (this.$refs.autocomplete.searchActive) {
const ac = this._getActiveAutocomplete();
if (ac) {
e.preventDefault();
this.$refs.autocomplete.cancel();
ac.cancel();
}
},
autoCompleteMixinSelectNextAutocomplete (e) {
if (this.$refs.autocomplete.searchActive) {
const ac = this._getActiveAutocomplete();
if (ac) {
e.preventDefault();
this.$refs.autocomplete.selectNext();
ac.selectNext();
}
},
autoCompleteMixinSelectPreviousAutocomplete (e) {
if (this.$refs.autocomplete.searchActive) {
const ac = this._getActiveAutocomplete();
if (ac) {
e.preventDefault();
this.$refs.autocomplete.selectPrevious();
ac.selectPrevious();
}
},
autoCompleteMixinSelectAutocomplete (e) {
if (this.$refs.autocomplete.searchActive) {
if (this.$refs.autocomplete.selected !== null) {
const ac = this._getActiveAutocomplete();
if (ac) {
if (ac.selected !== null) {
e.preventDefault();
this.$refs.autocomplete.makeSelection();
ac.makeSelection();
} else {
// no autocomplete selected, newline instead
this.$refs.autocomplete.cancel();
ac.cancel();
}
}
},
@@ -153,9 +153,23 @@
:placeholder="$t('needsTextPlaceholder')"
:maxlength="MAX_MESSAGE_LENGTH"
:class="{'has-content': newMessage.trim() !== '', 'disabled': newMessageDisabled}"
@keydown="autoCompleteMixinUpdateCarretPosition"
@keyup.ctrl.enter="sendPrivateMessage()"
@keydown.tab="autoCompleteMixinHandleTab($event)"
@keydown.up="autoCompleteMixinSelectPreviousAutocomplete($event)"
@keydown.down="autoCompleteMixinSelectNextAutocomplete($event)"
@keypress.enter="autoCompleteMixinSelectAutocomplete($event)"
@keydown.esc="autoCompleteMixinHandleEscape($event)"
>
</textarea>
<emoji-auto-complete
ref="emojiAutocomplete"
:text="newMessage"
:textbox="textbox"
:coords="mixinData.autoComplete.coords"
:caret-position="mixinData.autoComplete.caretPosition"
@select="selectedAutocomplete"
/>
</div>
<div
class="sub-new-message-row d-flex"
@@ -540,6 +554,7 @@ h3 {
}
.new-message-row {
position: relative;
width: 100%;
padding-left: 1.5rem;
padding-top: 1.5rem;
@@ -676,6 +691,8 @@ import PmNewMessageStarted from './pm-new-message-started.vue';
import StartNewConversationInputHeader from './start-new-conversation-input-header.vue';
import positiveIcon from '@/assets/svg/positive.svg?raw';
import NotificationMixins from '@/mixins/notifications';
import emojiAutoComplete from '@/components/chat/emojiAutoComplete';
import { autoCompleteHelperMixin } from '@/mixins/autoCompleteHelper';
// extract to a shared path
const CONVERSATIONS_PER_PAGE = 10;
@@ -700,13 +717,14 @@ export default defineComponent({
toggleSwitch,
userLink,
faceAvatar,
emojiAutoComplete,
},
filters: {
timeAgo (value) {
return moment(new Date(value)).fromNow();
},
},
mixins: [styleHelper, NotificationMixins],
mixins: [styleHelper, NotificationMixins, autoCompleteHelperMixin],
beforeRouteEnter (to, from, next) {
next(vm => {
const data = vm.$store.state.privateMessageOptions;
@@ -751,6 +769,7 @@ export default defineComponent({
/** @type {Record<string, PrivateMessages.PrivateMessageEntry[]>} */
messagesByConversation: {}, // cache {uuid: []}
textbox: null,
newMessage: '',
messages: [],
messagesLoading: false,
@@ -963,6 +982,15 @@ export default defineComponent({
}
},
},
watch: {
shouldShowInputPanel (val) {
if (val) {
this.$nextTick(() => {
this.textbox = this.$refs.textarea;
});
}
},
},
async mounted () {
this.$store.dispatch('common:setTitle', {
section: this.$t('messages'),
@@ -1224,6 +1252,13 @@ export default defineComponent({
triggerStartNewConversationState () {
this.showStartNewConversationInput = true;
},
selectedAutocomplete (newText, newCaret) {
this.newMessage = newText;
this.$nextTick(() => {
this.textbox.setSelectionRange(newCaret, newCaret);
this.textbox.focus();
});
},
async startConversationByUsername (targetUserName) {
// check if the target user exists in current conversations, select that conversation
/** @type {PrivateMessages.ConversationSummaryMessageEntry} */
+37 -24
View File
@@ -268,7 +268,6 @@ export default {
this.$store.dispatch('user:fetch'),
this.$store.dispatch('tasks:fetchUserTasks'),
]).then(() => {
this.$store.state.isUserLoaded = true;
let analyticsConsent = localStorage.getItem('analyticsConsent');
if (analyticsConsent !== null) {
analyticsConsent = analyticsConsent === 'true';
@@ -276,31 +275,11 @@ export default {
this.$store.dispatch('user:set', { 'preferences.analyticsConsent': analyticsConsent });
}
}
if (window && window['habitica-i18n']) {
if (this.user.preferences.language === window['habitica-i18n'].language.code) {
return null;
}
}
if (window && window['habitica-i18n']) {
if (this.user.preferences.language === window['habitica-i18n'].language.code) {
return null;
}
}
Analytics.updateUser();
return axios.get(
'/api/v4/i18n/browser-script',
{
language: this.user.preferences.language,
headers: {
'Cache-Control': 'no-cache',
Pragma: 'no-cache',
Expires: '0',
},
},
);
return this.loadAllTranslations();
}).then(() => {
const i18nData = window && window['habitica-i18n'];
this.$loadLocale(i18nData);
this.$store.state.isUserLoaded = true;
this.hideLoadingScreen();
// Adjust the timezone offset
@@ -316,6 +295,10 @@ export default {
appState = JSON.parse(appState);
if (appState.paymentCompleted) {
removeLocalSetting(CONSTANTS.savedAppStateValues.SAVED_APP_STATE);
if (appState.paymentType === 'groupPlan') {
this.$store.state.upgradingGroup = {};
this.$store.dispatch('guilds:getGroupPlans', true);
}
this.$root.$emit('habitica:payment-success', appState);
}
}
@@ -380,6 +363,36 @@ export default {
hideLoadingScreen () {
this.loading = false;
},
async loadContentTranslations () {
const contentTranslations = await axios.get(
'/api/v4/i18n/content',
{
language: this.user.preferences.language,
},
);
const i18nData = window && window['habitica-i18n'];
i18nData.strings = { ...i18nData.strings, ...contentTranslations.data };
this.$loadLocale(i18nData);
},
async loadAllTranslations () {
if (window && window['habitica-i18n']) {
if (this.user.preferences.language === window['habitica-i18n'].language.code) {
return this.loadContentTranslations();
}
}
await axios.get(
'/api/v4/i18n/core',
{
language: this.user.preferences.language,
headers: {
'Cache-Control': 'no-cache',
Pragma: 'no-cache',
Expires: '0',
},
},
);
return this.loadContentTranslations();
},
},
};
</script>
+1 -1
View File
@@ -5,7 +5,7 @@
"keepIt": "Запазване",
"removeIt": "Премахване",
"brokenChallenge": "Повредена връзка на предизвикателство: тази задача е била част от предизвикателство, но то (или групата) е било изтрито. Какво бихте искали да направите с останалите задачи?",
"challengeCompleted": "Това предизвикателство е приключило и победителят е <span class=\"badge\"><%- user %></span>! Какво искате да направите с останалите задачи?",
"challengeCompleted": "Това предизвикателство е приключило и победителят е <span class=\"badge\"><%= user %></span>! Какво искате да направите с останалите задачи?",
"unsubChallenge": "Повредена връзка на предизвикателство: тази задача е била част от предизвикателство, но Вие сте се отписали от него. Какво искате да направите с останалите задачи?",
"challenges": "Предизвикателства",
"endDate": "Крайна дата",
+2 -2
View File
@@ -182,7 +182,7 @@
"questEggVelociraptorText": "Велоцираптор",
"questEggVelociraptorMountText": "Велоцираптор",
"questEggVelociraptorAdjective": "умен",
"eggNotes": "Намерете излюпваща отвара, която да излеете върху това яйце и от него ще се излюпи <%= eggAdjective(locale) %> <%= eggText(locale) %>.",
"eggNotes": "Намерете излюпваща отвара, която да излеете върху това яйце и от него ще се излюпи <%= eggAdjective %> <%= eggText %>.",
"hatchingPotionBase": "Нормален цвят",
"hatchingPotionWhite": "Бял цвят",
"hatchingPotionDesert": "Пустинен цвят",
@@ -211,7 +211,7 @@
"hatchingPotionGlow": "Светещо в тъмното",
"hatchingPotionFrost": "Скреж",
"hatchingPotionIcySnow": "Леден сняг",
"hatchingPotionNotes": "Излейте това върху яйце и от него ще се излюпи любимец с(ъс) <%= potText(locale) %>.",
"hatchingPotionNotes": "Излейте това върху яйце и от него ще се излюпи любимец с(ъс) <%= potText %>.",
"foodMeat": "Месо",
"foodMeatThe": "Месото",
"foodMeatA": "Месо",
+1 -1
View File
@@ -190,7 +190,7 @@
"messages": "Съобщения",
"emptyMessagesLine1": "Нямате съобщения",
"emptyMessagesLine2": "Можете да изпратите ново съобщение на потребител, като посетите профила им и докоснете бутона \"Съобщение\".",
"userSentMessage": "<span class=\"notification-bold\"><%- user %></span> Ви изпрати съобщение",
"userSentMessage": "<span class=\"notification-bold\"><%= user %></span> Ви изпрати съобщение",
"letsgo": "Хойде!",
"selected": "Избрано",
"howManyToBuy": "Колко искате да купите?",
+14 -14
View File
@@ -24,14 +24,14 @@
"userId": "Потребителски идентификатор",
"invite": "Покана",
"leave": "Напускане",
"invitedToParty": "Получихте покана за присъединяване към групата <span class=\"notification-bold\"><%- party %></span>",
"invitedToPrivateGuild": "Получихте покана за присъединяване към частната гилдия <span class=\"notification-bold\"><%- guild %></span>",
"invitedToPublicGuild": "Получихте покана за присъединяване към гилдията <span class=\"notification-bold-blue\"><%- guild %></span>",
"invitedToParty": "Получихте покана за присъединяване към групата <span class=\"notification-bold\"><%= party %></span>",
"invitedToPrivateGuild": "Получихте покана за присъединяване към частната гилдия <span class=\"notification-bold\"><%= guild %></span>",
"invitedToPublicGuild": "Получихте покана за присъединяване към гилдията <span class=\"notification-bold-blue\"><%= guild %></span>",
"invitationAcceptedHeader": "Поканата Ви беше приета",
"invitationAcceptedBody": "<%= username %> прие поканата Ви да се присъедини към <%= groupName %>!",
"systemMessage": "Системно съобщение",
"newMsgGuild": "Има нови публикации в <span class=\"notification-bold-blue\"><%- name %></span>",
"newMsgParty": "Има нови публикации в групата Ви — <span class=\"notification-bold-blue\"><%- name %></span>",
"newMsgGuild": "Има нови публикации в <span class=\"notification-bold-blue\"><%= name %></span>",
"newMsgParty": "Има нови публикации в групата Ви — <span class=\"notification-bold-blue\"><%= name %></span>",
"chat": "Съобщения",
"sendChat": "Изпращане на съобщението",
"group": "Група",
@@ -151,14 +151,14 @@
"onlyGroupLeaderCanEditTasks": "Нямате право да управлявате задачите!",
"onlyGroupTasksCanBeAssigned": "Само групови задачи могат да бъдат зададени",
"assignedTo": "Назначена на",
"assignedToUser": "Назначена на <strong><%- userName %></strong>",
"assignedToUser": "Назначена на <strong><%= userName %></strong>",
"assignedToMembers": "Назначена на <strong><%= userCount %> членове </strong>",
"assignedToYouAndMembers": "Назначена на Вас и още <strong><%= userCount %> членове</strong>",
"youAreAssigned": "Тази задача е назначена на Вас",
"taskIsUnassigned": "Тази задача не е зададена на никого",
"confirmUnClaim": "Наистина ли искате да оставите тази задача?",
"confirmNeedsWork": "Наистина ли искате да отбележите, че тази задача се нуждае от още работа?",
"userRequestsApproval": "<strong><%- userName %></strong> иска одобрение",
"userRequestsApproval": "<strong><%= userName %></strong> иска одобрение",
"userCountRequestsApproval": "<strong><%= userCount %> членове</strong> искат одобрение",
"youAreRequestingApproval": "Вие искате одобрение",
"chatPrivilegesRevoked": "Не можете да направите това, защото привилегиите Ви в чата са Ви били отнети. За детайли или запитване за връшане на привилегии, моля пратете email на нашия Обществен Оправител на admin@habitica.com или попитайте вашия родител или настойник да им прати email. Моля, напишете и потребителското си име в писмото. Ако модератор вече ви е казал че блокирането ви към чата е временно, няма нужда да пращате email.",
@@ -168,9 +168,9 @@
"claim": "Вземане на Задача",
"removeClaim": "Отказване от задачата",
"onlyGroupLeaderCanManageSubscription": "Само водачът на групата може да управлява абонамента ѝ",
"yourTaskHasBeenApproved": "Задачата Ви <span class=\"notification-green notification-bold\"><%- taskText %></span>, беше одобрена.",
"taskNeedsWork": "<span class=\"notification-bold\"><%- managerName %></span> отбеляза, че задачата <span class=\"notification-bold\"><%- taskText %></span> се нуждае от още работа.",
"userHasRequestedTaskApproval": "<span class=\"notification-bold\"><%- user %></span> помоли следната задача да бъде одобрена: <span class=\"notification-bold\"><%- taskName %></span>",
"yourTaskHasBeenApproved": "Задачата Ви <span class=\"notification-green notification-bold\"><%= taskText %></span>, беше одобрена.",
"taskNeedsWork": "<span class=\"notification-bold\"><%= managerName %></span> отбеляза, че задачата <span class=\"notification-bold\"><%= taskText %></span> се нуждае от още работа.",
"userHasRequestedTaskApproval": "<span class=\"notification-bold\"><%= user %></span> помоли следната задача да бъде одобрена: <span class=\"notification-bold\"><%= taskName %></span>",
"approve": "Одобряване",
"approveTask": "Одобряване на задачата",
"needsWork": "Нуждае се от още работа",
@@ -183,8 +183,8 @@
"userIsClamingTask": "`<%= username %> пое:` <%= task %>",
"approvalRequested": "Заявено е одобрение",
"cantDeleteAssignedGroupTasks": "Не можете да изтриете груповите задачи, които са Ви разпределени.",
"groupPlanUpgraded": "<strong><%- groupName %></strong> премина към групов план!",
"groupPlanCreated": "Групата <strong><%- groupName %></strong> беше създадена!",
"groupPlanUpgraded": "<strong><%= groupName %></strong> премина към групов план!",
"groupPlanCreated": "Групата <strong><%= groupName %></strong> беше създадена!",
"onlyGroupLeaderCanInviteToGroupPlan": "Само водачът на групата може да кани хора в група с абонамент.",
"paymentDetails": "Подробности за разплащането",
"aboutToJoinCancelledGroupPlan": "На път сте да се присъедините към група, чийто план е прекратен. НЯМА да получите безплатен абонамент.",
@@ -325,8 +325,8 @@
"PMDisabled": "Деактивиране на лични съобщения",
"groupActivityNotificationTitle": "<%= user %> публикува в <%= group %>",
"suggestedGroup": "Предложено, защото сте нови в Habitica.",
"taskClaimed": "<%- userName %> взеха задачата <span class=\"notification-bold\"><%- taskText %></span>.",
"youHaveBeenAssignedTask": "<%- managerName %> ви присвои задачата <span class=\"notification-bold\"><%- taskText %></span>.",
"taskClaimed": "<%= userName %> взеха задачата <span class=\"notification-bold\"><%= taskText %></span>.",
"youHaveBeenAssignedTask": "<%= managerName %> ви присвои задачата <span class=\"notification-bold\"><%= taskText %></span>.",
"userWithUsernameOrUserIdNotFound": "Потребителското име или Потребителският Идентификатор не бяха намерени.",
"usernameOrUserId": "Потребителско име или Потребителски Идентификатор",
"sendGiftToWhom": "На кой бихте искали да пратите подарък?",
+2 -2
View File
@@ -82,8 +82,8 @@
"paymentMethods": "Купуване чрез",
"paymentSuccessful": "Плащането Ви беше успешно!",
"paymentYouReceived": "Получихте:",
"paymentYouSentGems": "Изпратихте на <strong><%- name %></strong>:",
"paymentYouSentSubscription": "Изпратихте на <strong><%- name %></strong> <%= months %>-месечен абонамент за Хабитика.",
"paymentYouSentGems": "Изпратихте на <strong><%= name %></strong>:",
"paymentYouSentSubscription": "Изпратихте на <strong><%= name %></strong> <%= months %>-месечен абонамент за Хабитика.",
"paymentSubBilling": "Абонаментът Ви ще бъде таксуван с <strong>$<%= amount %></strong> всеки <strong><%= months %> месеца</strong>.",
"success": "Готово!",
"classGear": "Снаряжение за класа",
+2 -2
View File
@@ -66,8 +66,8 @@
"mountNotOwned": "Не притежавате този прево.",
"feedPet": "Искате ли да дадете <%= text %> на <%= name %>?",
"raisedPet": "Вие отгледахте <%= pet %>!",
"petName": "<%= egg(locale) %> с(ъс) <%= potion(locale) %>",
"mountName": "<%= mount(locale) %> с(ъс) <%= potion(locale) %>",
"petName": "<%= egg %> с(ъс) <%= potion %>",
"mountName": "<%= mount %> с(ъс) <%= potion %>",
"keyToPets": "Ключ от зверилника за любимци",
"keyToPetsDesc": "Освобождаване на всички стандартни любимци, за да можете да ги съберете отново. (Това не засяга любимците от мисии и редките любимци.)",
"keyToMounts": "Ключ от зверилника за превози",
+1 -1
View File
@@ -5,7 +5,7 @@
"keepIt": "Ponechat",
"removeIt": "Odstranit",
"brokenChallenge": "Nefunkční odkaz na výzvu: tento úkol byl součástí výzvy, ale ta (nebo skupina, která ji vytvořila) byla odstraněna. Co chceš dělat s osiřelými úkoly?",
"challengeCompleted": "Výzva byla ukončena a vítězem se stal <span class=\"badge\"><%- user %></span>! Co chceš dělat s osiřelými úkoly?",
"challengeCompleted": "Výzva byla ukončena a vítězem se stal <span class=\"badge\"><%= user %></span>! Co chceš dělat s osiřelými úkoly?",
"unsubChallenge": "Nefunkční odkaz na výzvu: tento úkol byl součástí výzvy, ze které jsi se odhlásil/a. Co chceš dělat s osiřelými úkoly?",
"challenges": "Výzvy",
"endDate": "Končí",
+2 -2
View File
@@ -182,7 +182,7 @@
"questEggVelociraptorText": "Velociraptor",
"questEggVelociraptorMountText": "Velociraptor",
"questEggVelociraptorAdjective": "chytrý",
"eggNotes": "Najdi líhnoucí lektvar, nalij ho na vejce a to se vylíhne v <%= eggAdjective(locale) %> <%= eggText(locale) %>.",
"eggNotes": "Najdi líhnoucí lektvar, nalij ho na vejce a to se vylíhne v <%= eggAdjective %> <%= eggText %>.",
"hatchingPotionBase": "Základní",
"hatchingPotionWhite": "Bílý",
"hatchingPotionDesert": "Pouštní",
@@ -211,7 +211,7 @@
"hatchingPotionGlow": "Ve tmě svítící",
"hatchingPotionFrost": "Zmrzlý",
"hatchingPotionIcySnow": "Ledově Sněhový",
"hatchingPotionNotes": "Nalij ho na vejce a vylíhne se ti <%= potText(locale) %> mazlíček.",
"hatchingPotionNotes": "Nalij ho na vejce a vylíhne se ti <%= potText %> mazlíček.",
"foodMeat": "Maso",
"foodMeatThe": "Maso",
"foodMeatA": "Maso",
+1 -1
View File
@@ -190,7 +190,7 @@
"messages": "Zprávy",
"emptyMessagesLine1": "Nemáš žádné zprávy",
"emptyMessagesLine2": "Novou zprávu uživateli/Česku můžeš poslat tak, že navštívíš jeho/její profil a klikneš na tlačítko “Zprávy”.",
"userSentMessage": "<span class=\"notification-bold\"><%- user %></span> ti poslal/a zprávu",
"userSentMessage": "<span class=\"notification-bold\"><%= user %></span> ti poslal/a zprávu",
"letsgo": "Pojďmě!",
"selected": "Vybrané",
"howManyToBuy": "Kolik by jsi chtěl koupit?",
+15 -15
View File
@@ -24,14 +24,14 @@
"userId": "Uživatelské ID",
"invite": "Pozvat",
"leave": "Odejít",
"invitedToParty": "Byl jsi pozván do družiny <span class=\"notification-bold\"><%- party %></span>",
"invitedToPrivateGuild": "Byl jsi pozván do soukromého cechu <span class=\"notification-bold\"><%- guild %></span>",
"invitedToPublicGuild": "Byl jsi pozván do cechu <span class=\"notification-bold-blue\"><%- guild %></span>",
"invitedToParty": "Byl jsi pozván do družiny <span class=\"notification-bold\"><%= party %></span>",
"invitedToPrivateGuild": "Byl jsi pozván do soukromého cechu <span class=\"notification-bold\"><%= guild %></span>",
"invitedToPublicGuild": "Byl jsi pozván do cechu <span class=\"notification-bold-blue\"><%= guild %></span>",
"invitationAcceptedHeader": "Tvá pozvánka byla přijata",
"invitationAcceptedBody": "<%= username %> přijal tvoji pozvánku do <%= groupName %>!",
"systemMessage": "Systémová zpráva",
"newMsgGuild": "<span class=\"notification-bold-blue\"><%- name %></span> má nový příspěvek",
"newMsgParty": "Tvá družina, <span class=\"notification-bold-blue\"><%- name %></span>, má nový příspěvek",
"newMsgGuild": "<span class=\"notification-bold-blue\"><%= name %></span> má nový příspěvek",
"newMsgParty": "Tvá družina, <span class=\"notification-bold-blue\"><%= name %></span>, má nový příspěvek",
"chat": "Chat",
"sendChat": "Poslat zprávu",
"group": "Skupina",
@@ -151,14 +151,14 @@
"onlyGroupLeaderCanEditTasks": "Not authorized to manage tasks!",
"onlyGroupTasksCanBeAssigned": "Only group tasks can be assigned",
"assignedTo": "Přiřadit k",
"assignedToUser": "Přiřazeno <strong><%- userName %></strong>",
"assignedToUser": "Přiřazeno <strong><%= userName %></strong>",
"assignedToMembers": "Přiřazeno <strong><%= userCount %> members</strong>",
"assignedToYouAndMembers": "Přiřazeno vám a <strong><%= userCount %> members</strong>",
"youAreAssigned": "Jsi přiřazen/a k tomuto úkolu",
"taskIsUnassigned": "This task is unassigned",
"confirmUnClaim": "Are you sure you want to unclaim this task?",
"confirmNeedsWork": "Are you sure you want to mark this task as needing work?",
"userRequestsApproval": "<strong><%- userName %></strong> požaduje schválení",
"userRequestsApproval": "<strong><%= userName %></strong> požaduje schválení",
"userCountRequestsApproval": "<strong><%= userCount %> members</strong> požadují schválení",
"youAreRequestingApproval": "You are requesting approval",
"chatPrivilegesRevoked": "Toto nelze provést, protože vaše oprávnění k chatu byla odstraněna. Chcete-li získat další informace nebo se zeptat, zda lze vaše oprávnění vrátit, pošlete e-mail našemu komunitnímu manažerovi na adrese admin@habitica.com nebo požádejte svého rodiče nebo zákonného zástupce o zaslání e-mailu. Do e-mailu uveďte prosím své @uživatelskéjméno. Pokud vám moderátor již řekl, že váš zákaz chatu je dočasný, nemusíte posílat e-maily.",
@@ -168,9 +168,9 @@
"claim": "Nárokovat úkol",
"removeClaim": "Remove Claim",
"onlyGroupLeaderCanManageSubscription": "Only the group leader can manage the group's subscription",
"yourTaskHasBeenApproved": "Váš úkol <span class=\"notification-green notification-bold\"><%- taskText %></span> byl schválený.",
"taskNeedsWork": "<span class=\"notification-bold\"><%- managerName %></span> marked <span class=\"notification-bold\"><%- taskText %></span> as needing additional work.",
"userHasRequestedTaskApproval": "<span class=\"notification-bold\"><%- user %></span> requests approval for <span class=\"notification-bold\"><%- taskName %></span>",
"yourTaskHasBeenApproved": "Váš úkol <span class=\"notification-green notification-bold\"><%= taskText %></span> byl schválený.",
"taskNeedsWork": "<span class=\"notification-bold\"><%= managerName %></span> marked <span class=\"notification-bold\"><%= taskText %></span> as needing additional work.",
"userHasRequestedTaskApproval": "<span class=\"notification-bold\"><%= user %></span> requests approval for <span class=\"notification-bold\"><%= taskName %></span>",
"approve": "Approve",
"approveTask": "Approve Task",
"needsWork": "Needs Work",
@@ -183,8 +183,8 @@
"userIsClamingTask": "`<%= username %> has claimed:` <%= task %>",
"approvalRequested": "Approval Requested",
"cantDeleteAssignedGroupTasks": "Can't delete group tasks that are assigned to you.",
"groupPlanUpgraded": "<strong><%- groupName %></strong> was upgraded to a Group Plan!",
"groupPlanCreated": "<strong><%- groupName %></strong> was created!",
"groupPlanUpgraded": "<strong><%= groupName %></strong> was upgraded to a Group Plan!",
"groupPlanCreated": "<strong><%= groupName %></strong> was created!",
"onlyGroupLeaderCanInviteToGroupPlan": "Only the group leader can invite users to a group with a subscription.",
"paymentDetails": "Payment Details",
"aboutToJoinCancelledGroupPlan": "You are about to join a group with a canceled plan. You will NOT receive a free subscription.",
@@ -321,8 +321,8 @@
"allAssignedCompletion": "All - Completes when all assigned users finish",
"groupActivityNotificationTitle": "<%= user %> publikoval v <%= group %>",
"suggestedGroup": "Navrženo, protože jste v Habitica nový/á.",
"taskClaimed": "<%- userName %> nárokoval úkol <span class=\"notification-bold\"><%- taskText %></span>.",
"youHaveBeenAssignedTask": "<%- managerName %> vám přidělil úkol <span class=\"notification-bold\"><%- taskText %></span>.",
"taskClaimed": "<%= userName %> nárokoval úkol <span class=\"notification-bold\"><%= taskText %></span>.",
"youHaveBeenAssignedTask": "<%= managerName %> vám přidělil úkol <span class=\"notification-bold\"><%= taskText %></span>.",
"pmReported": "Děkujeme za nahlášení této zprávy.",
"newPartyPlaceholder": "Zadej jméno tvé družiny.",
"userWithUsernameOrUserIdNotFound": "Uživatelské jméno nebo uživatelské ID nebylo nalezeno.",
@@ -336,7 +336,7 @@
"PMDisabled": "Zakaž soukromé zprávy",
"unassigned": "Nepřiřazeno",
"claimRewards": "Vyzvedni si odměnu",
"assignedDateAndUser": "Přiřazeno uživatelem/kou <strong>@<%- username %></strong> dne <strong><%= date %></strong>",
"assignedDateAndUser": "Přiřazeno uživatelem/kou <strong>@<%= username %></strong> dne <strong><%= date %></strong>",
"assignedDateOnly": "Přiřazeno k <strong><%= date %></strong>",
"managerNotes": "Poznámky manažera",
"thisTaskApproved": "Tento úkol byl schválen",
+2 -2
View File
@@ -82,8 +82,8 @@
"paymentMethods": "Platební metody",
"paymentSuccessful": "Tvá platba proběhla úspěšně!",
"paymentYouReceived": "Obdržel jsi:",
"paymentYouSentGems": "Poslal/a jsi <strong><%- name %></strong>:",
"paymentYouSentSubscription": "Poslal/a jsi <strong><%- name %></strong> předplatné na <%= months %>-měsíce/ů v Habitica.",
"paymentYouSentGems": "Poslal/a jsi <strong><%= name %></strong>:",
"paymentYouSentSubscription": "Poslal/a jsi <strong><%= name %></strong> předplatné na <%= months %>-měsíce/ů v Habitica.",
"paymentSubBilling": "Tvoje předplatné ve výši <strong>$<%= amount %></strong> bude účtovano každé/ých <strong><%= months %> měsíce/ů </strong>.",
"success": "Úspěch!",
"classGear": "Vybavení pro tvé povolání",
+2 -2
View File
@@ -66,8 +66,8 @@
"mountNotOwned": "Nevlastníš toto jezdecké zvíře.",
"feedPet": "Dát <%= text %> svému <%= name %>?",
"raisedPet": "Vychoval jsi svého <%= pet %>!",
"petName": "<%= potion(locale) %> <%= egg(locale) %>",
"mountName": "<%= potion(locale) %> <%= mount(locale) %>",
"petName": "<%= potion %> <%= egg %>",
"mountName": "<%= potion %> <%= mount %>",
"keyToPets": "Klíč ke Kotcům Mazlíčků",
"keyToPetsDesc": "Propusť všechny své běžné mazlíčky abys je mohl sbírat znovu. (Ti vzácní a z výprav tím nebudou ovlivněni.)",
"keyToMounts": "Klíč ke Kotcům Zvířat",
+1 -1
View File
@@ -5,7 +5,7 @@
"keepIt": "Behold den",
"removeIt": "Fjern den",
"brokenChallenge": "Defekt udfordringslink: denne opgave var en del af en udfordring, men udfordringen (eller gruppen) er blevet fjernet. Hvad vil du gøre med de gruppeløse opgaver?",
"challengeCompleted": "Denne udfordring er afsluttet, og vinderen blev <span class=\"badge\"><%- user %></span>! Hvad vil du gøre med de gruppeløse opgaver?",
"challengeCompleted": "Denne udfordring er afsluttet, og vinderen blev <span class=\"badge\"><%= user %></span>! Hvad vil du gøre med de gruppeløse opgaver?",
"unsubChallenge": "Defekt Udfordringslink: denne opgave var en del af en udfordring, som du ikke længere abonnerer på. Hvad vil du gøre med de gruppeløse opgaver?",
"challenges": "Udfordringer",
"endDate": "Afsluttes",
+2 -2
View File
@@ -182,7 +182,7 @@
"questEggVelociraptorText": "Velociraptor",
"questEggVelociraptorMountText": "Velociraptor",
"questEggVelociraptorAdjective": "en vaks",
"eggNotes": "Find en udrugningseliksir til at hælde på dit æg, og det vil udklække <%= eggAdjective(locale) %> <%= eggText(locale) %>.",
"eggNotes": "Find en udrugningseliksir til at hælde på dit æg, og det vil udklække <%= eggAdjective %> <%= eggText %>.",
"hatchingPotionBase": "Almindelig",
"hatchingPotionWhite": "Hvid",
"hatchingPotionDesert": "Ørken",
@@ -211,7 +211,7 @@
"hatchingPotionGlow": "Selvlysende",
"hatchingPotionFrost": "Frost",
"hatchingPotionIcySnow": "Isnende sne",
"hatchingPotionNotes": "Hæld denne over et æg, og det vil udklækkes til et <%= potText(locale) %> kæledyr.",
"hatchingPotionNotes": "Hæld denne over et æg, og det vil udklækkes til et <%= potText %> kæledyr.",
"foodMeat": "Kød",
"foodMeatThe": "Kødet",
"foodMeatA": "Kød",
+1 -1
View File
@@ -190,7 +190,7 @@
"messages": "Beskeder",
"emptyMessagesLine1": "Du har ingen beskeder",
"emptyMessagesLine2": "Du kan sende en ny besked til en bruger ved at besøge deres profil og klikke på \"Besked\"-knappen.",
"userSentMessage": "<span class=\"notification-bold\"><%- user %></span> sendte en besked",
"userSentMessage": "<span class=\"notification-bold\"><%= user %></span> sendte en besked",
"letsgo": "Lad os komme i gang!",
"selected": "Valgt",
"howManyToBuy": "Hvor mange vil du købe?",
+13 -13
View File
@@ -24,14 +24,14 @@
"userId": "Bruger-ID",
"invite": "Invitér",
"leave": "Forlad",
"invitedToParty": "Du blev inviteret til at være med på Holdet <span class=\"notification-bold\"><%- party %></span>",
"invitedToPrivateGuild": "Du blev inviteret til den private Klan <span class=\"notification-bold\"><%- guild %></span>",
"invitedToPublicGuild": "Du blev inviteret til Klanen <span class=\"notification-bold-blue\"><%- guild %></span>",
"invitedToParty": "Du blev inviteret til at være med på Holdet <span class=\"notification-bold\"><%= party %></span>",
"invitedToPrivateGuild": "Du blev inviteret til den private Klan <span class=\"notification-bold\"><%= guild %></span>",
"invitedToPublicGuild": "Du blev inviteret til Klanen <span class=\"notification-bold-blue\"><%= guild %></span>",
"invitationAcceptedHeader": "Din invitation blev accepteret",
"invitationAcceptedBody": "<%= username %> har accepteret din invitation til <%= groupName %>!",
"systemMessage": "Systembesked",
"newMsgGuild": "<span class=\"notification-bold-blue\"><%- name %></span> har nye indlæg",
"newMsgParty": "Dit Hold, <span class=\"notification-bold-blue\"><%- name %></span>, har nye indlæg",
"newMsgGuild": "<span class=\"notification-bold-blue\"><%= name %></span> har nye indlæg",
"newMsgParty": "Dit Hold, <span class=\"notification-bold-blue\"><%= name %></span>, har nye indlæg",
"chat": "Chat",
"sendChat": "Send besked",
"group": "Gruppe",
@@ -151,14 +151,14 @@
"onlyGroupLeaderCanEditTasks": "Du har ikke rettigheder til at administrere opgaver!",
"onlyGroupTasksCanBeAssigned": "Kun gruppeopgaver kan blive tildelt",
"assignedTo": "Tildelt",
"assignedToUser": "Tildelt <%- userName %>",
"assignedToUser": "Tildelt <%= userName %>",
"assignedToMembers": "Tildelt <%= userCount %> medlemmer",
"assignedToYouAndMembers": "Tildelt dig og <%= userCount %> medlemmer",
"youAreAssigned": "Du er blevet bedt om at udføre denne opgave",
"taskIsUnassigned": "Denne opgave er ikke tildelt nogen",
"confirmUnClaim": "Er du sikker på, du vil give afkald på denne opgave?",
"confirmNeedsWork": "Er du sikker på, du vil markere denne opgave som ufuldstændig?",
"userRequestsApproval": "<%- userName %> anmoder om godkendelse",
"userRequestsApproval": "<%= userName %> anmoder om godkendelse",
"userCountRequestsApproval": "<%= userCount %> medlemmer anmoder om godkendelse",
"youAreRequestingApproval": "Du har anmodet om godkendelse",
"chatPrivilegesRevoked": "Dine chatprivilegier er blevet inddraget, så du kan ikke udføre denne handling.",
@@ -168,9 +168,9 @@
"claim": "Gør krav på",
"removeClaim": "Giv afkald på",
"onlyGroupLeaderCanManageSubscription": "Kun gruppelederen kan styre gruppens abonnement",
"yourTaskHasBeenApproved": "Din opgave, <span class=\"notification-green\"><%- taskText %></span>, er blevet godkendt.",
"taskNeedsWork": "<span class=\"notification-bold\"><%- managerName %></span> markerede <span class=\"notification-bold\"><%- taskText %></span> som ufuldstændig.",
"userHasRequestedTaskApproval": "<span class=\"notification-bold\"><%- user %></span> anmoder om godkendelse for <span class=\"notification-bold\"><%- taskName %></span>",
"yourTaskHasBeenApproved": "Din opgave, <span class=\"notification-green\"><%= taskText %></span>, er blevet godkendt.",
"taskNeedsWork": "<span class=\"notification-bold\"><%= managerName %></span> markerede <span class=\"notification-bold\"><%= taskText %></span> som ufuldstændig.",
"userHasRequestedTaskApproval": "<span class=\"notification-bold\"><%= user %></span> anmoder om godkendelse for <span class=\"notification-bold\"><%= taskName %></span>",
"approve": "Godkend",
"approveTask": "Godkend opgave",
"needsWork": "Ufuldstændig",
@@ -183,8 +183,8 @@
"userIsClamingTask": "`<%= username %> har gjort krav på:` <%= task %>",
"approvalRequested": "Godkendelse efterspurgt",
"cantDeleteAssignedGroupTasks": "Du kan ikke slette gruppeopgaver, der er blevet tildelt dig.",
"groupPlanUpgraded": "<strong><%- groupName %></strong> blev opgraderet til en Gruppeplan!",
"groupPlanCreated": "<strong><%- groupName %></strong> blev oprettet!",
"groupPlanUpgraded": "<strong><%= groupName %></strong> blev opgraderet til en Gruppeplan!",
"groupPlanCreated": "<strong><%= groupName %></strong> blev oprettet!",
"onlyGroupLeaderCanInviteToGroupPlan": "Kun gruppelederen kan invitere brugere til en gruppe med et abonnement.",
"paymentDetails": "Betalingsdetaljer",
"aboutToJoinCancelledGroupPlan": "Du er ved at slutte dig til en gruppe med en opsagt gruppeplan. Du vil IKKE få et gratis abonnement.",
@@ -321,7 +321,7 @@
"allAssignedCompletion": "All - Completes when all assigned users finish",
"pmReported": "Tak, fordi du rapporterede denne besked.",
"features": "Funktioner",
"invitedToPartyBy": "<a href=\"/profile/<%- userId %>\" target=\"_blank\">@<%- userName %></a> har inviteret dig til holdet <span class=\"notification-bold\"><%- party %></span>",
"invitedToPartyBy": "<a href=\"/profile/<%= userId %>\" target=\"_blank\">@<%= userName %></a> har inviteret dig til holdet <span class=\"notification-bold\"><%= party %></span>",
"PMUserDoesNotReceiveMessages": "Denne bruger modtager ikke længere private beskeder",
"blockedToSendToThisUser": "Du kan ikke sende til denne spiller da du har blokeret denne spiller.",
"blockYourself": "Du kan ikke blokere dig selv",
+2 -2
View File
@@ -82,8 +82,8 @@
"paymentMethods": "Køb med",
"paymentSuccessful": "Din betaling gik igennem!",
"paymentYouReceived": "Du modtog:",
"paymentYouSentGems": "Du sendte <strong><%- name %></strong>:",
"paymentYouSentSubscription": "Du sendte <strong><%- name %></strong> et <%= months %>-måneders Habitica-abonnement.",
"paymentYouSentGems": "Du sendte <strong><%= name %></strong>:",
"paymentYouSentSubscription": "Du sendte <strong><%= name %></strong> et <%= months %>-måneders Habitica-abonnement.",
"paymentSubBilling": "Betalingen for dit abonnement vil blive trukket <strong>$<%= amount %></strong> hver <strong><%= months %> måneder</strong>.",
"success": "Succes!",
"classGear": "Klasseudstyr",
+2 -2
View File
@@ -66,8 +66,8 @@
"mountNotOwned": "Du ejer ikke dette ridedyr.",
"feedPet": "Giv <%= text %> til din <%= name %>?",
"raisedPet": "Du har opdrættet din/dit <%= pet %>!",
"petName": "<%= potion(locale) %> <%= egg(locale) %>",
"mountName": "<%= potion(locale) %>-<%= mount(locale) %>",
"petName": "<%= potion %> <%= egg %>",
"mountName": "<%= potion %>-<%= mount %>",
"keyToPets": "Nøgle til Kæledyrskennelen",
"keyToPetsDesc": "Sæt alle standardkæledyrene fri, så du kan samle dem igen. (Kæledyr fra quests og sjældne kæledyr påvirkes ikke.)",
"keyToMounts": "Nøgle til Ridedyrskennelen",
+1 -1
View File
@@ -111,6 +111,6 @@
"deleteChallengeRefundDescription": "Wenn du diese Herausforderung löschst, bekommst du den Preis in Edelsteinen erstattet und die Aufgaben der Herausforderung verbleiben auf der Aufgabentafel der Teilnehmer.",
"brokenTaskDescription": "Diese Aufgabe war Teil einer Herausforderung, wurde jedoch daraus entfernt. Was möchtest Du tun?",
"brokenChallengeDescription": "Diese Aufgabe war Teil einer Herausforderung, aber die Herausforderung (oder Gruppe) wurde gelöscht. Was soll mit den verwaisten Aufgaben geschehen?",
"challengeCompletedDescription": "Gewonnen hat <%- user %>! Was soll mit den verwaisten Aufgaben geschehen?",
"challengeCompletedDescription": "Gewonnen hat <%= user %>! Was soll mit den verwaisten Aufgaben geschehen?",
"brokenTask": "Defekter Link zur Herausforderung"
}
+3 -3
View File
@@ -182,7 +182,7 @@
"questEggVelociraptorText": "Velociraptor-Haustier",
"questEggVelociraptorMountText": "Velociraptor-Reittier",
"questEggVelociraptorAdjective": "ein cleveres",
"eggNotes": "Finde ein Schlüpfelixier, das Du über dieses Ei gießen kannst, damit ein <%= eggAdjective(locale) %> <%= eggText(locale) %> schlüpfen kann.",
"eggNotes": "Finde ein Schlüpfelixier, das Du über dieses Ei gießen kannst, damit ein <%= eggAdjective %> <%= eggText %> schlüpfen kann.",
"hatchingPotionBase": "Normales",
"hatchingPotionWhite": "Weißes",
"hatchingPotionDesert": "Wüstenfarbenes",
@@ -211,7 +211,7 @@
"hatchingPotionGlow": "Fluoreszierendes",
"hatchingPotionFrost": "Frostiges",
"hatchingPotionIcySnow": "Eisschnee",
"hatchingPotionNotes": "Gieße dies über ein Ei und es wird ein <%= potText(locale) %> Haustier daraus schlüpfen.",
"hatchingPotionNotes": "Gieße dies über ein Ei und es wird ein <%= potText %> Haustier daraus schlüpfen.",
"foodMeat": "Fleisch",
"foodMeatThe": "das Fleisch",
"foodMeatA": "Fleisch",
@@ -406,7 +406,7 @@
"hatchingPotionBalloon": "Ballon",
"wackyPotionAddlNotes": "Kann nicht zum Reittier großgezogen oder für Quest-Haustier Eier benutzt werden.",
"hatchingPotionCryptid": "Kryptisch",
"wackyPotionNotes": "Schütte dies über ein Ei und es wird als Durchgeknalltes <%= potText(locale) %> Haustier schlüpfen.",
"wackyPotionNotes": "Schütte dies über ein Ei und es wird als Durchgeknalltes <%= potText %> Haustier schlüpfen.",
"questEggPlatypusText": "Schnabeltier",
"questEggPlatypusMountText": "Schnabeltier",
"questEggPlatypusAdjective": "ein Perfektionist",
+1 -1
View File
@@ -190,7 +190,7 @@
"messages": "Nachrichten",
"emptyMessagesLine1": "Du hast im Moment keine Nachrichten",
"emptyMessagesLine2": "Sende eine Nachricht, um eine Konversation mit Mitgliedern deiner Gruppe oder anderen Habitica Spielern zu beginnen",
"userSentMessage": "<span class=\"notification-bold\"><%- user %></span> hat Dir eine Nachricht gesendet",
"userSentMessage": "<span class=\"notification-bold\"><%= user %></span> hat Dir eine Nachricht gesendet",
"letsgo": "Auf geht's!",
"selected": "Ausgewählt",
"howManyToBuy": "Wie viele möchtest Du kaufen?",
+16 -16
View File
@@ -24,14 +24,14 @@
"userId": "Benutzer-ID",
"invite": "Einladen",
"leave": "Verlassen",
"invitedToParty": "Du wurdest in die Party <span class=\"notification-bold\"><%- party %></span> eingeladen",
"invitedToPrivateGuild": "Du wurdest eingeladen, der privaten Gruppe<span class=\"notification-bold\"><%- guild %></span> beizutreten",
"invitedToPublicGuild": "Du wurdest eingeladen, der Gruppe<span class=\"notification-bold-blue\"><%- guild %></span> beizutreten",
"invitedToParty": "Du wurdest in die Party <span class=\"notification-bold\"><%= party %></span> eingeladen",
"invitedToPrivateGuild": "Du wurdest eingeladen, der privaten Gruppe<span class=\"notification-bold\"><%= guild %></span> beizutreten",
"invitedToPublicGuild": "Du wurdest eingeladen, der Gruppe<span class=\"notification-bold-blue\"><%= guild %></span> beizutreten",
"invitationAcceptedHeader": "Deine Einladung wurde angenommen",
"invitationAcceptedBody": "<%= username %> hat Deine Einladung zu <%= groupName %> angenommen!",
"systemMessage": "Systemmeldung",
"newMsgGuild": "<span class=\"notification-bold-blue\"><%- name %></span> hat neue Beiträge",
"newMsgParty": "Deine Party, <span class=\"notification-bold-blue\"><%- name %></span>, hat neue Beiträge",
"newMsgGuild": "<span class=\"notification-bold-blue\"><%= name %></span> hat neue Beiträge",
"newMsgParty": "Deine Party, <span class=\"notification-bold-blue\"><%= name %></span>, hat neue Beiträge",
"chat": "Chat",
"sendChat": "Nachricht senden",
"group": "Gruppe",
@@ -151,14 +151,14 @@
"onlyGroupLeaderCanEditTasks": "Nicht berechtigt, Aufgaben zu bearbeiten!",
"onlyGroupTasksCanBeAssigned": "Nur Team-Aufgaben können verteilt werden",
"assignedTo": "Zugewiesen an",
"assignedToUser": "Zugewiesen: <strong>@<%- userName %></strong>",
"assignedToUser": "Zugewiesen: <strong>@<%= userName %></strong>",
"assignedToMembers": "<%= userCount %> Mitgliedern",
"assignedToYouAndMembers": "<strong>Dir</strong>, <%= userCount %> Mitgliedern",
"youAreAssigned": "Zugewiesen: <strong>Dir</strong>",
"taskIsUnassigned": "Diese Aufgabe ist niemandem zugewiesen",
"confirmUnClaim": "Bist Du sicher, dass Du diese Aufgabe abgeben möchtest?",
"confirmNeedsWork": "Bist Du sicher, dass Du diese Aufgabe auf \"Benötigt Arbeit\" setzen möchtest?",
"userRequestsApproval": "<strong><%- userName %></strong> beantragt eine Bestätigung",
"userRequestsApproval": "<strong><%= userName %></strong> beantragt eine Bestätigung",
"userCountRequestsApproval": "<strong><%= userCount %> Mitglieder</strong> beantragen eine Bestätigung",
"youAreRequestingApproval": "Du beantragst eine Bestätigung",
"chatPrivilegesRevoked": "Du kannst dies nicht tun, da Dir Deine Chat-Privilegien entzogen wurden. Für genauere Angaben oder um zu fragen, ob Dir Deine Chat-Privilegien zurückgegeben werden können, schreibe bitte eine E-Mail an den Community-Manager unter admin@habitica.com oder bitte Deine Eltern diese E-Mail zu schreiben. Bitte gib Deinen @Usernamen in der E-Mail an. Falls ein Moderator Dir bereits mitgeteilt hat, dass diese Sperre zeitlich begrenzt ist, brauchst Du keine E-Mail zu schreiben.",
@@ -168,9 +168,9 @@
"claim": "Aufgabe übernehmen",
"removeClaim": "Aufgabe abtreten",
"onlyGroupLeaderCanManageSubscription": "Nur der Gruppenleiter kann Gruppen-Registrierungen verwalten",
"yourTaskHasBeenApproved": "Deiner Aufgabe <span class=\"notification-green notification-bold\"><%- taskText %></span> wurde Zustimmung erteilt.",
"taskNeedsWork": "<span class=\"notification-bold\"><%- managerName %></span> hat <span class=\"notification-bold\"><%- taskText %></span> als unfertig markiert.",
"userHasRequestedTaskApproval": "<span class=\"notification-bold\"><%- user %></span> bittet um Zustimmung für <span class=\"notification-bold\"><%- taskName %></span>",
"yourTaskHasBeenApproved": "Deiner Aufgabe <span class=\"notification-green notification-bold\"><%= taskText %></span> wurde Zustimmung erteilt.",
"taskNeedsWork": "<span class=\"notification-bold\"><%= managerName %></span> hat <span class=\"notification-bold\"><%= taskText %></span> als unfertig markiert.",
"userHasRequestedTaskApproval": "<span class=\"notification-bold\"><%= user %></span> bittet um Zustimmung für <span class=\"notification-bold\"><%= taskName %></span>",
"approve": "Zustimmen",
"approveTask": "Aufgabe zustimmen",
"needsWork": "Benötigt Arbeit",
@@ -183,8 +183,8 @@
"userIsClamingTask": "`<%= username %> beansprucht:` <%= task %>",
"approvalRequested": "Zustimmung erbeten",
"cantDeleteAssignedGroupTasks": "Du kannst Gruppen-Aufgaben, die Dir zugewiesen wurden, nicht löschen.",
"groupPlanUpgraded": "<strong><%- groupName %></strong> wurde erfolgreich auf einen Gruppenplan hochgestuft!",
"groupPlanCreated": "<strong><%- groupName %></strong> wurde erstellt!",
"groupPlanUpgraded": "<strong><%= groupName %></strong> wurde erfolgreich auf einen Gruppenplan hochgestuft!",
"groupPlanCreated": "<strong><%= groupName %></strong> wurde erstellt!",
"onlyGroupLeaderCanInviteToGroupPlan": "Nur der Gruppenleiter kann Nutzer zu einer Gruppe mit einem Abonnement hinzufügen.",
"paymentDetails": "Zahlungsinformationen",
"aboutToJoinCancelledGroupPlan": "Du bist dabei einer Gruppe mit gekündigtem Plan beizutreten. Du erhältst KEIN freies Abonnement.",
@@ -321,8 +321,8 @@
"allAssignedCompletion": "Alle Ist erledigt, sobald alle zugeteilten Benutzer abschliessen",
"pmReported": "Danke dass Du diese Nachricht gemeldet hast.",
"suggestedGroup": "Vorgeschlagen weil Du bei Habitica neu bist.",
"taskClaimed": "<%- userName %> hat die Aufgabe <span class=\"notification-bold\"><%- taskText %></span> übernommen.",
"youHaveBeenAssignedTask": "<%- managerName %> hat Dir die Aufgabe <span class=\"notification-bold\"><%- taskText %></span> zugeteilt.",
"taskClaimed": "<%= userName %> hat die Aufgabe <span class=\"notification-bold\"><%= taskText %></span> übernommen.",
"youHaveBeenAssignedTask": "<%= managerName %> hat Dir die Aufgabe <span class=\"notification-bold\"><%= taskText %></span> zugeteilt.",
"groupActivityNotificationTitle": "<%= user %> hat in <%= group %> gepostet",
"blockedToSendToThisUser": "Du kannst dieser Person nicht schreiben, weil Du diese Person blockiert hast.",
"PMDisabled": "Private Nachrichten deaktivieren",
@@ -337,7 +337,7 @@
"chooseTeamMember": "Wähle ein Teammitglied",
"unassigned": "Nicht zugewiesen",
"claimRewards": "Belohnung einfordern",
"assignedDateAndUser": "Zugewiesen am <strong><%= date %></strong> von <strong>@<%- username %></strong>",
"assignedDateAndUser": "Zugewiesen am <strong><%= date %></strong> von <strong>@<%= username %></strong>",
"assignedDateOnly": "Zugewiesen am <strong><%= date %></strong>",
"managerNotes": "Manager-Notizen",
"thisTaskApproved": "Dieser Aufgabe wurde zugestimmt",
@@ -399,7 +399,7 @@
"bannedUser": "<strong>Dieser Spieler wurde gebannt.</strong>",
"questWithOthers": "Übernimm Missionen mit anderen",
"sendTotal": "Gesamt:",
"invitedToPartyBy": "<a href=\"/profile/<%- userId %>\" target=\"_blank\">@<%- userName %></a> hat dich eingeladen, der Party beizutreten <span class=\"notification-bold\"><%- party %></span>",
"invitedToPartyBy": "<a href=\"/profile/<%= userId %>\" target=\"_blank\">@<%= userName %></a> hat dich eingeladen, der Party beizutreten <span class=\"notification-bold\"><%= party %></span>",
"partyExceedsInvitesLimit": "Eine Party kann nur bis zu <%= maxInvites %> ausstehende Einladungen haben.",
"lookForParty": "Suche eine Party",
"currentlyLookingForParty": "Du suchst nach einer Party!",
+3 -3
View File
@@ -82,8 +82,8 @@
"paymentMethods": "Kauf mit",
"paymentSuccessful": "Die Zahlung war erfolgreich!",
"paymentYouReceived": "Du hast erhalten:",
"paymentYouSentGems": "Du hast <strong><%- name %></strong> geschickt:",
"paymentYouSentSubscription": "Du hast <strong><%- name %></strong><br> ein <%= months %>-Monate-Abo für Habitica geschickt.",
"paymentYouSentGems": "Du hast <strong><%= name %></strong> geschickt:",
"paymentYouSentSubscription": "Du hast <strong><%= name %></strong><br> ein <%= months %>-Monate-Abo für Habitica geschickt.",
"paymentSubBilling": "Dein Abonnement wird mit <strong>$<%= amount %></strong> alle <strong><%= months %> Monate</strong> verrechnet.",
"success": "Erfolg!",
"classGear": "Klassenausrüstung",
@@ -129,5 +129,5 @@
"sellItems": "Items verkaufen",
"customizationsShopText": "Willst du deinen Style ändern? Hier bist du richtig! Wir haben die frischesten Looks, passend zur Saison, auf Lager.",
"notAvailable": "Dieser Gegenstand ist nicht verfügbar.",
"paymentYouSentSubscriptionG1G1": "Du hast <strong><%- name %></strong><br> ein <%= months %>-Monat(e)-Abo für Habitica geschickt und dasselbe Abo wurde deinem Account im Zuge der \"Schenk' Eins, Bekomm' Eins\"-Aktion gutgeschrieben!"
"paymentYouSentSubscriptionG1G1": "Du hast <strong><%= name %></strong><br> ein <%= months %>-Monat(e)-Abo für Habitica geschickt und dasselbe Abo wurde deinem Account im Zuge der \"Schenk' Eins, Bekomm' Eins\"-Aktion gutgeschrieben!"
}
+2 -2
View File
@@ -66,8 +66,8 @@
"mountNotOwned": "Du besitzt dieses Reittier nicht.",
"feedPet": "<%= text %> an <%= name %> verfüttern?",
"raisedPet": "Du hast ein <%= pet %> aufgezogen!",
"petName": "<%= potion(locale) %> <%= egg(locale) %>",
"mountName": "<%= potion(locale) %> <%= mount(locale) %>",
"petName": "<%= potion %> <%= egg %>",
"mountName": "<%= potion %> <%= mount %>",
"keyToPets": "Schlüssel zu den Haustier-Zwingern",
"keyToPetsDesc": "Lässt alle Standard-Haustiere frei, so dass Du sie erneut sammeln kannst. (Quest- und seltene Haustiere sind nicht betroffen.)",
"keyToMounts": "Schlüssel zu den Reittier-Zwingern",
+1 -1
View File
@@ -10,7 +10,7 @@
"brokenChallenge": "Broken Challenge Link",
"brokenChallengeDescription": "This task was part of a challenge, but the challenge (or group) has been deleted. What to do with the orphan tasks?",
"challengeCompleted": "Challenge Completed!",
"challengeCompletedDescription": "The winner was <%- user %>! What to do with the orphan tasks?",
"challengeCompletedDescription": "The winner was <%= user %>! What to do with the orphan tasks?",
"unsubChallenge": "Broken Challenge Link: this task was part of a challenge, but you have unsubscribed from the challenge. What to do with the orphan tasks?",
"challenges": "Challenges",
"endDate": "Ends",
+3 -3
View File
@@ -287,7 +287,7 @@
"questEggPlatypusMountText": "Platypus",
"questEggPlatypusAdjective": "a perfectionist",
"eggNotes": "Find a hatching potion to pour on this egg, and it will hatch into <%= eggAdjective(locale) %> <%= eggText(locale) %>.",
"eggNotes": "Find a hatching potion to pour on this egg, and it will hatch into <%= eggAdjective %> <%= eggText %>.",
"hatchingPotionBase": "Base",
"hatchingPotionWhite": "White",
@@ -357,9 +357,9 @@
"hatchingPotionCryptid": "Cryptid",
"hatchingPotionOpal": "Opal",
"hatchingPotionNotes": "Pour this on an egg, and it will hatch as a <%= potText(locale) %> Pet.",
"hatchingPotionNotes": "Pour this on an egg, and it will hatch as a <%= potText %> Pet.",
"premiumPotionUnlimitedNotes": "Not usable on Quest Pet eggs.",
"wackyPotionNotes": "Pour this on an egg, and it will hatch as a Wacky <%= potText(locale) %> Pet.",
"wackyPotionNotes": "Pour this on an egg, and it will hatch as a Wacky <%= potText %> Pet.",
"wackyPotionAddlNotes": "Cannot be raised to Mounts or used on Quest Pet eggs.",
"foodMeat": "Meat",
+1 -1
View File
@@ -210,7 +210,7 @@
"emptyMessagesLine1": "You don't have any messages",
"emptyMessagesLine2": "Send a message to start a conversation with your Party members or another Habitica player",
"newMessage": "New Message",
"userSentMessage": "<span class=\"notification-bold\"><%- user %></span> sent you a message",
"userSentMessage": "<span class=\"notification-bold\"><%= user %></span> sent you a message",
"letsgo": "Let's Go!",
"selected": "Selected",
"howManyToBuy": "How many would you like to purchase?",
+29 -17
View File
@@ -27,15 +27,15 @@
"userId": "User ID",
"invite": "Invite",
"leave": "Leave",
"invitedToParty": "You were invited to join the Party <span class=\"notification-bold\"><%- party %></span>",
"invitedToPartyBy": "<a href=\"/profile/<%- userId %>\" target=\"_blank\">@<%- userName %></a> has invited you to join the Party <span class=\"notification-bold\"><%- party %></span>",
"invitedToPrivateGuild": "You were invited to join the private Group <span class=\"notification-bold\"><%- guild %></span>",
"invitedToPublicGuild": "You were invited to join the Group <span class=\"notification-bold-blue\"><%- guild %></span>",
"invitedToParty": "You were invited to join the Party <span class=\"notification-bold\"><%= party %></span>",
"invitedToPartyBy": "<a href=\"/profile/<%= userId %>\" target=\"_blank\">@<%= userName %></a> has invited you to join the Party <span class=\"notification-bold\"><%= party %></span>",
"invitedToPrivateGuild": "You were invited to join the private Group <span class=\"notification-bold\"><%= guild %></span>",
"invitedToPublicGuild": "You were invited to join the Group <span class=\"notification-bold-blue\"><%= guild %></span>",
"invitationAcceptedHeader": "Your Invitation has been Accepted",
"invitationAcceptedBody": "<%= username %> accepted your invitation to <%= groupName %>!",
"systemMessage": "System Message",
"newMsgGuild": "<span class=\"notification-bold-blue\"><%- name %></span> has new posts",
"newMsgParty": "Your Party, <span class=\"notification-bold-blue\"><%- name %></span>, has new posts",
"newMsgGuild": "<span class=\"notification-bold-blue\"><%= name %></span> has new posts",
"newMsgParty": "Your Party, <span class=\"notification-bold-blue\"><%= name %></span>, has new posts",
"chat": "Chat",
"sendChat": "Send Chat",
"group": "Group",
@@ -184,7 +184,7 @@
"onlyGroupTasksCanBeAssigned": "Only group tasks can be assigned",
"assignTo": "Assign To",
"assignedTo": "Assigned to",
"assignedToUser": "Assigned: <strong>@<%- userName %></strong>",
"assignedToUser": "Assigned: <strong>@<%= userName %></strong>",
"assignedToMembers": "<%= userCount %> users",
"assignedToYouAndMembers": "<strong>You</strong>, <%= userCount %> users",
"youAreAssigned": "Assigned: <strong>you</strong>",
@@ -193,7 +193,7 @@
"chooseTeamMember": "Search for a team member",
"confirmUnClaim": "Are you sure you want to unclaim this task?",
"confirmNeedsWork": "Are you sure you want to mark this task as needing work?",
"userRequestsApproval": "<strong><%- userName %></strong> requests approval",
"userRequestsApproval": "<strong><%= userName %></strong> requests approval",
"userCountRequestsApproval": "<strong><%= userCount %> members</strong> request approval",
"youAreRequestingApproval": "You are requesting approval",
"chatPrivilegesRevoked": "You cannot do this because your chat privileges have been removed. For details or to ask if your privileges can be returned, please email our Community Manager at admin@habitica.com or ask your parent or guardian to email them. Please include your @Username in the email. If a moderator has already told you that your chat ban is temporary, you do not need to send an email.",
@@ -204,12 +204,12 @@
"removeClaim": "Remove Claim",
"onlyGroupLeaderCanManageSubscription": "Only the group leader can manage the group's subscription",
"onlyPrivateGuildsCanUpgrade": "Only private guilds can be upgraded to a group plan.",
"youHaveBeenAssignedTask": "<%- managerName %> has assigned you the task <span class=\"notification-bold\"><%- taskText %></span>.",
"yourTaskHasBeenApproved": "Your task <span class=\"notification-green notification-bold\"><%- taskText %></span> has been approved.",
"youHaveBeenAssignedTask": "<%= managerName %> has assigned you the task <span class=\"notification-bold\"><%= taskText %></span>.",
"yourTaskHasBeenApproved": "Your task <span class=\"notification-green notification-bold\"><%= taskText %></span> has been approved.",
"thisTaskApproved": "This task was approved",
"taskClaimed": "<%- userName %> has claimed the task <span class=\"notification-bold\"><%- taskText %></span>.",
"taskNeedsWork": "<span class=\"notification-bold\"><%- taskText %></span> was unchecked by <span class=\"notification-bold\">@<%- managerName %></span>. Your rewards for completing the task were reverted.",
"userHasRequestedTaskApproval": "<span class=\"notification-bold\"><%- user %></span> requests approval for <span class=\"notification-bold\"><%- taskName %></span>",
"taskClaimed": "<%= userName %> has claimed the task <span class=\"notification-bold\"><%= taskText %></span>.",
"taskNeedsWork": "<span class=\"notification-bold\"><%= taskText %></span> was unchecked by <span class=\"notification-bold\">@<%= managerName %></span>. Your rewards for completing the task were reverted.",
"userHasRequestedTaskApproval": "<span class=\"notification-bold\"><%= user %></span> requests approval for <span class=\"notification-bold\"><%= taskName %></span>",
"approve": "Approve",
"approveTask": "Approve Task",
"needsWork": "Needs Work",
@@ -222,8 +222,8 @@
"userIsClamingTask": "`<%= username %> has claimed:` <%= task %>",
"approvalRequested": "Approval Requested",
"cantDeleteAssignedGroupTasks": "Can't delete group tasks that are assigned to you.",
"groupPlanUpgraded": "<strong><%- groupName %></strong> was successfully upgraded to a Group Plan!",
"groupPlanCreated": "<strong><%- groupName %></strong> was created!",
"groupPlanUpgraded": "<strong><%= groupName %></strong> was successfully upgraded to a Group Plan!",
"groupPlanCreated": "<strong><%= groupName %></strong> was created!",
"onlyGroupLeaderCanInviteToGroupPlan": "Only the group leader can invite users to a group with a subscription.",
"paymentDetails": "Payment Details",
"aboutToJoinCancelledGroupPlan": "You are about to join a group with a canceled plan. You will NOT receive a free subscription.",
@@ -389,7 +389,7 @@
"groupActivityNotificationTitle": "<%= user %> posted in <%= group %>",
"managerNotes": "Manager's Notes",
"assignedDateOnly": "Assigned on <strong><%= date %></strong>",
"assignedDateAndUser": "Assigned by @<%- username %> on <%= date %>",
"assignedDateAndUser": "Assigned by @<%= username %> on <%= date %>",
"claimRewards": "Claim Rewards",
"dayStart": "<strong>Day start</strong>: <%= startTime %>",
"viewStatus": "Status",
@@ -428,5 +428,17 @@
"interestedLearningMore": "Interested in Learning More?",
"checkGroupPlanFAQ": "Check out the <a href='/static/faq#what-is-group-plan'>Group Plans FAQ</a> to learn how to get the most out of your shared task experience.",
"groupPlanBillingFYI": "Group Plan subscriptions automatically renew unless you cancel at least 24 hours before the end of your current period. You can cancel from the Group Billing tab of your Group Plan. You will be charged within 24 hours before your subscription renews, based on the number of members in your Group Plan at that time. If you add members between payment periods, you'll see an additional prorated charge for their benefits at your next billing cycle.",
"groupPlanBillingFYIShort": "Group Plan subscriptions automatically renew unless you cancel at least 24 hours before the end of your current period. You will be charged within 24 hours before your subscription renews, based on the number of members in your Group Plan at that time. If you add members between payment periods, you'll see an additional prorated charge for their benefits at your next billing cycle."
"groupPlanBillingFYIShort": "Group Plan subscriptions automatically renew unless you cancel at least 24 hours before the end of your current period. You will be charged within 24 hours before your subscription renews, based on the number of members in your Group Plan at that time. If you add members between payment periods, you'll see an additional prorated charge for their benefits at your next billing cycle.",
"chooseAnOption": "Choose an Option",
"upgradeExistingGroup": "Upgrade an Existing Group",
"createNewGroup": "Create a New Group",
"yourParty": "Your Party",
"previouslyUpgradedGroup": "Previously upgraded Group",
"inviteOthersForAdditional": "Invite others to your Group for an additional",
"perMember": "per member",
"additionalMembersProrated": "Additional members invited during the month will be added to the next billing cycle's total as a pro-rated charge.",
"oneMember": "1 member",
"membersCount": "<%= count %> members",
"pendingCount": "(<%= count %> pending)",
"upgradeCancelsPendingInvites": "Upgrading your Party will cancel all pending invites"
}
+3 -3
View File
@@ -92,9 +92,9 @@
"paymentMethods": "Purchase using",
"paymentSuccessful": "Your payment was successful!",
"paymentYouReceived": "You received:",
"paymentYouSentGems": "You sent <strong><%- name %></strong>:",
"paymentYouSentSubscription": "You sent <strong><%- name %></strong><br> a <%= months %> month(s) Habitica subscription.",
"paymentYouSentSubscriptionG1G1": "You sent <strong><%- name %></strong><br> a <%= months %> month(s) Habitica subscription, and the same subscription was applied to your account for our Gift One Get One promotion!",
"paymentYouSentGems": "You sent <strong><%= name %></strong>:",
"paymentYouSentSubscription": "You sent <strong><%= name %></strong><br> a <%= months %> month(s) Habitica subscription.",
"paymentYouSentSubscriptionG1G1": "You sent <strong><%= name %></strong><br> a <%= months %> month(s) Habitica subscription, and the same subscription was applied to your account for our Gift One Get One promotion!",
"paymentSubBilling": "Your subscription will be billed <strong>$<%= amount %></strong> every <strong><%= months %> months</strong>.",
"groupsPaymentSubBilling": "Your next billing date is <strong><%= renewalDate %></strong>.",
"paymentSubBillingWithMethod": "Your subscription will be billed<br><strong>$<%= amount %>.00 USD</strong> every <strong><%= months %> months</strong> via <strong><%= paymentMethod %></strong>",
+2 -2
View File
@@ -71,8 +71,8 @@
"mountNotOwned": "You do not own this mount.",
"feedPet": "Feed <%= text %> to your <%= name %>?",
"raisedPet": "You grew your <%= pet %>!",
"petName": "<%= potion(locale) %> <%= egg(locale) %>",
"mountName": "<%= potion(locale) %> <%= mount(locale) %>",
"petName": "<%= potion %> <%= egg %>",
"mountName": "<%= potion %> <%= mount %>",
"keyToPets": "Key to the Pet Kennels",
"keyToPetsDesc": "Release all standard Pets so you can collect them again. (Quest Pets and rare Pets are not affected.)",
"keyToMounts": "Key to the Mount Kennels",
+1 -1
View File
@@ -5,7 +5,7 @@
"keepIt": "Keep It",
"removeIt": "Remove It",
"brokenChallenge": "Broken Challenge Link: this task was part of a challenge, but the challenge (or group) has been deleted. What to do with the orphan tasks?",
"challengeCompleted": "This challenge has been completed, and the winner was <span class=\"badge\"><%- user %></span>! What to do with the orphan tasks?",
"challengeCompleted": "This challenge has been completed, and the winner was <span class=\"badge\"><%= user %></span>! What to do with the orphan tasks?",
"unsubChallenge": "Broken Challenge Link: this task was part of a challenge, but you have unsubscribed from the challenge. What to do with the orphan tasks?",
"challenges": "Challenges",
"endDate": "Ends",
+3 -3
View File
@@ -182,7 +182,7 @@
"questEggVelociraptorText": "Velociraptor",
"questEggVelociraptorMountText": "Velociraptor",
"questEggVelociraptorAdjective": "a clever",
"eggNotes": "Find a hatching potion to pour on this egg, and it will hatch into <%= eggAdjective(locale) %> <%= eggText(locale) %>.",
"eggNotes": "Find a hatching potion to pour on this egg, and it will hatch into <%= eggAdjective %> <%= eggText %>.",
"hatchingPotionBase": "Base",
"hatchingPotionWhite": "White",
"hatchingPotionDesert": "Desert",
@@ -211,7 +211,7 @@
"hatchingPotionGlow": "Glow-in-the-Dark",
"hatchingPotionFrost": "Frost",
"hatchingPotionIcySnow": "Icy Snow",
"hatchingPotionNotes": "Pour this on an egg, and it will hatch as a <%= potText(locale) %> Pet.",
"hatchingPotionNotes": "Pour this on an egg, and it will hatch as a <%= potText %> Pet.",
"foodMeat": "Meat",
"foodMeatThe": "the Meat",
"foodMeatA": "Meat",
@@ -406,7 +406,7 @@
"hatchingPotionBalloon": "Balloon",
"hatchingPotionCryptid": "Cryptid",
"wackyPotionAddlNotes": "Cannot be raised to Mounts or used on Quest Pet eggs.",
"wackyPotionNotes": "Pour this on an egg, and it will hatch as a Wacky <%= potText(locale) %> Pet.",
"wackyPotionNotes": "Pour this on an egg, and it will hatch as a Wacky <%= potText %> Pet.",
"questEggPlatypusText": "Platypus",
"questEggPlatypusMountText": "Platypus",
"questEggPlatypusAdjective": "a perfectionist",
+1 -1
View File
@@ -190,7 +190,7 @@
"messages": "Messages",
"emptyMessagesLine1": "You don't have any messages",
"emptyMessagesLine2": "Send a message to start a conversation with your Party members or another Habitica player! You can send a new message to a user by visiting their profile and clicking the \"Message\" button.",
"userSentMessage": "<span class=\"notification-bold\"><%- user %></span> sent you a message",
"userSentMessage": "<span class=\"notification-bold\"><%= user %></span> sent you a message",
"letsgo": "Let's Go!",
"selected": "Selected",
"howManyToBuy": "How many would you like to purchase?",
+16 -16
View File
@@ -24,14 +24,14 @@
"userId": "User ID",
"invite": "Invite",
"leave": "Leave",
"invitedToParty": "You were invited to join the Party <span class=\"notification-bold\"><%- party %></span>",
"invitedToPrivateGuild": "You were invited to join the private Group <span class=\"notification-bold\"><%- guild %></span>",
"invitedToPublicGuild": "You were invited to join the Group <span class=\"notification-bold-blue\"><%- guild %></span>",
"invitedToParty": "You were invited to join the Party <span class=\"notification-bold\"><%= party %></span>",
"invitedToPrivateGuild": "You were invited to join the private Group <span class=\"notification-bold\"><%= guild %></span>",
"invitedToPublicGuild": "You were invited to join the Group <span class=\"notification-bold-blue\"><%= guild %></span>",
"invitationAcceptedHeader": "Your Invitation has been Accepted",
"invitationAcceptedBody": "<%= username %> accepted your invitation to <%= groupName %>!",
"systemMessage": "System Message",
"newMsgGuild": "<span class=\"notification-bold-blue\"><%- name %></span> has new posts",
"newMsgParty": "Your Party, <span class=\"notification-bold-blue\"><%- name %></span>, has new posts",
"newMsgGuild": "<span class=\"notification-bold-blue\"><%= name %></span> has new posts",
"newMsgParty": "Your Party, <span class=\"notification-bold-blue\"><%= name %></span>, has new posts",
"chat": "Chat",
"sendChat": "Send Chat",
"group": "Group",
@@ -151,14 +151,14 @@
"onlyGroupLeaderCanEditTasks": "Not authorised to manage tasks!",
"onlyGroupTasksCanBeAssigned": "Only group tasks can be assigned",
"assignedTo": "Assigned to",
"assignedToUser": "Assigned: <strong>@<%- userName %></strong>",
"assignedToUser": "Assigned: <strong>@<%= userName %></strong>",
"assignedToMembers": "<%= userCount %> users",
"assignedToYouAndMembers": "<strong>You</strong>, <%= userCount %> users",
"youAreAssigned": "Assigned: <strong>you</strong>",
"taskIsUnassigned": "This task is unassigned",
"confirmUnClaim": "Are you sure you want to unclaim this task?",
"confirmNeedsWork": "Are you sure you want to mark this task as needing work?",
"userRequestsApproval": "<strong><%- userName %></strong> requests approval",
"userRequestsApproval": "<strong><%= userName %></strong> requests approval",
"userCountRequestsApproval": "<strong><%= userCount %> members</strong> request approval",
"youAreRequestingApproval": "You are requesting approval",
"chatPrivilegesRevoked": "You cannot do this because your chat privileges have been removed. For details or to ask if your privileges can be returned, please email our Community Manager at admin@habitica.com or ask your parent or guardian to email them. Please include your @Username in the email. If a moderator has already told you that your chat ban is temporary, you do not need to send an email.",
@@ -168,9 +168,9 @@
"claim": "Claim Task",
"removeClaim": "Remove Claim",
"onlyGroupLeaderCanManageSubscription": "Only the group leader can manage the group's subscription",
"yourTaskHasBeenApproved": "Your task <span class=\"notification-green notification-bold\"><%- taskText %></span> has been approved.",
"taskNeedsWork": "<span class=\"notification-bold\"><%- taskText %></span> was unchecked by <span class=\"notification-bold\">@<%- managerName %></span>. Your rewards for completing the task were reverted.",
"userHasRequestedTaskApproval": "<span class=\"notification-bold\"><%- user %></span> requests approval for <span class=\"notification-bold\"><%- taskName %></span>",
"yourTaskHasBeenApproved": "Your task <span class=\"notification-green notification-bold\"><%= taskText %></span> has been approved.",
"taskNeedsWork": "<span class=\"notification-bold\"><%= taskText %></span> was unchecked by <span class=\"notification-bold\">@<%= managerName %></span>. Your rewards for completing the task were reverted.",
"userHasRequestedTaskApproval": "<span class=\"notification-bold\"><%= user %></span> requests approval for <span class=\"notification-bold\"><%= taskName %></span>",
"approve": "Approve",
"approveTask": "Approve Task",
"needsWork": "Needs Work",
@@ -183,8 +183,8 @@
"userIsClamingTask": "`<%= username %> has claimed:` <%= task %>",
"approvalRequested": "Approval Requested",
"cantDeleteAssignedGroupTasks": "Can't delete group tasks that are assigned to you.",
"groupPlanUpgraded": "<strong><%- groupName %></strong> was successfully upgraded to a Group Plan!",
"groupPlanCreated": "<strong><%- groupName %></strong> was created!",
"groupPlanUpgraded": "<strong><%= groupName %></strong> was successfully upgraded to a Group Plan!",
"groupPlanCreated": "<strong><%= groupName %></strong> was created!",
"onlyGroupLeaderCanInviteToGroupPlan": "Only the group leader can invite users to a group with a subscription.",
"paymentDetails": "Payment Details",
"aboutToJoinCancelledGroupPlan": "You are about to join a group with a cancelled plan. You will NOT receive a free subscription.",
@@ -322,8 +322,8 @@
"pmReported": "Thank you for reporting this message.",
"groupActivityNotificationTitle": "<%= user %> posted in <%= group %>",
"suggestedGroup": "Suggested because youre new to Habitica.",
"taskClaimed": "<%- userName %> has claimed the task <span class=\"notification-bold\"><%- taskText %></span>.",
"youHaveBeenAssignedTask": "<%- managerName %> has assigned you the task <span class=\"notification-bold\"><%- taskText %></span>.",
"taskClaimed": "<%= userName %> has claimed the task <span class=\"notification-bold\"><%= taskText %></span>.",
"youHaveBeenAssignedTask": "<%= managerName %> has assigned you the task <span class=\"notification-bold\"><%= taskText %></span>.",
"blockedToSendToThisUser": "You can't send to this player because you have blocked this player.",
"PMDisabled": "Disable Private Messages",
"userWithUsernameOrUserIdNotFound": "Username or User ID not found.",
@@ -335,7 +335,7 @@
"PMCanNotReply": "You can not reply to this conversation",
"newPartyPlaceholder": "Enter your Party's name.",
"claimRewards": "Claim Rewards",
"assignedDateAndUser": "Assigned by @<%- username %> on <%= date %>",
"assignedDateAndUser": "Assigned by @<%= username %> on <%= date %>",
"assignedDateOnly": "Assigned on <strong><%= date %></strong>",
"managerNotes": "Manager's Notes",
"thisTaskApproved": "This task was approved",
@@ -350,7 +350,7 @@
"giftMessageTooLong": "The maximum length for gift messages is <%= maxGiftMessageLength %>.",
"selectSubscription": "Select Subscription",
"blockYourself": "You cannot block yourself",
"invitedToPartyBy": "<a href=\"/profile/<%- userId %>\" target=\"_blank\">@<%- userName %></a> has invited you to join the Party <span class=\"notification-bold\"><%- party %></span>",
"invitedToPartyBy": "<a href=\"/profile/<%= userId %>\" target=\"_blank\">@<%= userName %></a> has invited you to join the Party <span class=\"notification-bold\"><%= party %></span>",
"challengeBannedSlurs": "Your Challenge contains a slur which violates Habiticas community guidelines and your chat and Challenge creation privileges have been revoked. Contact admin@habitica.com for more information.",
"challengeBannedWords": "Your Challenge contains one or more swear words or references to an adult topic. Please edit your Challenge so you can save it. You must remove the word, not just censor it.",
"challengeBannedSlursPrivate": "Your Challenge contains a slur which violates Habitica's community guidelines. Please remove it in order to save your Challenge.",
+3 -3
View File
@@ -82,8 +82,8 @@
"paymentMethods": "Purchase using",
"paymentSuccessful": "Your payment was successful!",
"paymentYouReceived": "You received:",
"paymentYouSentGems": "You sent <strong><%- name %></strong>:",
"paymentYouSentSubscription": "You sent <strong><%- name %></strong><br> a <%= months %> month(s) Habitica subscription.",
"paymentYouSentGems": "You sent <strong><%= name %></strong>:",
"paymentYouSentSubscription": "You sent <strong><%= name %></strong><br> a <%= months %> month(s) Habitica subscription.",
"paymentSubBilling": "Your subscription will be billed <strong>$<%= amount %></strong> every <strong><%= months %> months</strong>.",
"success": "Success!",
"classGear": "Class Gear",
@@ -129,5 +129,5 @@
"sellItems": "Sell Items",
"customizationsShopText": "Want to change up your style? You came to the right place! We stock the freshest looks to fit the season.",
"notAvailable": "This item isn't available.",
"paymentYouSentSubscriptionG1G1": "You sent <strong><%- name %></strong><br> a <%= months %> month Habitica subscription, and the same subscription was applied to your account for our Gift One Get One promotion!"
"paymentYouSentSubscriptionG1G1": "You sent <strong><%= name %></strong><br> a <%= months %> month Habitica subscription, and the same subscription was applied to your account for our Gift One Get One promotion!"
}
+2 -2
View File
@@ -66,8 +66,8 @@
"mountNotOwned": "You do not own this mount.",
"feedPet": "Feed <%= text %> to your <%= name %>?",
"raisedPet": "You grew your <%= pet %>!",
"petName": "<%= potion(locale) %> <%= egg(locale) %>",
"mountName": "<%= potion(locale) %> <%= mount(locale) %>",
"petName": "<%= potion %> <%= egg %>",
"mountName": "<%= potion %> <%= mount %>",
"keyToPets": "Key to the Pet Kennels",
"keyToPetsDesc": "Release all standard Pets so you can collect them again. (Quest Pets and rare Pets are not affected.)",
"keyToMounts": "Key to the Mount Kennels",
+1 -1
View File
@@ -5,7 +5,7 @@
"keepIt": "Conservarla",
"removeIt": "Eliminarla",
"brokenChallenge": "Enlace al desafío interrumpido: esta tarea formaba parte de un desafío, pero el desafío (o el grupo) se ha eliminado. ¿Qué hacemos con las tareas del desafío?",
"challengeCompleted": "Este desafío ha finalizado y el ganador es ¡<span class=\"badge\"><%- user %></span>! ¿Qué hacemos con las tareas del desafío?",
"challengeCompleted": "Este desafío ha finalizado y el ganador es ¡<span class=\"badge\"><%= user %></span>! ¿Qué hacemos con las tareas del desafío?",
"unsubChallenge": "Enlace al desafío interrumpido: esta tarea formaba parte de un desafío, pero ya no participas en él. ¿Qué hacemos con las tareas del desafío?",
"challenges": "Desafíos",
"endDate": "Concluye",
+3 -3
View File
@@ -182,7 +182,7 @@
"questEggVelociraptorText": "Velociraptor",
"questEggVelociraptorMountText": "Velociraptor",
"questEggVelociraptorAdjective": "un ingenioso",
"eggNotes": "Encuentra una poción de eclosión para verter en este huevo y eclosionará en <%= eggAdjective(locale) %> <%= eggText(locale) %>.",
"eggNotes": "Encuentra una poción de eclosión para verter en este huevo y eclosionará en <%= eggAdjective %> <%= eggText %>.",
"hatchingPotionBase": "Base",
"hatchingPotionWhite": "Blanco",
"hatchingPotionDesert": "del Desierto",
@@ -211,7 +211,7 @@
"hatchingPotionGlow": "que brilla en la oscuridad",
"hatchingPotionFrost": "Escarcha",
"hatchingPotionIcySnow": "Nieve Glacial",
"hatchingPotionNotes": "Vierte esto en un huevo y eclosionará como una Mascota <%= potText(locale) %>.",
"hatchingPotionNotes": "Vierte esto en un huevo y eclosionará como una Mascota <%= potText %>.",
"foodMeat": "Carne",
"foodMeatThe": "La Carne",
"foodMeatA": "Carne",
@@ -405,7 +405,7 @@
"hatchingPotionBalloon": "Globo",
"questEggAlpacaAdjective": "una colmada",
"hatchingPotionCryptid": "Críptido",
"wackyPotionNotes": "Vierte esto en un huevo y eclosionará como una Mascota Absurda <%= potText(locale) %>.",
"wackyPotionNotes": "Vierte esto en un huevo y eclosionará como una Mascota Absurda <%= potText %>.",
"wackyPotionAddlNotes": "No puede convertirse en una Montura o usarse en huevos de Mascotas de Misión.",
"questEggPlatypusMountText": "Marsupial",
"hatchingPotionOpal": "Ópalo",
+1 -1
View File
@@ -190,7 +190,7 @@
"messages": "Mensajes",
"emptyMessagesLine1": "No tienes ningún mensaje",
"emptyMessagesLine2": "Envía un mensaje para empezar una conversación con un miembro de tu Equipo o otro jugador de Habitica",
"userSentMessage": "<span class=\"notification-bold\"><%- user %></span> te ha enviado un mensaje",
"userSentMessage": "<span class=\"notification-bold\"><%= user %></span> te ha enviado un mensaje",
"letsgo": "¡Vamos!",
"selected": "Seleccionado",
"howManyToBuy": "¿Cuántos te gustaría comprar?",
+16 -16
View File
@@ -24,14 +24,14 @@
"userId": "Número de Usuario",
"invite": "Invitar",
"leave": "Salir",
"invitedToParty": "Has sido invitado a unirte al Equipo <span class=\"notification-bold\"><%- party %></span>",
"invitedToPrivateGuild": "Has sido invitado a unirte al Grupo privado <span class=\"notification-bold\"><%- guild %></span>",
"invitedToPublicGuild": "Has sido invitado a unirte al Grupo <span class=\"notification-bold-blue\"><%- guild %></span>",
"invitedToParty": "Has sido invitado a unirte al Equipo <span class=\"notification-bold\"><%= party %></span>",
"invitedToPrivateGuild": "Has sido invitado a unirte al Grupo privado <span class=\"notification-bold\"><%= guild %></span>",
"invitedToPublicGuild": "Has sido invitado a unirte al Grupo <span class=\"notification-bold-blue\"><%= guild %></span>",
"invitationAcceptedHeader": "Tu Invitación ha sido Aceptada",
"invitationAcceptedBody": "¡<%= username %> ha aceptado tu invitación a <%= groupName %>!",
"systemMessage": "Mensaje del sistema",
"newMsgGuild": "<span class=\"notification-bold-blue\"><%- name %></span> tiene nuevos mensajes",
"newMsgParty": "Tu Equipo, <span class=\"notification-bold-blue\"><%- name %></span>, tiene nuevos mensajes",
"newMsgGuild": "<span class=\"notification-bold-blue\"><%= name %></span> tiene nuevos mensajes",
"newMsgParty": "Tu Equipo, <span class=\"notification-bold-blue\"><%= name %></span>, tiene nuevos mensajes",
"chat": "Chat",
"sendChat": "Enviar Chat",
"group": "Grupo",
@@ -151,14 +151,14 @@
"onlyGroupLeaderCanEditTasks": "¡No estás autorizado para manejar las tareas!",
"onlyGroupTasksCanBeAssigned": "Sólo pueden ser asignadas tareas del grupo",
"assignedTo": "Asignado a",
"assignedToUser": "Asignado: <strong>@<%- userName %></strong>",
"assignedToUser": "Asignado: <strong>@<%= userName %></strong>",
"assignedToMembers": "<%= userCount %> usuarios",
"assignedToYouAndMembers": "<strong>Tú</strong>, <%= userCount %> usuarios",
"youAreAssigned": "Asignado: <strong>tú</strong>",
"taskIsUnassigned": "Esta tarea está sin asignar",
"confirmUnClaim": "¿Estás seguro de querer cancelar esta tarea?",
"confirmNeedsWork": "¿Estás seguro de querer marcar esta tarea como trabajo necesario?",
"userRequestsApproval": "<strong><%- userName %></strong> requieren aprobación",
"userRequestsApproval": "<strong><%= userName %></strong> requieren aprobación",
"userCountRequestsApproval": "<strong><%= userCount %> members</strong> miembros requieren aprobación",
"youAreRequestingApproval": "Estás solicitando aprobación",
"chatPrivilegesRevoked": "No puedes hacer esto porque tus privilegios de chat han sido removidos. Para obtener detalles o preguntar si tus privilegios pueden ser devueltos, por favor envía un correo a nuestro Community Manager vía admin@habitica.com o pide a tus padres o tutor que lo hagan. Por favor incluye tu @NombreDeUsuario en el correo. Si un moderador ya te ha dicho que tu exclusión del chat es temporal, no necesitas mandar un correo.",
@@ -168,9 +168,9 @@
"claim": "Reclamar Tarea",
"removeClaim": "Eliminar Reclamación",
"onlyGroupLeaderCanManageSubscription": "Solo el lider de grupo puede manejar las subscripciones de grupo",
"yourTaskHasBeenApproved": "Tu tarea <span class=\"notification-green notification-bold\"><%- taskText %></span> ha sido aprobada.",
"taskNeedsWork": "<span class=\"notification-bold\"><%- taskText %></span> ha sido desmarcada por <span class=\"notification-bold\">@<%- managerName %></span>. Las recompensas por completar la tarea se han revertido.",
"userHasRequestedTaskApproval": "<span class=\"notification-bold\"><%- user %></span> pide aprobación para <span class=\"notification-bold\"><%- taskName %></span>",
"yourTaskHasBeenApproved": "Tu tarea <span class=\"notification-green notification-bold\"><%= taskText %></span> ha sido aprobada.",
"taskNeedsWork": "<span class=\"notification-bold\"><%= taskText %></span> ha sido desmarcada por <span class=\"notification-bold\">@<%= managerName %></span>. Las recompensas por completar la tarea se han revertido.",
"userHasRequestedTaskApproval": "<span class=\"notification-bold\"><%= user %></span> pide aprobación para <span class=\"notification-bold\"><%= taskName %></span>",
"approve": "Aprobar",
"approveTask": "Aprobar Tarea",
"needsWork": "Necesita Trabajo",
@@ -183,8 +183,8 @@
"userIsClamingTask": "\"<%= username %> ha reclamado:\" <%= task %>",
"approvalRequested": "Aprobación Solicitada",
"cantDeleteAssignedGroupTasks": "No puedes borrar tareas de grupo que tienes asignadas.",
"groupPlanUpgraded": "¡A <strong><%- groupName %></strong>se le mejoró a un Plan de Grupo!",
"groupPlanCreated": "¡El grupo <strong><%- groupName %></strong> fue creado!",
"groupPlanUpgraded": "¡A <strong><%= groupName %></strong>se le mejoró a un Plan de Grupo!",
"groupPlanCreated": "¡El grupo <strong><%= groupName %></strong> fue creado!",
"onlyGroupLeaderCanInviteToGroupPlan": "Sólo el líder del grupo puede invitar usuarios a un grupo con una suscripción activa.",
"paymentDetails": "Detalles de pago",
"aboutToJoinCancelledGroupPlan": "Estás a punto de unirte a un grupo con un plan cancelado. NO recibirás una subscripción gratuita.",
@@ -322,8 +322,8 @@
"pmReported": "Gracias por reportar este mensaje.",
"groupActivityNotificationTitle": "<%= user %> publicó en <%= group %>",
"suggestedGroup": "Sugerido porque eres nuevo en Habitica.",
"taskClaimed": "<%- userName %> ha reclamado la tarea <span class=\"notification-bold\"><%- taskText %></span>.",
"youHaveBeenAssignedTask": "<%- managerName %> te ha asignado la tarea <span class=\"notification-bold\"><%- taskText %></span>.",
"taskClaimed": "<%= userName %> ha reclamado la tarea <span class=\"notification-bold\"><%= taskText %></span>.",
"youHaveBeenAssignedTask": "<%= managerName %> te ha asignado la tarea <span class=\"notification-bold\"><%= taskText %></span>.",
"blockedToSendToThisUser": "No puedes enviárselo a este jugador porque lo has bloqueado.",
"PMDisabled": "Desactivar mensajes privados",
"newPartyPlaceholder": "Ingresa el nombre de tu Equipo.",
@@ -336,7 +336,7 @@
"PMCanNotReply": "No puedes responder a esta conversación",
"unassigned": "Sin asignar",
"claimRewards": "Reclama recompensas",
"assignedDateAndUser": "Asignada por @<%- username %> en <%= date %>",
"assignedDateAndUser": "Asignada por @<%= username %> en <%= date %>",
"assignedDateOnly": "Asignada el <strong><%= date %></strong>",
"managerNotes": "Notas del administrador",
"bannedWordsAllowedDetail": "Con esta opción seleccionada, se permitirá el uso de palabras vetadas en este Grupo.",
@@ -364,7 +364,7 @@
"youEmphasized": "<strong>Tú</strong>",
"newGroupsWhatsNew": "Comprueba qué hay de nuevo:",
"newGroupsBullet02": "Cualquiera puede completar una tarea sin asignar",
"invitedToPartyBy": "<a href=\"/profile/<%- userId %>\" target=\"_blank\">@<%- userName %></a>te ha invitado a su Equipo<span class=\"notification-bold\"><%- party %></span>",
"invitedToPartyBy": "<a href=\"/profile/<%= userId %>\" target=\"_blank\">@<%= userName %></a>te ha invitado a su Equipo<span class=\"notification-bold\"><%= party %></span>",
"newGroupsBullet03": "Para facilitar la colaboración, las tareas compartidas se reinician al mismo tiempo para todos los participantes",
"tavernDiscontinuedDetail": "Debido a una serie de factores, incluidos los cambios en la forma en que nuestra base de jugadores interactúa con Habitica, los recursos necesarios para mantener estos espacios se volvieron desproporcionados en relación con el número de personas que participan en ellos e insostenibles a largo plazo.",
"newGroupsBullet09": "Una tarea compartida puede desmarcarse para indicar que aún necesita trabajo",
+3 -3
View File
@@ -82,8 +82,8 @@
"paymentMethods": "Comprar con",
"paymentSuccessful": "¡El pago se llevó a cabo con éxito!",
"paymentYouReceived": "Has recibido:",
"paymentYouSentGems": "Has enviado a <strong><%- name %></strong>:",
"paymentYouSentSubscription": "Has mandado a <strong><%- name %></strong><br> una suscripción de Habitica de <%= months %> mes/es.",
"paymentYouSentGems": "Has enviado a <strong><%= name %></strong>:",
"paymentYouSentSubscription": "Has mandado a <strong><%= name %></strong><br> una suscripción de Habitica de <%= months %> mes/es.",
"paymentSubBilling": "Por tu suscripción, abonarás <strong><%= amount %> $</strong> cada <strong><%= months %> meses</strong>.",
"success": "¡Éxito!",
"classGear": "Equipo de clase",
@@ -129,5 +129,5 @@
"sellItems": "Vender objetos",
"notAvailable": "Este artículo no está disponible.",
"customizationsShopText": "¿Necesitas un cambio de estilo? ¡Has llegado al lugar adecuado! Tenemos los complementos más actuales para que encajes en la temporada.",
"paymentYouSentSubscriptionG1G1": "Enviaste a <strong><%- name %></strong><br> una suscripción a Habitica de <%= months %> mes(es), ¡y la misma suscripción se aplicó a tu cuenta para nuestra promoción Regala uno y llévate otro!"
"paymentYouSentSubscriptionG1G1": "Enviaste a <strong><%= name %></strong><br> una suscripción a Habitica de <%= months %> mes(es), ¡y la misma suscripción se aplicó a tu cuenta para nuestra promoción Regala uno y llévate otro!"
}
+2 -2
View File
@@ -66,8 +66,8 @@
"mountNotOwned": "No tienes esta montura.",
"feedPet": "¿Dar de comer <%= text %> a tu <%= name %>?",
"raisedPet": "¡Creciste tu <%= pet %>!",
"petName": "<%= egg(locale) %> <%= potion(locale) %>",
"mountName": "<%= mount(locale) %> <%= potion(locale) %>",
"petName": "<%= egg %> <%= potion %>",
"mountName": "<%= mount %> <%= potion %>",
"keyToPets": "Llave a las Casetas de las Mascotas",
"keyToPetsDesc": "Libera todas las mascotas estándar para coleccionarlas de nuevo. (Las mascotas de misión y las raras no se verán afectadas.)",
"keyToMounts": "Llave a las Casetas de las Monturas",
+1 -1
View File
@@ -5,7 +5,7 @@
"keepIt": "Conservarla",
"removeIt": "Eliminarla",
"brokenChallenge": "Enlace al Desafío roto: esta tarea era parte de un desafío pero el desafío (o grupo) ha sido eliminado. ¿Qué hacemos con las tareas huérfanas?",
"challengeCompleted": "Este desafío ha sido completado ¡y el ganador es <span class=\"badge\"><%- user %></span>! ¿Qué hacemos con las tareas huérfanas?",
"challengeCompleted": "Este desafío ha sido completado ¡y el ganador es <span class=\"badge\"><%= user %></span>! ¿Qué hacemos con las tareas huérfanas?",
"unsubChallenge": "Enlace al Desafío roto: esta tarea era parte de un Desafío, pero te has dado de baja del mismo. ¿Qué hacemos con las tareas huérfanas?",
"challenges": "Desafíos",
"endDate": "Termina",
+2 -2
View File
@@ -182,7 +182,7 @@
"questEggVelociraptorText": "Velociraptor",
"questEggVelociraptorMountText": "Velociraptor",
"questEggVelociraptorAdjective": "un inteligente",
"eggNotes": "Encuentra una poción de eclosión para verter sobre este huevo y se convertirá en <%= eggAdjective(locale) %> <%= eggText(locale) %>.",
"eggNotes": "Encuentra una poción de eclosión para verter sobre este huevo y se convertirá en <%= eggAdjective %> <%= eggText %>.",
"hatchingPotionBase": "Base",
"hatchingPotionWhite": "Blanco",
"hatchingPotionDesert": "Desierto",
@@ -211,7 +211,7 @@
"hatchingPotionGlow": "Fosforescente",
"hatchingPotionFrost": "Escarcha",
"hatchingPotionIcySnow": "Nieve Helada",
"hatchingPotionNotes": "Vierte esto sobre un huevo, y nacerá una mascota <%= potText(locale) %>.",
"hatchingPotionNotes": "Vierte esto sobre un huevo, y nacerá una mascota <%= potText %>.",
"foodMeat": "Carne",
"foodMeatThe": "la Carne",
"foodMeatA": "Carne",
+1 -1
View File
@@ -190,7 +190,7 @@
"messages": "Mensajes",
"emptyMessagesLine1": "No tienes ningún mensaje",
"emptyMessagesLine2": "Puedes enviar un mensaje nuevo a un usuario, visitando su perfil y dando click en el botón \"Mensaje\".",
"userSentMessage": "<span class=\"notification-bold\"><%- user %></span> te envió un mensaje",
"userSentMessage": "<span class=\"notification-bold\"><%= user %></span> te envió un mensaje",
"letsgo": "¡Vamos!",
"selected": "Seleccionado",
"howManyToBuy": "¿Cuántos quieres comprar?",
+15 -15
View File
@@ -24,14 +24,14 @@
"userId": "ID de Usuario",
"invite": "Invitar",
"leave": "Salir",
"invitedToParty": "Has sido invitado a unirte al Equipo <span class=\"notification-bold\"><%- party %></span>",
"invitedToPrivateGuild": "Has sido invitado a unirte al Gremio privado <span class=\"notification-bold\"><%- guild %></span>",
"invitedToPublicGuild": "Has sido invitado a unirte al Gremio <span class=\"notification-bold-blue\"><%- guild %></span>",
"invitedToParty": "Has sido invitado a unirte al Equipo <span class=\"notification-bold\"><%= party %></span>",
"invitedToPrivateGuild": "Has sido invitado a unirte al Gremio privado <span class=\"notification-bold\"><%= guild %></span>",
"invitedToPublicGuild": "Has sido invitado a unirte al Gremio <span class=\"notification-bold-blue\"><%= guild %></span>",
"invitationAcceptedHeader": "Tu invitación ha sido Aceptada",
"invitationAcceptedBody": "¡<%= username %> aceptó tu invitación a <%= groupName %>!",
"systemMessage": "Mensaje de Sistema",
"newMsgGuild": "<span class=\"notification-bold-blue\"><%- name %></span> tiene nuevos anuncios",
"newMsgParty": "Tu Equipo, <span class=\"notification-bold-blue\"><%- name %></span>, tiene nuevos anuncios",
"newMsgGuild": "<span class=\"notification-bold-blue\"><%= name %></span> tiene nuevos anuncios",
"newMsgParty": "Tu Equipo, <span class=\"notification-bold-blue\"><%= name %></span>, tiene nuevos anuncios",
"chat": "Chat",
"sendChat": "Enviar Chat",
"group": "Grupo",
@@ -151,14 +151,14 @@
"onlyGroupLeaderCanEditTasks": "¡No autorizado para administrar tareas!",
"onlyGroupTasksCanBeAssigned": "Solo las tareas grupales pueden ser asignadas",
"assignedTo": "Asignar a",
"assignedToUser": "Asignado a <strong><%- userName %></strong>",
"assignedToUser": "Asignado a <strong><%= userName %></strong>",
"assignedToMembers": "Asignado a <strong><%= userCount %> miembros</strong>",
"assignedToYouAndMembers": "Asignado a ti y a <strong><%= userCount %> miembros</strong>",
"youAreAssigned": "Asignado: <strong>tú</strong>",
"taskIsUnassigned": "Esta tarea está sin asignar",
"confirmUnClaim": "¿Estás seguro que no quieres reclamar esta tarea?",
"confirmNeedsWork": "¿Está seguro de que desea marcar esta tarea como necesaria?",
"userRequestsApproval": "<strong><%- userName %></strong> solicita aprobación",
"userRequestsApproval": "<strong><%= userName %></strong> solicita aprobación",
"userCountRequestsApproval": "<strong><%= userCount %> miembros</strong> solicitan aprobación",
"youAreRequestingApproval": "Estás solicitando aprobación",
"chatPrivilegesRevoked": "No puedes hacer esto porque tus privilegios de chat han sido retirados. Para más detalles o para preguntar si tus privilegios pueden ser devueltos, por favor envía un correo a nuestro Administrador de la Comunidad en admin@habitica.com o pide a tus padres o tutores que lo hagan. Por favor incluye tu @Nombredeusuario en el correo. Si un moderador ya te dijo que tu exclusión del chat es temporal, no necesitas enviar un correo.",
@@ -168,9 +168,9 @@
"claim": "Reclamar tarea",
"removeClaim": "Eliminar Reclamo",
"onlyGroupLeaderCanManageSubscription": "Solo el líder del grupo puede administrar la suscripción grupal",
"yourTaskHasBeenApproved": "Tu Tarea <span class=\"notification-green\"><%- taskText %></span>ha sido aprobada.",
"taskNeedsWork": "<span class=\"notification-bold\"><%- managerName %></span> marcado <span class=\"notification-bold\"><%- taskText %></span> como necesitando trabajo adicional.",
"userHasRequestedTaskApproval": "<span class=\"notification-bold\"><%- user %></span> solicita aprovación para <span class=\"notification-bold\"><%- taskName %></span>",
"yourTaskHasBeenApproved": "Tu Tarea <span class=\"notification-green\"><%= taskText %></span>ha sido aprobada.",
"taskNeedsWork": "<span class=\"notification-bold\"><%= managerName %></span> marcado <span class=\"notification-bold\"><%= taskText %></span> como necesitando trabajo adicional.",
"userHasRequestedTaskApproval": "<span class=\"notification-bold\"><%= user %></span> solicita aprovación para <span class=\"notification-bold\"><%= taskName %></span>",
"approve": "Aprobar",
"approveTask": "Aprovar Tarea",
"needsWork": "Requiere Trabajo",
@@ -183,8 +183,8 @@
"userIsClamingTask": "`<%= username %> ha reclamado:` <%= task %>",
"approvalRequested": "Aprobación Solicitada",
"cantDeleteAssignedGroupTasks": "No puedes eliminar tareas grupales que te han sido asignadas.",
"groupPlanUpgraded": "¡<strong><%- groupName %></strong> fue elevado a un Plan Grupal!",
"groupPlanCreated": "¡El grupo <strong><%- groupName %></strong> fue creado!",
"groupPlanUpgraded": "¡<strong><%= groupName %></strong> fue elevado a un Plan Grupal!",
"groupPlanCreated": "¡El grupo <strong><%= groupName %></strong> fue creado!",
"onlyGroupLeaderCanInviteToGroupPlan": "Solo el líder del grupo puede invitar a usuarios a un grupo con una suscripción.",
"paymentDetails": "Detalles de pago",
"aboutToJoinCancelledGroupPlan": "Estás a punto de unirte a un grupo con un plan cancelado. NO recibirás una suscripción gratuita.",
@@ -329,7 +329,7 @@
"PMUserDoesNotReceiveMessages": "Este usuario ya no recibe mensajes privados",
"PMCanNotReply": "No puedes contestar a esta conversación",
"PMDisabled": "Desactivar Mensajes Privados",
"taskClaimed": "<%- userName %> ha reclamado la tarea <span class=\"notification-bold\"><%- taskText %></span>.",
"taskClaimed": "<%= userName %> ha reclamado la tarea <span class=\"notification-bold\"><%= taskText %></span>.",
"thisTaskApproved": "Esta tarea fue aprovada",
"chooseTeamMember": "Escoge un miembro del equipo",
"unassigned": "Sin asignar",
@@ -337,9 +337,9 @@
"managerNotes": "Notas de Administrador",
"groupActivityNotificationTitle": "<%= user %> publicó en <%= group %>",
"suggestedGroup": "Sugerido porque eres nuev@ en Habitica.",
"youHaveBeenAssignedTask": "<%- managerName %> te ha asignado la tarea <span class=\"notification-bold\"><%- taskText %></span>.",
"youHaveBeenAssignedTask": "<%= managerName %> te ha asignado la tarea <span class=\"notification-bold\"><%= taskText %></span>.",
"onlyPrivateGuildsCanUpgrade": "Solo los gremios privados pueden actualizarse a un plan grupal.",
"assignedDateAndUser": "Asignado por <strong>@<%- username %></strong> en <strong><%= date %></strong>",
"assignedDateAndUser": "Asignado por <strong>@<%= username %></strong> en <strong><%= date %></strong>",
"assignedDateOnly": "Asignado en <strong><%= date %></strong>",
"bannedWordsAllowedDetail": "Con esta opción seleccionada, se permitirá el uso de palabras prohibidas en este Gremio.",
"bannedWordsAllowed": "Permitir palabras prohibidas",
+2 -2
View File
@@ -82,8 +82,8 @@
"paymentMethods": "Comprar usando",
"paymentSuccessful": "¡Tu pago fue exitoso!",
"paymentYouReceived": "Recibiste:",
"paymentYouSentGems": "Enviaste <strong><%- name %></strong>:",
"paymentYouSentSubscription": "Enviaste una suscripción a Habitica de <%= months %> mes(es) para <strong><%- name %></strong>.",
"paymentYouSentGems": "Enviaste <strong><%= name %></strong>:",
"paymentYouSentSubscription": "Enviaste una suscripción a Habitica de <%= months %> mes(es) para <strong><%= name %></strong>.",
"paymentSubBilling": "Tu suscripción será cobrada <strong>$<%= amount %></strong> cada <strong><%= months %> mes(es)</strong>.",
"success": "¡Éxito!",
"classGear": "Equipamiento de Clase",
+2 -2
View File
@@ -66,8 +66,8 @@
"mountNotOwned": "No tienes esta montura.",
"feedPet": "¿Dar de comer <%= text %> a tu <%= name %>?",
"raisedPet": "¡Hiciste crecer tu <%= pet %>!",
"petName": "<%= egg(locale) %> <%= potion(locale) %>",
"mountName": "<%= mount(locale) %> <%= potion(locale) %>",
"petName": "<%= egg %> <%= potion %>",
"mountName": "<%= mount %> <%= potion %>",
"keyToPets": "Llave de las Casetas de Mascotas",
"keyToPetsDesc": "Libera todas las Mascotas estándar para poder coleccionarlas de nuevo. (Las Mascotas de Misión y las raras no son afectadas.)",
"keyToMounts": "Llave de las Casetas de Monturas",
+1 -1
View File
@@ -109,7 +109,7 @@
"cannotMakeChallenge": "Vous ne pouvez pas créer de Défis publics car votre compte n'a pour le moment pas les accès aux discussions. Merci de contacter admin@habitica.com pour plus d'informations.",
"messageChallengeFlagOfficial": "Les Défis Officiels ne peuvent pas être signalés.",
"deleteChallengeRefundDescription": "Si vous supprimez ce Défi, les Gemmes investies vous seront restituées et les Tâches du Défis ne disparaîtront pas des Tâches des participant·e·s.",
"challengeCompletedDescription": "<%- user %> a remporté le Défi ! Que souhaitez-vous faire des tâches restantes ?",
"challengeCompletedDescription": "<%= user %> a remporté le Défi ! Que souhaitez-vous faire des tâches restantes ?",
"brokenTaskDescription": "Cette tâche faisait partie d'un défi mais en a été supprimé. Que souhaitez-vous faire ?",
"brokenChallengeDescription": "Cette tâche faisait partie d'un défi mais celui-ci (ou le groupe) a été supprimé. Que souhaitez-vous faire des tâches restantes ?",
"brokenTask": "Lien Inexistant vers Défi"
+3 -3
View File
@@ -182,7 +182,7 @@
"questEggVelociraptorText": "Vélociraptor",
"questEggVelociraptorMountText": "Vélociraptor",
"questEggVelociraptorAdjective": "un intelligent",
"eggNotes": "Trouvez une potion d’éclosion à verser sur cet œuf et il en sortira <%= eggAdjective(locale) %> bébé <%= eggText(locale) %>.",
"eggNotes": "Trouvez une potion d’éclosion à verser sur cet œuf et il en sortira <%= eggAdjective %> bébé <%= eggText %>.",
"hatchingPotionBase": "de base",
"hatchingPotionWhite": "des neiges",
"hatchingPotionDesert": "du désert",
@@ -211,7 +211,7 @@
"hatchingPotionGlow": "phosphorescent",
"hatchingPotionFrost": "du gel",
"hatchingPotionIcySnow": "de neige verglacée",
"hatchingPotionNotes": "Versez-la sur un œuf et il en sortira un Familier <%= potText(locale) %>.",
"hatchingPotionNotes": "Versez-la sur un œuf et il en sortira un Familier <%= potText %>.",
"foodMeat": "Côtelette",
"foodMeatThe": "la côtelette",
"foodMeatA": "une côtelette",
@@ -406,7 +406,7 @@
"hatchingPotionBalloon": "Ballon",
"wackyPotionAddlNotes": "Ne peut se transformer en Monture ni être utilisée sur les œufs de Familier de Quête.",
"hatchingPotionCryptid": "Cyptide",
"wackyPotionNotes": "Versez-la sur un œuf et il en sortira un Familier <%= potText(locale) %> Farfelu.",
"wackyPotionNotes": "Versez-la sur un œuf et il en sortira un Familier <%= potText %> Farfelu.",
"questEggPlatypusText": "Ornithorynque",
"questEggPlatypusMountText": "Ornithorynque",
"questEggPlatypusAdjective": "organisé",
+1 -1
View File
@@ -190,7 +190,7 @@
"messages": "Messages",
"emptyMessagesLine1": "Vous n'avez aucun message",
"emptyMessagesLine2": "Envoyez un message pour démarrer une conversation avec les membres de votre Équipe ou un·e autre joueu·r·se d'Habitica",
"userSentMessage": "<span class=\"notification-bold\"><%- user %></span> vous a envoyé un message",
"userSentMessage": "<span class=\"notification-bold\"><%= user %></span> vous a envoyé un message",
"letsgo": "Allons-y !",
"selected": "Selectionné",
"howManyToBuy": "Combien voulez-vous en acquérir ?",
+16 -16
View File
@@ -24,14 +24,14 @@
"userId": "ID d'utilisateur",
"invite": "Inviter",
"leave": "Quitter",
"invitedToParty": "Vous avez reçu une invitation à rejoindre l'équipe <span class=\"notification-bold\"><%- party %></span>",
"invitedToPrivateGuild": "Vous avez reçu une invitation à rejoindre le Groupe <span class=\"notification-bold\"><%- guild %></span>",
"invitedToPublicGuild": "Vous avez reçu une invitation à rejoindre le Groupe <span class=\"notification-bold-blue\"><%- guild %></span>",
"invitedToParty": "Vous avez reçu une invitation à rejoindre l'équipe <span class=\"notification-bold\"><%= party %></span>",
"invitedToPrivateGuild": "Vous avez reçu une invitation à rejoindre le Groupe <span class=\"notification-bold\"><%= guild %></span>",
"invitedToPublicGuild": "Vous avez reçu une invitation à rejoindre le Groupe <span class=\"notification-bold-blue\"><%= guild %></span>",
"invitationAcceptedHeader": "Votre invitation a été acceptée",
"invitationAcceptedBody": "<%= username %> a accepté votre invitation pour <%= groupName %> !",
"systemMessage": "Message du système",
"newMsgGuild": "<span class=\"notification-bold-blue\"><%- name %></span> a de nouveaux messages",
"newMsgParty": "Votre équipe, <span class=\"notification-bold-blue\"><%- name %></span>, a de nouveaux messages",
"newMsgGuild": "<span class=\"notification-bold-blue\"><%= name %></span> a de nouveaux messages",
"newMsgParty": "Votre équipe, <span class=\"notification-bold-blue\"><%= name %></span>, a de nouveaux messages",
"chat": "Discussion",
"sendChat": "Envoyer un Message",
"group": "Groupe",
@@ -151,14 +151,14 @@
"onlyGroupLeaderCanEditTasks": "Pas d'autorisation pour gérer les tâches !",
"onlyGroupTasksCanBeAssigned": "Seules les tâches de groupe peuvent être assignées",
"assignedTo": "Attribué à",
"assignedToUser": "Attribué : <strong><%- userName %></strong>",
"assignedToUser": "Attribué : <strong><%= userName %></strong>",
"assignedToMembers": "<%= userCount %> membres",
"assignedToYouAndMembers": "<strong>Vous</strong>, <%= userCount %> membres",
"youAreAssigned": "Assigné : <strong>vous</strong>",
"taskIsUnassigned": "Cette tâche n'est pas attribuée",
"confirmUnClaim": "Voulez-vous ne plus réclamer cette tâche ?",
"confirmNeedsWork": "Voulez-vous vraiment marquer cette tâche comme nécessitant du travail supplémentaire ?",
"userRequestsApproval": "<strong><%- userName %></strong> demande une approbation",
"userRequestsApproval": "<strong><%= userName %></strong> demande une approbation",
"userCountRequestsApproval": "<strong><%= userCount %> membres</strong> demandent une approbation",
"youAreRequestingApproval": "Vous demandez une approbation",
"chatPrivilegesRevoked": "Vous ne pouvez faire cela car vos privilèges de discussion ont été supprimés. Pour des détails ou pour demander si vos privilèges peuvent être rétablis, veuillez envoyer un message à notre responsable de la communauté à admin@habitica.com ou demandez à vos parents ou tuteur de leur écrire. Veuillez inclure votre @pseudo dans l'email. Si l'équipe de modération vous a déjà prévenu que votre révocation est temporaire, vous n'avez pas besoin d'envoyer d'email.",
@@ -168,9 +168,9 @@
"claim": "Revendiquer une tâche",
"removeClaim": "Enlever la demande",
"onlyGroupLeaderCanManageSubscription": "Seul le responsable du groupe peut gérer l'abonnement du groupe",
"yourTaskHasBeenApproved": "Votre tâche <span class=\"notification-green notification-bold\"><%- taskText %></span> a été approuvée.",
"taskNeedsWork": "<span class=\"notification-bold\"><%- taskText %></span> a été décoché par <span class=\"notification-bold\">@<%- managerName %></span>. Votre récompense pour avoir réalisé cette tâche a été enlevée.",
"userHasRequestedTaskApproval": "<span class=\"notification-bold\"><%- user %></span> a demandé une approbation pour <span class=\"notification-bold\"><%- taskName %></span>",
"yourTaskHasBeenApproved": "Votre tâche <span class=\"notification-green notification-bold\"><%= taskText %></span> a été approuvée.",
"taskNeedsWork": "<span class=\"notification-bold\"><%= taskText %></span> a été décoché par <span class=\"notification-bold\">@<%= managerName %></span>. Votre récompense pour avoir réalisé cette tâche a été enlevée.",
"userHasRequestedTaskApproval": "<span class=\"notification-bold\"><%= user %></span> a demandé une approbation pour <span class=\"notification-bold\"><%= taskName %></span>",
"approve": "Approuver",
"approveTask": "Approuver la tâche",
"needsWork": "Nécessite du travail supplémentaire",
@@ -183,8 +183,8 @@
"userIsClamingTask": "`<%= username %> a revendiqué : `<%= task %>",
"approvalRequested": "Approbation demandée",
"cantDeleteAssignedGroupTasks": "Vous ne pouvez pas supprimer les tâches de groupe qui vous ont été attribuées.",
"groupPlanUpgraded": "<strong><%- groupName %></strong> a été correctement amélioré en plan de groupe !",
"groupPlanCreated": "<strong><%- groupName %></strong> a été créé !",
"groupPlanUpgraded": "<strong><%= groupName %></strong> a été correctement amélioré en plan de groupe !",
"groupPlanCreated": "<strong><%= groupName %></strong> a été créé !",
"onlyGroupLeaderCanInviteToGroupPlan": "Seul le chef de groupe peut inviter des utilisateurs dans un groupe avec abonnement.",
"paymentDetails": "Détails du paiement",
"aboutToJoinCancelledGroupPlan": "Vous êtes sur le point de rejoindre un groupe dont l'abonnement a été annulé. Vous ne recevrez PAS d'abonnement gratuit.",
@@ -321,8 +321,8 @@
"allAssignedCompletion": "Toutes - Terminée lorsque toutes les personnes avec cette tâche la terminent",
"pmReported": "Merci d'avoir signalé ce message.",
"suggestedGroup": "Suggérer parce que vous venez d'arriver sur Habitica.",
"taskClaimed": "<%- userName %> a revendiqué la tâche <span class=\"notification-bold\"><%- taskText %></span>.",
"youHaveBeenAssignedTask": "<%- managerName %> vous a assigné la tâche <span class=\"notification-bold\"><%- taskText %></span>.",
"taskClaimed": "<%= userName %> a revendiqué la tâche <span class=\"notification-bold\"><%= taskText %></span>.",
"youHaveBeenAssignedTask": "<%= managerName %> vous a assigné la tâche <span class=\"notification-bold\"><%= taskText %></span>.",
"groupActivityNotificationTitle": "<%= user %> a écrit dans <%= group %>",
"blockedToSendToThisUser": "Vous ne pouvez pas envoyer de message à ce membre, car vous l'avez bloqué.",
"PMDisabled": "Désactiver les messages privés",
@@ -335,7 +335,7 @@
"PMCanNotReply": "Vous ne pouvez pas répondre à cette conversation",
"newPartyPlaceholder": "Indiquez le nom de votre Équipe.",
"claimRewards": "Demander les récompenses",
"assignedDateAndUser": "Assigné par @<%- username %> le <%= date %>",
"assignedDateAndUser": "Assigné par @<%= username %> le <%= date %>",
"assignedDateOnly": "Assigné le <strong><%= date %></strong>",
"managerNotes": "Notes de la personne responsable",
"thisTaskApproved": "Cette tâche a été approuvée",
@@ -391,7 +391,7 @@
"nameStar": "Nom*",
"nameStarText": "Ajouter un titre",
"descriptionOptional": "Description",
"invitedToPartyBy": "<a href=\"/profile/<%- userId %>\" target=\"_blank\">@<%- userName %></a> vous a invité à rejoindre l'équipe <span class=\"notification-bold\"><%- party %></span>",
"invitedToPartyBy": "<a href=\"/profile/<%= userId %>\" target=\"_blank\">@<%= userName %></a> vous a invité à rejoindre l'équipe <span class=\"notification-bold\"><%= party %></span>",
"findMorePartyMembers": "Trouver plus de Membres",
"invitedToYourParty": "<strong>a été invité·e dans votre Équipe !</strong>&nbsp;&nbsp;Clique pour annuler",
"partyExceedsInvitesLimit": "Une Équipe ne peut avoir que <%= maxInvites %> invitations en attente.",
+3 -3
View File
@@ -82,8 +82,8 @@
"paymentMethods": "Moyens de paiement",
"paymentSuccessful": "Le paiement a été réalisé !",
"paymentYouReceived": "Vous avez reçu :",
"paymentYouSentGems": "Vous avez envoyé à <strong><%- name %></strong> :",
"paymentYouSentSubscription": "Vous avez envoyé à <strong><%- name %></strong><br> un abonnement de <%= months %> mois sur Habitica.",
"paymentYouSentGems": "Vous avez envoyé à <strong><%= name %></strong> :",
"paymentYouSentSubscription": "Vous avez envoyé à <strong><%= name %></strong><br> un abonnement de <%= months %> mois sur Habitica.",
"paymentSubBilling": "Votre abonnement sera débité de <strong><%= amount %>$</strong> chaque <strong><%= months %> mois</strong>.",
"success": "Victoire !",
"classGear": "Équipement de classe",
@@ -129,5 +129,5 @@
"sellItems": "Vendre des objets",
"notAvailable": "Cet objet n'est pas disponible.",
"customizationsShopText": "Vous voulez changer de style ? Vous êtes au bon endroit ! Nous fournissons des tenues de saison branchées.",
"paymentYouSentSubscriptionG1G1": "Vous avez offert une abonnement Habitica de <%= months %> mois à <strong><%- name %></strong><br>, et vous profiterez du même abonnement sur votre compte grâce à l'offre Offrez-en Un Recevez-en Un !"
"paymentYouSentSubscriptionG1G1": "Vous avez offert une abonnement Habitica de <%= months %> mois à <strong><%= name %></strong><br>, et vous profiterez du même abonnement sur votre compte grâce à l'offre Offrez-en Un Recevez-en Un !"
}
+2 -2
View File
@@ -66,8 +66,8 @@
"mountNotOwned": "Vous ne possédez pas cette monture.",
"feedPet": "Donner cette <%= text %> à votre <%= name %> ?",
"raisedPet": "Votre <%= pet %> a bien grandi !",
"petName": "bébé <%= egg(locale) %> <%= potion(locale) %>",
"mountName": "<%= mount(locale) %> <%= potion(locale) %>",
"petName": "bébé <%= egg %> <%= potion %>",
"mountName": "<%= mount %> <%= potion %>",
"keyToPets": "Clé du chenil des familiers",
"keyToPetsDesc": "Libère tous les familiers standards pour vous puissiez les collectionner à nouveau. (Les familiers rares et de quêtes ne sont pas affectés.)",
"keyToMounts": "Clé du chenil des montures",
+1 -1
View File
@@ -5,7 +5,7 @@
"keepIt": "להשאיר אותה",
"removeIt": "להסיר אותה",
"brokenChallenge": "קישור אתגר שבור: משימה זו לביצוע הייתה חלק מאתגר, אך האתגר (או הקבוצה) נמחק. מה ברצונך לעשות עם המשימות שנותרו?",
"challengeCompleted": "אתגר זה הושלם, והניצחון בידי <span class=\"badge\"><%- user %></span>! מה לעשות עם המשימות שנותרו?",
"challengeCompleted": "אתגר זה הושלם, והניצחון בידי <span class=\"badge\"><%= user %></span>! מה לעשות עם המשימות שנותרו?",
"unsubChallenge": "קישור אתגר שבור: משימה זו לביצוע הייתה חלק מאתגר, אבל פרשת ממנו. מה ברצונך לעשות עם המשימות שנותרו?",
"challenges": "אתגרים",
"endDate": "סופים",
+2 -2
View File
@@ -182,7 +182,7 @@
"questEggVelociraptorText": "ולוצירפטור",
"questEggVelociraptorMountText": "ולוצירפטור",
"questEggVelociraptorAdjective": "פיקח",
"eggNotes": "מצא שיקוי הבקעה לשפוך על ביצה זו, והיא תהפוך ל<%= eggText(locale) %> <%= eggAdjective(locale) %>.",
"eggNotes": "מצא שיקוי הבקעה לשפוך על ביצה זו, והיא תהפוך ל<%= eggText %> <%= eggAdjective %>.",
"hatchingPotionBase": "רגיל",
"hatchingPotionWhite": "לבן",
"hatchingPotionDesert": "מדברי",
@@ -211,7 +211,7 @@
"hatchingPotionGlow": "זוהר-בחושך",
"hatchingPotionFrost": "כפור",
"hatchingPotionIcySnow": "שלג קרחי",
"hatchingPotionNotes": "שפוך שיקוי זה על הביצה, והיא תבקע כ <%= potText(locale) %> חיית מחמד.",
"hatchingPotionNotes": "שפוך שיקוי זה על הביצה, והיא תבקע כ <%= potText %> חיית מחמד.",
"foodMeat": "בשר",
"foodMeatThe": "הבשר",
"foodMeatA": "בשר",
+1 -1
View File
@@ -190,7 +190,7 @@
"messages": "Messages",
"emptyMessagesLine1": "You don't have any messages",
"emptyMessagesLine2": "Send a message to start a conversation!",
"userSentMessage": "<span class=\"notification-bold\"><%- user %></span> sent you a message",
"userSentMessage": "<span class=\"notification-bold\"><%= user %></span> sent you a message",
"letsgo": "קדימה!",
"selected": "נבחרו",
"howManyToBuy": "כמה ברצונך לרכוש?",
+15 -15
View File
@@ -24,14 +24,14 @@
"userId": "מזהה משתמש",
"invite": "הזמנה",
"leave": "עזיבה",
"invitedToParty": "קיבלת זימון להצטרף לחבורה <span class=\"notification-bold\"><%- party %></span>",
"invitedToPrivateGuild": "הוזמנת להצטרף לגילדה הפרטית <span class=\"notification-bold\"><%- guild %></span>",
"invitedToPublicGuild": "הוזמת להצטרף לגילדה <span class=\"notification-bold-blue\"><%- guild %></span>",
"invitedToParty": "קיבלת זימון להצטרף לחבורה <span class=\"notification-bold\"><%= party %></span>",
"invitedToPrivateGuild": "הוזמנת להצטרף לגילדה הפרטית <span class=\"notification-bold\"><%= guild %></span>",
"invitedToPublicGuild": "הוזמת להצטרף לגילדה <span class=\"notification-bold-blue\"><%= guild %></span>",
"invitationAcceptedHeader": "ההזמה שלך התקבלה",
"invitationAcceptedBody": "<%= username %> אישר את ההזמנה שלך ל<%= groupName %>!",
"systemMessage": "הודעת מערכת",
"newMsgGuild": "יש פוסטים חדשים בגילדה <span class=\"notification-bold-blue\"><%- name %></span>",
"newMsgParty": "יש בחבורה שלך, <span class=\"notification-bold-blue\"><%- name %></span>, הודעות חדשות",
"newMsgGuild": "יש פוסטים חדשים בגילדה <span class=\"notification-bold-blue\"><%= name %></span>",
"newMsgParty": "יש בחבורה שלך, <span class=\"notification-bold-blue\"><%= name %></span>, הודעות חדשות",
"chat": "שיחה",
"sendChat": "שילחו הודעה",
"group": "קבוצה",
@@ -151,14 +151,14 @@
"onlyGroupLeaderCanEditTasks": "אין הרשאה לנהל משימות!",
"onlyGroupTasksCanBeAssigned": "ניתן לשייך רק משימות של הקבוצה",
"assignedTo": "שיוך אל",
"assignedToUser": "Assigned to <%- userName %>",
"assignedToUser": "Assigned to <%= userName %>",
"assignedToMembers": "Assigned to <%= userCount %> members",
"assignedToYouAndMembers": "Assigned to you and <%= userCount %> members",
"youAreAssigned": "שויך לך",
"taskIsUnassigned": "המשימה הזאת לא שויכה",
"confirmUnClaim": "אתם בטוחים שתרצו להתנער מהמשימה הזאת?",
"confirmNeedsWork": "אתם בטוחים שאתם רוצים לציין את המשימה הזאת כדורשת עבודה?",
"userRequestsApproval": "<%- userName %> requests approval",
"userRequestsApproval": "<%= userName %> requests approval",
"userCountRequestsApproval": "<%= userCount %> members request approval",
"youAreRequestingApproval": "אתם מבקשים אישור",
"chatPrivilegesRevoked": "You cannot do that because your chat privileges have been revoked.",
@@ -168,9 +168,9 @@
"claim": "Claim",
"removeClaim": "להסיר את הבעלות על המשימה",
"onlyGroupLeaderCanManageSubscription": "רק מנהיג הקבוצה יכול לנהל את ההרשמה לקבוצה",
"yourTaskHasBeenApproved": "Your task <span class=\"notification-green\"><%- taskText %></span> has been approved.",
"taskNeedsWork": "<span class=\"notification-bold\"><%- taskText %></span> סומן כלא גמור על ידי <span class=\"notification-bold\">@<%- managerName %></span>. הפרסים על השלמת המשימה התבטלו.",
"userHasRequestedTaskApproval": "<span class=\"notification-bold\"><%- user %></span> מבקש אישור על <span class=\"notification-bold\"><%- taskName %></span>",
"yourTaskHasBeenApproved": "Your task <span class=\"notification-green\"><%= taskText %></span> has been approved.",
"taskNeedsWork": "<span class=\"notification-bold\"><%= taskText %></span> סומן כלא גמור על ידי <span class=\"notification-bold\">@<%= managerName %></span>. הפרסים על השלמת המשימה התבטלו.",
"userHasRequestedTaskApproval": "<span class=\"notification-bold\"><%= user %></span> מבקש אישור על <span class=\"notification-bold\"><%= taskName %></span>",
"approve": "לאשר",
"approveTask": "לאשר משימה",
"needsWork": "דרושה עוד עבודה",
@@ -183,8 +183,8 @@
"userIsClamingTask": "`<%= username %> שייך לעצמו את:` <%= task %>",
"approvalRequested": "בקשה לאישור נשלחה",
"cantDeleteAssignedGroupTasks": "לא ניתן למחוק משימות של חבורה המשויכות אליכם.",
"groupPlanUpgraded": "<strong><%- groupName %></strong> שודרגה בהצלחה לתוכנית קבוצות!",
"groupPlanCreated": "<strong><%- groupName %></strong> נוצרה!",
"groupPlanUpgraded": "<strong><%= groupName %></strong> שודרגה בהצלחה לתוכנית קבוצות!",
"groupPlanCreated": "<strong><%= groupName %></strong> נוצרה!",
"onlyGroupLeaderCanInviteToGroupPlan": "רק מנהיג הקבוצה יכול להזמין משתמשים לקבוצה עם מנוי.",
"paymentDetails": "פרטי תשלום",
"aboutToJoinCancelledGroupPlan": "אתם עומדים להצטרף לקבוצה עם מנוי מבוטל. אתם לא הולכים לקבל מנוי בחינם.",
@@ -339,7 +339,7 @@
"userWithUsernameOrUserIdNotFound": "לא נמצא שם משתמש או מזהה משתמש.",
"selectSubscription": "בחירת מינוי",
"usernameOrUserId": "נא לציין @שם_משתמש או מזהה משתמש",
"invitedToPartyBy": "<a href=\"/profile/<%- userId %>\" target=\"_blank\">@<%- userName %></a> הזמין אותך להצטרף לחבורה <span class=\"notification-bold\"><%- party %></span>",
"invitedToPartyBy": "<a href=\"/profile/<%= userId %>\" target=\"_blank\">@<%= userName %></a> הזמין אותך להצטרף לחבורה <span class=\"notification-bold\"><%= party %></span>",
"PMUnblockUserToSendMessages": "הסירו את החסימה של המשתמש כדי להמשיך לשלוח או לקבל הודעות.",
"PMUserDoesNotReceiveMessages": "המשתמש כבר לא מקבל הודעות פרטיות",
"sendTotal": "סך הכל:",
@@ -351,9 +351,9 @@
"sendGiftLabel": "תרצו לשלוח הודעת מתנה?",
"onlyPrivateGuildsCanUpgrade": "ניתן לשדרג רק גילדות פרטיות לתוכנית הקבוצות.",
"assignTo": "לשייך",
"taskClaimed": "<%- userName %> לקח בעלות על המשימה <span class=\"notification-bold\"><%- taskText %></span>.",
"taskClaimed": "<%= userName %> לקח בעלות על המשימה <span class=\"notification-bold\"><%= taskText %></span>.",
"partyExceedsInvitesLimit": "חבורה יכולה להיות עם <%= maxInvites %> מוזמנים לכל היותר.",
"chooseTeamMember": "חיפוש חבר צוות",
"youHaveBeenAssignedTask": "<%- managerName %> שייך אותך למשימה<span class=\"notification-bold\"><%- taskText %></span>.",
"youHaveBeenAssignedTask": "<%= managerName %> שייך אותך למשימה<span class=\"notification-bold\"><%= taskText %></span>.",
"challengeBannedSlurs": "האתגר שלך כולל מילה שמפרה את הנחיות הקהילה של הביטיקה, לכן פריבילגיות הצ'ט והאתגרים שלך נשללו. צרו קשר בכתובת המייל admin@habitica.com למידע נוסף."
}
+1 -1
View File
@@ -82,7 +82,7 @@
"paymentMethods": "רכשו באמצעות",
"paymentSuccessful": "התשלום נעשה בהצלחה!",
"paymentYouReceived": "קיבלת:",
"paymentYouSentGems": "שלחת <strong><%- name %></strong>:",
"paymentYouSentGems": "שלחת <strong><%= name %></strong>:",
"paymentYouSentSubscription": "",
"paymentSubBilling": "",
"success": "הצלחה!",
+1 -1
View File
@@ -66,7 +66,7 @@
"mountNotOwned": "חיית רכיבה זו אינה בבעלותך.",
"feedPet": "האכילו את <%= name %> ב<%= text %>?",
"raisedPet": "ה <%= pet %> שלכם גדל/ה!",
"petName": "<%= potion(locale) %> מ<%= egg(locale) %>",
"petName": "<%= potion %> מ<%= egg %>",
"mountName": "",
"keyToPets": "מפתח למאורות של חיות המחמד",
"keyToPetsDesc": "שחררו את כל חיות המחמד הבסיסיות כדי שתוכלו לאסוף אותם שוב. (חיות מחמד מהרפתקאות וחיות מחמד נדירות לא ישוחררו.)",
+1 -1
View File
@@ -5,7 +5,7 @@
"keepIt": "Zadrži",
"removeIt": "Ukloni",
"brokenChallenge": "Neispravna poveznica Izazova: ovaj je zadatak bio dio izazova, ali je izazov (ili grupa) izbrisan/a. Što učiniti s tim osamljenim zadacima?",
"challengeCompleted": "Ovaj je izazov završen, a pobjednik je bio <span class=\"badge\"><%- user %></span>! Što učiniti s tim osamljenim zadacima?",
"challengeCompleted": "Ovaj je izazov završen, a pobjednik je bio <span class=\"badge\"><%= user %></span>! Što učiniti s tim osamljenim zadacima?",
"unsubChallenge": "Neispravna poveznica Izazova: ovaj je zadatak bio dio izazova, ali ste se odjavili s izazova. Što učiniti s tim osamljenim zadacima?",
"challenges": "Izazovi",
"endDate": "Završava",
+3 -3
View File
@@ -182,7 +182,7 @@
"questEggVelociraptorText": "Velociraptor",
"questEggVelociraptorMountText": "Velociraptor",
"questEggVelociraptorAdjective": "oštroumni",
"eggNotes": "Pronađite napitak za izlijeganje koji ćete izliti na ovo jaje, i ono će se izleći u <%= eggAdjective(locale) %> <%= eggText(locale) %>.",
"eggNotes": "Pronađite napitak za izlijeganje koji ćete izliti na ovo jaje, i ono će se izleći u <%= eggAdjective %> <%= eggText %>.",
"hatchingPotionBase": "Osnovni",
"hatchingPotionWhite": "Bijeli",
"hatchingPotionDesert": "Pustinjski",
@@ -211,7 +211,7 @@
"hatchingPotionGlow": "Svijetleći",
"hatchingPotionFrost": "Mrzli",
"hatchingPotionIcySnow": "Ledeni snijeg",
"hatchingPotionNotes": "Izlijte ovo na jaje, i ono će se izleći kao <%= potText(locale) %> Ljubimac.",
"hatchingPotionNotes": "Izlijte ovo na jaje, i ono će se izleći kao <%= potText %> Ljubimac.",
"foodMeat": "Meso",
"foodMeatThe": "Meso",
"foodMeatA": "Meso",
@@ -373,7 +373,7 @@
"hatchingPotionFungi": "Gljivičasti",
"hatchingPotionCryptid": "Kriptidni",
"hatchingPotionOpal": "Sedefast",
"wackyPotionNotes": "Izlijte ovo na jaje, i ono će se izleći kao Otkačeni <%= potText(locale) %> Ljubimac.",
"wackyPotionNotes": "Izlijte ovo na jaje, i ono će se izleći kao Otkačeni <%= potText %> Ljubimac.",
"wackyPotionAddlNotes": "Ne može se pretvoriti u Jahaću životinju niti koristiti na jajima ljubimaca za pustolovine.",
"premiumPotionUnlimitedNotes": "Nije upotrebljivo na jajima ljubimaca pustolovine.",
"hatchingPotionOnyx": "Oniksov",

Some files were not shown because too many files have changed in this diff Show More