Merge branch 'develop' of https://codeberg.org/calckey/calckey into feature/edits
This commit is contained in:
commit
f0a0a657b9
|
@ -0,0 +1,38 @@
|
|||
url: http://localhost:3000
|
||||
port: 3000
|
||||
|
||||
db:
|
||||
host: 127.0.0.1
|
||||
port: 5432
|
||||
|
||||
db: calckey
|
||||
|
||||
user: calckey
|
||||
pass: calckey
|
||||
|
||||
redis:
|
||||
host: localhost
|
||||
port: 6379
|
||||
family: 4
|
||||
#sonic:
|
||||
# host: localhost
|
||||
# port: 1491
|
||||
# auth: SecretPassword
|
||||
# collection: notes
|
||||
# bucket: default
|
||||
|
||||
#elasticsearch:
|
||||
# host: localhost
|
||||
# port: 9200
|
||||
# ssl: false
|
||||
# user:
|
||||
# pass:
|
||||
|
||||
id: 'aid'
|
||||
|
||||
reservedUsernames:
|
||||
- root
|
||||
- admin
|
||||
- administrator
|
||||
- me
|
||||
- system
|
|
@ -110,12 +110,13 @@ id: 'aid'
|
|||
#maxCaptionLength: 1500
|
||||
|
||||
# Reserved usernames that only the administrator can register with
|
||||
reservedUsernames:
|
||||
- root
|
||||
- admin
|
||||
- administrator
|
||||
- me
|
||||
- system
|
||||
reservedUsernames: [
|
||||
'root',
|
||||
'admin',
|
||||
'administrator',
|
||||
'me',
|
||||
'system'
|
||||
]
|
||||
|
||||
# Whether disable HSTS
|
||||
#disableHsts: true
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
replicaCount: 1
|
||||
|
||||
resources:
|
||||
requests:
|
||||
cpu: 0.5
|
||||
memory: 512Mi
|
||||
limits:
|
||||
cpu: 1
|
||||
memory: 1Gi
|
||||
|
||||
calckey:
|
||||
domain: example.tld
|
||||
smtp:
|
||||
from_address: noreply@example.tld
|
||||
port: 587
|
||||
server: smtp.gmail.com
|
||||
useImplicitSslTls: false
|
||||
login: me@example.tld
|
||||
password: CHANGEME
|
||||
objectStorage:
|
||||
baseUrl: https://example-bucket.nyc3.cdn.digitaloceanspaces.com
|
||||
access_key: CHANGEME
|
||||
access_secret: CHANGEME
|
||||
bucket: example-bucket
|
||||
endpoint: nyc3.digitaloceanspaces.com:443
|
||||
region: nyc3
|
||||
allowedPrivateNetworks: []
|
||||
|
||||
ingress:
|
||||
enabled: true
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: letsencrypt
|
||||
hosts:
|
||||
- host: example.tld
|
||||
paths:
|
||||
- path: /
|
||||
pathType: ImplementationSpecific
|
||||
tls:
|
||||
- secretName: example-tld-certificate
|
||||
hosts:
|
||||
- example.tld
|
||||
|
||||
elasticsearch:
|
||||
enabled: false
|
||||
|
||||
postgresql:
|
||||
auth:
|
||||
password: CHANGEME
|
||||
postgresPassword: CHANGEME
|
||||
primary:
|
||||
persistence:
|
||||
enabled: true
|
||||
storageClass: vultr-block-storage
|
||||
size: 25Gi
|
||||
resources:
|
||||
requests:
|
||||
cpu: 0.25
|
||||
memory: 256Mi
|
||||
limits:
|
||||
cpu: 0.5
|
||||
memory: 512Mi
|
||||
metrics:
|
||||
enabled: true
|
||||
|
||||
redis:
|
||||
auth:
|
||||
password: CHANGEME
|
||||
master:
|
||||
resources:
|
||||
requests:
|
||||
cpu: 0.25
|
||||
memory: 256Mi
|
||||
limits:
|
||||
cpu: 0.5
|
||||
memory: 256Mi
|
||||
persistence:
|
||||
storageclass: vultr-block-storage
|
||||
size: 10Gi
|
||||
replica:
|
||||
replicaCount: 0
|
||||
metrics:
|
||||
enabled: true
|
|
@ -0,0 +1,4 @@
|
|||
if ! has nix_direnv_version || ! nix_direnv_version 2.2.1; then
|
||||
source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/2.2.1/direnvrc" "sha256-zelF0vLbEl5uaqrfIzbgNzJWGmLzCmYAkInj/LNxvKs="
|
||||
fi
|
||||
use flake . --impure
|
|
@ -22,7 +22,9 @@ coverage
|
|||
# config
|
||||
/.config/*
|
||||
!/.config/example.yml
|
||||
!/.config/devenv.yml
|
||||
!/.config/docker_example.env
|
||||
!/.config/helm_values_example.yml
|
||||
|
||||
#docker dev config
|
||||
/dev/docker-compose.yml
|
||||
|
@ -56,3 +58,7 @@ packages/backend/assets/sounds/None.mp3
|
|||
# old yarn
|
||||
.yarn
|
||||
yarn*
|
||||
|
||||
# Nix Development shell items
|
||||
.devenv
|
||||
.direnv
|
||||
|
|
|
@ -11,5 +11,4 @@ pipeline:
|
|||
password:
|
||||
# Secret 'docker_password' needs to be set in the CI settings
|
||||
from_secret: docker_password
|
||||
|
||||
branches: beta
|
||||
|
|
|
@ -16,4 +16,3 @@ pipeline:
|
|||
# Push new version when version tag is created
|
||||
event: tag
|
||||
tag: v*
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
- MFM button
|
||||
- Personal notes for all accounts
|
||||
- Fully revamp non-logged-in screen
|
||||
- Classic mode make instance icon bring up new context menu
|
||||
- Lookup/details for post/file/instance
|
||||
- [Rat mode?](https://stop.voring.me/notes/933fx97bmd)
|
||||
|
||||
|
@ -118,6 +117,13 @@
|
|||
- Sonic search
|
||||
- Popular color schemes, including Nord, Gruvbox, and Catppuccin
|
||||
- Non-nyaify cat mode
|
||||
- Post imports from other Calckey/Misskey/Mastodon/Pleroma/Akkoma instances
|
||||
- Improve Classic mode
|
||||
- Proper Helm/Kubernetes config
|
||||
- Multiple boost visibilities
|
||||
- Improve system emails
|
||||
- Mod mail
|
||||
- Focus trapping and button labels
|
||||
|
||||
## Implemented (remote)
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ representative at an online or offline event.
|
|||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
@thatonecalculator on Codeberg,
|
||||
`@thatonecalculator@stop.voring.me` or `@t1c@i.calckey.cloud` on the Fediverse,
|
||||
`@kainoa@calckey.social` on the Fediverse,
|
||||
or kainoa@t1c.dev via email.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# Contribution guide
|
||||
We're glad you're interested in contributing Calckey! In this document you will find the information you need to contribute to the project.
|
||||
|
||||
## Localization (l10n)
|
||||
Calckey uses [Weblate](hhttps://hosted.weblate.org/engage/calckey/) for localization management.
|
||||
## Translation (i18n)
|
||||
Calckey uses [Weblate](hhttps://hosted.weblate.org/engage/calckey/) for translation and internationalization management.
|
||||
|
||||
If your language is not listed in Weblate, please open an issue.
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ FROM node:19-alpine
|
|||
WORKDIR /calckey
|
||||
|
||||
# Install runtime dependencies
|
||||
RUN apk add --no-cache --no-progress tini ffmpeg vips-dev
|
||||
RUN apk add --no-cache --no-progress tini ffmpeg vips-dev zip unzip
|
||||
|
||||
COPY . ./
|
||||
|
||||
|
|
57
README.md
57
README.md
|
@ -7,6 +7,7 @@
|
|||
|
||||
[![no github badge](https://nogithub.codeberg.page/badge.svg)](https://nogithub.codeberg.page/)
|
||||
[![status badge](https://ci.codeberg.org/api/badges/calckey/calckey/status.svg)](https://ci.codeberg.org/calckey/calckey)
|
||||
[![opencollective badge](https://opencollective.com/calckey/tiers/badge.svg)](https://opencollective.com/Calckey)
|
||||
[![liberapay badge](https://img.shields.io/liberapay/receives/ThatOneCalculator?logo=liberapay)](https://liberapay.com/ThatOneCalculator)
|
||||
[![translate-badge](https://hosted.weblate.org/widgets/calckey/-/svg-badge.svg)](https://hosted.weblate.org/engage/calckey/)
|
||||
[![docker badge](https://img.shields.io/docker/pulls/thatonecalculator/calckey?logo=docker)](https://hub.docker.com/r/thatonecalculator/calckey)
|
||||
|
@ -46,6 +47,7 @@
|
|||
|
||||
# 🥂 Links
|
||||
|
||||
- 💸 OpenCollective: <https://opencollective.com/Calckey>
|
||||
- 💸 Liberapay: <https://liberapay.com/ThatOneCalculator>
|
||||
- Donate publicly to get your name on the Patron list!
|
||||
- 🚢 Flagship instance: <https://calckey.social>
|
||||
|
@ -67,9 +69,10 @@ If you have access to a server that supports one of the sources below, I recomme
|
|||
|
||||
[![Install on Ubuntu](https://pool.jortage.com/voringme/misskey/3b62a443-1b44-45cf-8f9e-f1c588f803ed.png)](https://codeberg.org/calckey/ubuntu-bash-install) [![Install on the Arch User Repository](https://pool.jortage.com/voringme/misskey/ba2a5c07-f078-43f1-8483-2e01acca9c40.png)](https://aur.archlinux.org/packages/calckey) [![Install Calckey with YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=calckey)
|
||||
|
||||
### 🐋 Docker
|
||||
## 🛳️ Containerization
|
||||
|
||||
[How to run Calckey with Docker](./docs/docker.md).
|
||||
- [🐳 How to run Calckey with Docker](https://codeberg.org/calckey/calckey/src/branch/develop/docs/docker.md)
|
||||
- [🛞 How to run Calckey with Kubernetes/Helm](https://codeberg.org/calckey/calckey/src/branch/develop/docs/kubernetes.md)
|
||||
|
||||
## 🧑💻 Dependencies
|
||||
|
||||
|
@ -77,17 +80,17 @@ If you have access to a server that supports one of the sources below, I recomme
|
|||
- Install with [nvm](https://github.com/nvm-sh/nvm)
|
||||
- 🐘 At least [PostgreSQL](https://www.postgresql.org/) v12
|
||||
- 🍱 At least [Redis](https://redis.io/) v6 (v7 recommend)
|
||||
- Web Proxy (one of the following)
|
||||
- 🍀 Nginx (recommended)
|
||||
- 🪶 Apache
|
||||
- 🦦 Caddy
|
||||
|
||||
### 😗 Optional dependencies
|
||||
|
||||
- [FFmpeg](https://ffmpeg.org/) for video transcoding
|
||||
- Full text search (choost one of the following)
|
||||
- 🦔 [Sonic](https://crates.io/crates/sonic-server) (highly recommended!)
|
||||
- Full text search (one of the following)
|
||||
- 🦔 [Sonic](https://crates.io/crates/sonic-server) (recommended)
|
||||
- [ElasticSearch](https://www.elastic.co/elasticsearch/)
|
||||
- Management (choose one of the following)
|
||||
- 🛰️ [pm2](https://pm2.io/)
|
||||
- 🐳 [Docker](https://docker.com)
|
||||
- Service manager (systemd, openrc, etc)
|
||||
|
||||
### 🏗️ Build dependencies
|
||||
|
||||
|
@ -116,6 +119,17 @@ corepack prepare pnpm@latest --activate
|
|||
pnpm i # --no-optional
|
||||
```
|
||||
|
||||
### pm2
|
||||
|
||||
To install pm2 run:
|
||||
|
||||
```
|
||||
npm i -g pm2
|
||||
pm2 install pm2-logrotate
|
||||
```
|
||||
|
||||
[`pm2-logrotate`](https://github.com/keymetrics/pm2-logrotate/blob/master/README.md) ensures that log files don't infinitely gather size, as Calckey produces a lot of logs.
|
||||
|
||||
## 🐘 Create database
|
||||
|
||||
Assuming you set up PostgreSQL correctly, all you have to run is:
|
||||
|
@ -152,16 +166,33 @@ In Calckey's directory, fill out the `sonic` section of `.config/default.yml` wi
|
|||
|
||||
## 🚚 Migrating from Misskey to Calckey
|
||||
|
||||
For migrating from Misskey v13, Misskey v12, and Foundkey, read [this document](./docs/migrate.md).
|
||||
For migrating from Misskey v13, Misskey v12, and Foundkey, read [this document](https://codeberg.org/calckey/calckey/src/branch/develop/docs/migrate.md).
|
||||
|
||||
## 🍀 NGINX
|
||||
## 🌐 Web proxy
|
||||
|
||||
### 🍀 Nginx (recommended)
|
||||
|
||||
- Run `sudo cp ./calckey.nginx.conf /etc/nginx/sites-available/ && cd /etc/nginx/sites-available/`
|
||||
- Edit `calckey.nginx.conf` to reflect your instance properly
|
||||
- Run `sudo cp ./calckey.nginx.conf ../sites-enabled/`
|
||||
- Run `sudo ln -s ./calckey.nginx.conf ../sites-enabled/calckey.nginx.conf`
|
||||
- Run `sudo nginx -t` to validate that the config is valid, then restart the NGINX service.
|
||||
|
||||
</details>
|
||||
### 🪶 Apache
|
||||
|
||||
- Run `sudo cp ./calckey.apache.conf /etc/apache2/sites-available/ && cd /etc/apache2/sites-available/`
|
||||
- Edit `calckey.apache.conf` to reflect your instance properly
|
||||
- Run `sudo a2ensite calckey.apache` to enable the site
|
||||
- Run `sudo service apache2 restart` to reload apache2 configuration
|
||||
|
||||
### 🦦 Caddy
|
||||
|
||||
- Add the following block to your `Caddyfile`, replacing `example.tld` with your own domain:
|
||||
```caddy
|
||||
example.tld {
|
||||
reverse_proxy http://127.0.0.1:3000
|
||||
}
|
||||
```
|
||||
- Reload your caddy configuration
|
||||
|
||||
## 🚀 Build and launch!
|
||||
|
||||
|
@ -180,7 +211,7 @@ pm2 start "NODE_ENV=production pnpm run start" --name Calckey
|
|||
|
||||
- When editing the config file, please don't fill out the settings at the bottom. They're designed *only* for managed hosting, not self hosting. Those settings are much better off being set in Calckey's control panel.
|
||||
- Port 3000 (used in the default config) might be already used on your server for something else. To find an open port for Calckey, run `for p in {3000..4000}; do ss -tlnH | tr -s ' ' | cut -d" " -sf4 | grep -q "${p}$" || echo "${p}"; done | head -n 1`. Replace 3000 with the minimum port and 4000 with the maximum port if you need it.
|
||||
- I'd recommend you use a S3 Bucket/CDN for Object Storage, especially if you use Docker.
|
||||
- I'd recommend you use a S3 Bucket/CDN for Object Storage, especially if you use Docker.
|
||||
- I'd ***strongly*** recommend against using CloudFlare, but if you do, make sure to turn code minification off.
|
||||
- For push notifications, run `npx web-push generate-vapid-keys`, then put the public and private keys into Control Panel > General > ServiceWorker.
|
||||
- For translations, make a [DeepL](https://deepl.com) account and generate an API key, then put it into Control Panel > General > DeepL Translation.
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
# Replace example.tld with your domain
|
||||
|
||||
<VirtualHost *:80>
|
||||
ServerName example.tld
|
||||
# For WebSocket
|
||||
ProxyPass "/streaming" "ws://127.0.0.1:3000/streaming/"
|
||||
# Proxy to Node
|
||||
ProxyPass "/" "http://127.0.0.1:3000/"
|
||||
ProxyPassReverse "/" "http://127.0.0.1:3000/"
|
||||
ProxyPreserveHost On
|
||||
# For files proxy
|
||||
AllowEncodedSlashes On
|
||||
</VirtualHost>
|
|
@ -0,0 +1,23 @@
|
|||
# Patterns to ignore when building packages.
|
||||
# This supports shell glob matching, relative path matching, and
|
||||
# negation (prefixed with !). Only one pattern per line.
|
||||
.DS_Store
|
||||
# Common VCS dirs
|
||||
.git/
|
||||
.gitignore
|
||||
.bzr/
|
||||
.bzrignore
|
||||
.hg/
|
||||
.hgignore
|
||||
.svn/
|
||||
# Common backup files
|
||||
*.swp
|
||||
*.bak
|
||||
*.tmp
|
||||
*.orig
|
||||
*~
|
||||
# Various IDEs
|
||||
.project
|
||||
.idea/
|
||||
*.tmproj
|
||||
.vscode/
|
|
@ -1,3 +1,38 @@
|
|||
apiVersion: v2
|
||||
name: misskey
|
||||
version: 0.0.0
|
||||
name: calckey
|
||||
description: A fun, new, open way to experience social media https://calckey.org
|
||||
|
||||
# A chart can be either an 'application' or a 'library' chart.
|
||||
#
|
||||
# Application charts are a collection of templates that can be packaged into versioned archives
|
||||
# to be deployed.
|
||||
#
|
||||
# Library charts provide useful utilities or functions for the chart developer. They're included as
|
||||
# a dependency of application charts to inject those utilities and functions into the rendering
|
||||
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
|
||||
type: application
|
||||
|
||||
# This is the chart version. This version number should be incremented each time you make changes
|
||||
# to the chart and its templates, including the app version.
|
||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||
version: 0.1.0
|
||||
|
||||
# This is the version number of the application being deployed. This version number should be
|
||||
# incremented each time you make changes to the application. Versions are not expected to
|
||||
# follow Semantic Versioning. They should reflect the version the application is using.
|
||||
# It is recommended to use it with quotes.
|
||||
appVersion: "rc"
|
||||
|
||||
dependencies:
|
||||
- name: elasticsearch
|
||||
version: 19.0.1
|
||||
repository: https://raw.githubusercontent.com/bitnami/charts/archive-full-index/bitnami
|
||||
condition: elasticsearch.enabled
|
||||
- name: postgresql
|
||||
version: 11.1.3
|
||||
repository: https://raw.githubusercontent.com/bitnami/charts/archive-full-index/bitnami
|
||||
condition: postgresql.enabled
|
||||
- name: redis
|
||||
version: 16.13.2
|
||||
repository: https://raw.githubusercontent.com/bitnami/charts/archive-full-index/bitnami
|
||||
condition: redis.enabled
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
# calckey
|
||||
|
||||
![Version: 0.1.0](https://img.shields.io/badge/Version-0.1.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: rc](https://img.shields.io/badge/AppVersion-rc-informational?style=flat-square)
|
||||
|
||||
A fun, new, open way to experience social media https://calckey.org
|
||||
|
||||
## Requirements
|
||||
|
||||
| Repository | Name | Version |
|
||||
|------------|------|---------|
|
||||
| https://raw.githubusercontent.com/bitnami/charts/archive-full-index/bitnami | elasticsearch | 19.0.1 |
|
||||
| https://raw.githubusercontent.com/bitnami/charts/archive-full-index/bitnami | postgresql | 11.1.3 |
|
||||
| https://raw.githubusercontent.com/bitnami/charts/archive-full-index/bitnami | redis | 16.13.2 |
|
||||
|
||||
## Values
|
||||
|
||||
| Key | Type | Default | Description |
|
||||
|-----|------|---------|-------------|
|
||||
| affinity | object | `{}` | |
|
||||
| autoscaling.enabled | bool | `false` | |
|
||||
| autoscaling.maxReplicas | int | `100` | |
|
||||
| autoscaling.minReplicas | int | `1` | |
|
||||
| autoscaling.targetCPUUtilizationPercentage | int | `80` | |
|
||||
| calckey.allowedPrivateNetworks | list | `[]` | If you want to allow calckey to connect to private ips, enter the cidrs here. |
|
||||
| calckey.domain | string | `"calckey.local"` | |
|
||||
| calckey.isManagedHosting | bool | `true` | |
|
||||
| calckey.objectStorage.access_key | string | `""` | |
|
||||
| calckey.objectStorage.access_secret | string | `""` | |
|
||||
| calckey.objectStorage.baseUrl | string | `""` | |
|
||||
| calckey.objectStorage.bucket | string | `""` | |
|
||||
| calckey.objectStorage.endpoint | string | `""` | |
|
||||
| calckey.objectStorage.managed | bool | `true` | |
|
||||
| calckey.objectStorage.prefix | string | `"files"` | |
|
||||
| calckey.objectStorage.region | string | `""` | |
|
||||
| calckey.reservedUsernames[0] | string | `"root"` | |
|
||||
| calckey.reservedUsernames[1] | string | `"admin"` | |
|
||||
| calckey.reservedUsernames[2] | string | `"administrator"` | |
|
||||
| calckey.reservedUsernames[3] | string | `"me"` | |
|
||||
| calckey.reservedUsernames[4] | string | `"system"` | |
|
||||
| calckey.smtp.from_address | string | `"notifications@example.com"` | |
|
||||
| calckey.smtp.login | string | `""` | |
|
||||
| calckey.smtp.managed | bool | `true` | |
|
||||
| calckey.smtp.password | string | `""` | |
|
||||
| calckey.smtp.port | int | `587` | |
|
||||
| calckey.smtp.server | string | `"smtp.mailgun.org"` | |
|
||||
| calckey.smtp.useImplicitSslTls | bool | `false` | |
|
||||
| elasticsearch | object | `{"auth":null,"enabled":false,"hostname":"","port":9200,"ssl":false}` | https://github.com/bitnami/charts/tree/master/bitnami/elasticsearch#parameters |
|
||||
| fullnameOverride | string | `""` | |
|
||||
| image.pullPolicy | string | `"IfNotPresent"` | |
|
||||
| image.repository | string | `"docker.io/thatonecalculator/calckey"` | |
|
||||
| image.tag | string | `""` | |
|
||||
| imagePullSecrets | list | `[]` | |
|
||||
| ingress.annotations | object | `{}` | |
|
||||
| ingress.className | string | `""` | |
|
||||
| ingress.enabled | bool | `false` | |
|
||||
| ingress.hosts[0].host | string | `"chart-example.local"` | |
|
||||
| ingress.hosts[0].paths[0].path | string | `"/"` | |
|
||||
| ingress.hosts[0].paths[0].pathType | string | `"ImplementationSpecific"` | |
|
||||
| ingress.tls | list | `[]` | |
|
||||
| nameOverride | string | `""` | |
|
||||
| nodeSelector | object | `{}` | |
|
||||
| podAnnotations | object | `{}` | |
|
||||
| podSecurityContext | object | `{}` | |
|
||||
| postgresql.auth.database | string | `"calckey_production"` | |
|
||||
| postgresql.auth.password | string | `""` | |
|
||||
| postgresql.auth.username | string | `"calckey"` | |
|
||||
| postgresql.enabled | bool | `true` | disable if you want to use an existing db; in which case the values below must match those of that external postgres instance |
|
||||
| redis.auth.password | string | `""` | you must set a password; the password generated by the redis chart will be rotated on each upgrade: |
|
||||
| redis.enabled | bool | `true` | |
|
||||
| redis.hostname | string | `""` | |
|
||||
| redis.port | int | `6379` | |
|
||||
| replicaCount | int | `1` | |
|
||||
| resources | object | `{}` | |
|
||||
| securityContext | object | `{}` | |
|
||||
| service.port | int | `80` | |
|
||||
| service.type | string | `"ClusterIP"` | |
|
||||
| serviceAccount.annotations | object | `{}` | |
|
||||
| serviceAccount.create | bool | `true` | |
|
||||
| serviceAccount.name | string | `""` | |
|
||||
| tolerations | list | `[]` | |
|
||||
|
||||
----------------------------------------------
|
||||
Autogenerated from chart metadata using [helm-docs v1.11.0](https://github.com/norwoodj/helm-docs/releases/v1.11.0)
|
|
@ -1,162 +0,0 @@
|
|||
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
# Misskey configuration
|
||||
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
# ┌─────┐
|
||||
#───┘ URL └─────────────────────────────────────────────────────
|
||||
|
||||
# Final accessible URL seen by a user.
|
||||
# url: https://example.tld/
|
||||
|
||||
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
||||
# URL SETTINGS AFTER THAT!
|
||||
|
||||
# ┌───────────────────────┐
|
||||
#───┘ Port and TLS settings └───────────────────────────────────
|
||||
|
||||
#
|
||||
# Misskey supports two deployment options for public.
|
||||
#
|
||||
|
||||
# Option 1: With Reverse Proxy
|
||||
#
|
||||
# +----- https://example.tld/ ------------+
|
||||
# +------+ |+-------------+ +----------------+|
|
||||
# | User | ---> || Proxy (443) | ---> | Misskey (3000) ||
|
||||
# +------+ |+-------------+ +----------------+|
|
||||
# +---------------------------------------+
|
||||
#
|
||||
# You need to setup reverse proxy. (eg. nginx)
|
||||
# You do not define 'https' section.
|
||||
|
||||
# Option 2: Standalone
|
||||
#
|
||||
# +- https://example.tld/ -+
|
||||
# +------+ | +---------------+ |
|
||||
# | User | ---> | | Misskey (443) | |
|
||||
# +------+ | +---------------+ |
|
||||
# +------------------------+
|
||||
#
|
||||
# You need to run Misskey as root.
|
||||
# You need to set Certificate in 'https' section.
|
||||
|
||||
# To use option 1, uncomment below line.
|
||||
port: 3000 # A port that your Misskey server should listen.
|
||||
|
||||
# To use option 2, uncomment below lines.
|
||||
#port: 443
|
||||
|
||||
#https:
|
||||
# # path for certification
|
||||
# key: /etc/letsencrypt/live/example.tld/privkey.pem
|
||||
# cert: /etc/letsencrypt/live/example.tld/fullchain.pem
|
||||
|
||||
# ┌──────────────────────────┐
|
||||
#───┘ PostgreSQL configuration └────────────────────────────────
|
||||
|
||||
db:
|
||||
host: localhost
|
||||
port: 5432
|
||||
|
||||
# Database name
|
||||
db: misskey
|
||||
|
||||
# Auth
|
||||
user: example-misskey-user
|
||||
pass: example-misskey-pass
|
||||
|
||||
# Whether disable Caching queries
|
||||
#disableCache: true
|
||||
|
||||
# Extra Connection options
|
||||
#extra:
|
||||
# ssl: true
|
||||
|
||||
# ┌─────────────────────┐
|
||||
#───┘ Redis configuration └─────────────────────────────────────
|
||||
|
||||
redis:
|
||||
host: localhost
|
||||
port: 6379
|
||||
#pass: example-pass
|
||||
#prefix: example-prefix
|
||||
#db: 1
|
||||
|
||||
# ┌─────────────────────────────┐
|
||||
#───┘ Elasticsearch configuration └─────────────────────────────
|
||||
|
||||
#elasticsearch:
|
||||
# host: localhost
|
||||
# port: 9200
|
||||
# ssl: false
|
||||
# user:
|
||||
# pass:
|
||||
|
||||
# ┌───────────────┐
|
||||
#───┘ ID generation └───────────────────────────────────────────
|
||||
|
||||
# You can select the ID generation method.
|
||||
# You don't usually need to change this setting, but you can
|
||||
# change it according to your preferences.
|
||||
|
||||
# Available methods:
|
||||
# aid ... Short, Millisecond accuracy
|
||||
# meid ... Similar to ObjectID, Millisecond accuracy
|
||||
# ulid ... Millisecond accuracy
|
||||
# objectid ... This is left for backward compatibility
|
||||
|
||||
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
||||
# ID SETTINGS AFTER THAT!
|
||||
|
||||
id: "aid"
|
||||
# ┌─────────────────────┐
|
||||
#───┘ Other configuration └─────────────────────────────────────
|
||||
|
||||
# Whether disable HSTS
|
||||
#disableHsts: true
|
||||
|
||||
# Number of worker processes
|
||||
#clusterLimit: 1
|
||||
|
||||
# Job concurrency per worker
|
||||
# deliverJobConcurrency: 128
|
||||
# inboxJobConcurrency: 16
|
||||
|
||||
# Job rate limiter
|
||||
# deliverJobPerSec: 128
|
||||
# inboxJobPerSec: 16
|
||||
|
||||
# Job attempts
|
||||
# deliverJobMaxAttempts: 12
|
||||
# inboxJobMaxAttempts: 8
|
||||
|
||||
# IP address family used for outgoing request (ipv4, ipv6 or dual)
|
||||
#outgoingAddressFamily: ipv4
|
||||
|
||||
# Syslog option
|
||||
#syslog:
|
||||
# host: localhost
|
||||
# port: 514
|
||||
|
||||
# Proxy for HTTP/HTTPS
|
||||
#proxy: http://127.0.0.1:3128
|
||||
|
||||
#proxyBypassHosts: [
|
||||
# 'example.com',
|
||||
# '192.0.2.8'
|
||||
#]
|
||||
|
||||
# Proxy for SMTP/SMTPS
|
||||
#proxySmtp: http://127.0.0.1:3128 # use HTTP/1.1 CONNECT
|
||||
#proxySmtp: socks4://127.0.0.1:1080 # use SOCKS4
|
||||
#proxySmtp: socks5://127.0.0.1:1080 # use SOCKS5
|
||||
|
||||
# Media Proxy
|
||||
#mediaProxy: https://example.com/proxy
|
||||
|
||||
#allowedPrivateNetworks: [
|
||||
# '127.0.0.1/32'
|
||||
#]
|
||||
|
||||
# Upload or download file size limits (bytes)
|
||||
#maxFileSize: 262144000
|
|
@ -1,8 +0,0 @@
|
|||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "misskey.fullname" . }}-configuration
|
||||
data:
|
||||
default.yml: |-
|
||||
{{ .Files.Get "files/default.yml"|nindent 4 }}
|
||||
url: {{ .Values.url }}
|
|
@ -1,47 +0,0 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "misskey.fullname" . }}
|
||||
labels:
|
||||
{{- include "misskey.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "misskey.selectorLabels" . | nindent 6 }}
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "misskey.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: misskey
|
||||
image: {{ .Values.image }}
|
||||
env:
|
||||
- name: NODE_ENV
|
||||
value: {{ .Values.environment }}
|
||||
volumeMounts:
|
||||
- name: {{ include "misskey.fullname" . }}-configuration
|
||||
mountPath: /misskey/.config
|
||||
readOnly: true
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
- name: postgres
|
||||
image: postgres:14-alpine
|
||||
env:
|
||||
- name: POSTGRES_USER
|
||||
value: "example-misskey-user"
|
||||
- name: POSTGRES_PASSWORD
|
||||
value: "example-misskey-pass"
|
||||
- name: POSTGRES_DB
|
||||
value: "misskey"
|
||||
ports:
|
||||
- containerPort: 5432
|
||||
- name: redis
|
||||
image: redis:alpine
|
||||
ports:
|
||||
- containerPort: 6379
|
||||
volumes:
|
||||
- name: {{ include "misskey.fullname" . }}-configuration
|
||||
configMap:
|
||||
name: {{ include "misskey.fullname" . }}-configuration
|
|
@ -0,0 +1,22 @@
|
|||
1. Get the application URL by running these commands:
|
||||
{{- if .Values.ingress.enabled }}
|
||||
{{- range $host := .Values.ingress.hosts }}
|
||||
{{- range .paths }}
|
||||
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- else if contains "NodePort" .Values.service.type }}
|
||||
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "calckey.fullname" . }})
|
||||
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
|
||||
echo http://$NODE_IP:$NODE_PORT
|
||||
{{- else if contains "LoadBalancer" .Values.service.type }}
|
||||
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
|
||||
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "calckey.fullname" . }}'
|
||||
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "calckey.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
|
||||
echo http://$SERVICE_IP:{{ .Values.service.port }}
|
||||
{{- else if contains "ClusterIP" .Values.service.type }}
|
||||
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "calckey.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
|
||||
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
|
||||
echo "Visit http://127.0.0.1:8080 to use your application"
|
||||
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
|
||||
{{- end }}
|
|
@ -1,14 +0,0 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "misskey.fullname" . }}
|
||||
annotations:
|
||||
dev.okteto.com/auto-ingress: "true"
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- port: 3000
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
{{- include "misskey.selectorLabels" . | nindent 4 }}
|
|
@ -1,7 +1,7 @@
|
|||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "misskey.name" -}}
|
||||
{{- define "calckey.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
|
@ -10,7 +10,7 @@ Create a default fully qualified app name.
|
|||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
If release name contains chart name it will be used as a full name.
|
||||
*/}}
|
||||
{{- define "misskey.fullname" -}}
|
||||
{{- define "calckey.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
|
@ -26,16 +26,16 @@ If release name contains chart name it will be used as a full name.
|
|||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "misskey.chart" -}}
|
||||
{{- define "calckey.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Common labels
|
||||
*/}}
|
||||
{{- define "misskey.labels" -}}
|
||||
helm.sh/chart: {{ include "misskey.chart" . }}
|
||||
{{ include "misskey.selectorLabels" . }}
|
||||
{{- define "calckey.labels" -}}
|
||||
helm.sh/chart: {{ include "calckey.chart" . }}
|
||||
{{ include "calckey.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
|
@ -45,18 +45,274 @@ app.kubernetes.io/managed-by: {{ .Release.Service }}
|
|||
{{/*
|
||||
Selector labels
|
||||
*/}}
|
||||
{{- define "misskey.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "misskey.name" . }}
|
||||
{{- define "calckey.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "calckey.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use
|
||||
*/}}
|
||||
{{- define "misskey.serviceAccountName" -}}
|
||||
{{- define "calckey.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
{{- default (include "misskey.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- default (include "calckey.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified name for dependent services.
|
||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
*/}}
|
||||
{{- define "calckey.elasticsearch.fullname" -}}
|
||||
{{- printf "%s-%s" .Release.Name "elasticsearch" | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "calckey.redis.fullname" -}}
|
||||
{{- printf "%s-%s" .Release.Name "redis" | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "calckey.postgresql.fullname" -}}
|
||||
{{- printf "%s-%s" .Release.Name "postgresql" | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
config/default.yml content
|
||||
*/}}
|
||||
{{- define "calckey.configDir.default.yml" -}}
|
||||
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
# Calckey configuration
|
||||
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
# ┌─────┐
|
||||
#───┘ URL └─────────────────────────────────────────────────────
|
||||
|
||||
# Final accessible URL seen by a user.
|
||||
url: "https://{{ .Values.calckey.domain }}/"
|
||||
|
||||
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
||||
# URL SETTINGS AFTER THAT!
|
||||
|
||||
# ┌───────────────────────┐
|
||||
#───┘ Port and TLS settings └───────────────────────────────────
|
||||
|
||||
#
|
||||
# Misskey requires a reverse proxy to support HTTPS connections.
|
||||
#
|
||||
# +----- https://example.tld/ ------------+
|
||||
# +------+ |+-------------+ +----------------+|
|
||||
# | User | ---> || Proxy (443) | ---> | Misskey (3000) ||
|
||||
# +------+ |+-------------+ +----------------+|
|
||||
# +---------------------------------------+
|
||||
#
|
||||
# You need to set up a reverse proxy. (e.g. nginx)
|
||||
# An encrypted connection with HTTPS is highly recommended
|
||||
# because tokens may be transferred in GET requests.
|
||||
|
||||
# The port that your Misskey server should listen on.
|
||||
port: 3000
|
||||
|
||||
# ┌──────────────────────────┐
|
||||
#───┘ PostgreSQL configuration └────────────────────────────────
|
||||
|
||||
db:
|
||||
{{- if .Values.postgresql.enabled }}
|
||||
host: {{ template "calckey.postgresql.fullname" . }}
|
||||
port: '5432'
|
||||
{{- else }}
|
||||
host: {{ .Values.postgresql.postgresqlHostname }}
|
||||
port: {{ .Values.postgresql.postgresqlPort | default "5432" | quote }}
|
||||
{{- end }}
|
||||
|
||||
# Database name
|
||||
db: {{ .Values.postgresql.auth.database }}
|
||||
|
||||
# Auth
|
||||
user: {{ .Values.postgresql.auth.username }}
|
||||
pass: "{{ .Values.postgresql.auth.password }}"
|
||||
|
||||
# Whether disable Caching queries
|
||||
#disableCache: true
|
||||
|
||||
# Extra Connection options
|
||||
#extra:
|
||||
# ssl: true
|
||||
|
||||
# ┌─────────────────────┐
|
||||
#───┘ Redis configuration └─────────────────────────────────────
|
||||
|
||||
redis:
|
||||
{{- if .Values.redis.enabled }}
|
||||
host: {{ template "calckey.redis.fullname" . }}-master
|
||||
{{- else }}
|
||||
host: {{ required "When the redis chart is disabled .Values.redis.hostname is required" .Values.redis.hostname }}
|
||||
{{- end }}
|
||||
port: {{ .Values.redis.port | default "6379" | quote }}
|
||||
#family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
||||
pass: {{ .Values.redis.auth.password | quote }}
|
||||
#prefix: example-prefix
|
||||
#db: 1
|
||||
|
||||
# ┌─────────────────────┐
|
||||
#───┘ Sonic configuration └─────────────────────────────────────
|
||||
|
||||
#sonic:
|
||||
# host: localhost
|
||||
# port: 1491
|
||||
# auth: SecretPassword
|
||||
# collection: notes
|
||||
# bucket: default
|
||||
|
||||
# ┌─────────────────────────────┐
|
||||
#───┘ Elasticsearch configuration └─────────────────────────────
|
||||
|
||||
{{- if .Values.elasticsearch.enabled }}
|
||||
elasticsearch:
|
||||
host: {{ template "mastodon.elasticsearch.fullname" . }}-master-hl
|
||||
port: 9200
|
||||
ssl: false
|
||||
{{- else if .Values.elasticsearch.hostname }}
|
||||
elasticsearch:
|
||||
host: {{ .Values.elasticsearch.hostname | quote }}
|
||||
port: {{ .Values.elasticsearch.port }}
|
||||
ssl: {{ .Values.elasticsearch.ssl }}
|
||||
{{- if .Values.elasticsearch.auth }}
|
||||
user: {{ .Values.elasticsearch.auth.username | quote }}
|
||||
pass: {{ .Values.elasticsearch.auth.password | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
# ┌───────────────┐
|
||||
#───┘ ID generation └───────────────────────────────────────────
|
||||
|
||||
# You can select the ID generation method.
|
||||
# You don't usually need to change this setting, but you can
|
||||
# change it according to your preferences.
|
||||
|
||||
# Available methods:
|
||||
# aid ... Short, Millisecond accuracy
|
||||
# meid ... Similar to ObjectID, Millisecond accuracy
|
||||
# ulid ... Millisecond accuracy
|
||||
# objectid ... This is left for backward compatibility
|
||||
|
||||
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
||||
# ID SETTINGS AFTER THAT!
|
||||
|
||||
id: 'aid'
|
||||
|
||||
# ┌─────────────────────┐
|
||||
#───┘ Other configuration └─────────────────────────────────────
|
||||
|
||||
# Max note length, should be < 8000.
|
||||
#maxNoteLength: 3000
|
||||
|
||||
# Maximum lenght of an image caption or file comment (default 1500, max 8192)
|
||||
#maxCaptionLength: 1500
|
||||
|
||||
# Reserved usernames that only the administrator can register with
|
||||
reservedUsernames:
|
||||
{{ .Values.calckey.reservedUsernames | toYaml }}
|
||||
|
||||
# Whether disable HSTS
|
||||
#disableHsts: true
|
||||
|
||||
# Number of worker processes
|
||||
#clusterLimit: 1
|
||||
|
||||
# Job concurrency per worker
|
||||
# deliverJobConcurrency: 128
|
||||
# inboxJobConcurrency: 16
|
||||
|
||||
# Job rate limiter
|
||||
# deliverJobPerSec: 128
|
||||
# inboxJobPerSec: 16
|
||||
|
||||
# Job attempts
|
||||
# deliverJobMaxAttempts: 12
|
||||
# inboxJobMaxAttempts: 8
|
||||
|
||||
# IP address family used for outgoing request (ipv4, ipv6 or dual)
|
||||
#outgoingAddressFamily: ipv4
|
||||
|
||||
# Syslog option
|
||||
#syslog:
|
||||
# host: localhost
|
||||
# port: 514
|
||||
|
||||
# Proxy for HTTP/HTTPS
|
||||
#proxy: http://127.0.0.1:3128
|
||||
|
||||
#proxyBypassHosts: [
|
||||
# 'example.com',
|
||||
# '192.0.2.8'
|
||||
#]
|
||||
|
||||
# Proxy for SMTP/SMTPS
|
||||
#proxySmtp: http://127.0.0.1:3128 # use HTTP/1.1 CONNECT
|
||||
#proxySmtp: socks4://127.0.0.1:1080 # use SOCKS4
|
||||
#proxySmtp: socks5://127.0.0.1:1080 # use SOCKS5
|
||||
|
||||
# Media Proxy
|
||||
#mediaProxy: https://example.com/proxy
|
||||
|
||||
# Proxy remote files (default: false)
|
||||
#proxyRemoteFiles: true
|
||||
|
||||
allowedPrivateNetworks:
|
||||
{{ .Values.calckey.allowedPrivateNetworks | toYaml }}
|
||||
|
||||
# TWA
|
||||
#twa:
|
||||
# nameSpace: android_app
|
||||
# packageName: tld.domain.twa
|
||||
# sha256CertFingerprints: ['AB:CD:EF']
|
||||
|
||||
# Upload or download file size limits (bytes)
|
||||
#maxFileSize: 262144000
|
||||
|
||||
# Managed hosting settings
|
||||
# !!!!!!!!!!
|
||||
# >>>>>> NORMAL SELF-HOSTERS, STAY AWAY! <<<<<<
|
||||
# >>>>>> YOU DON'T NEED THIS! <<<<<<
|
||||
# !!!!!!!!!!
|
||||
# Each category is optional, but if each item in each category is mandatory!
|
||||
# If you mess this up, that's on you, you've been warned...
|
||||
|
||||
#maxUserSignups: 100
|
||||
isManagedHosting: {{ .Values.calckey.isManagedHosting }}
|
||||
deepl:
|
||||
managed: false
|
||||
# authKey: ''
|
||||
# isPro: false
|
||||
#
|
||||
email:
|
||||
managed: {{ .Values.calckey.smtp.managed }}
|
||||
address: {{ .Values.calckey.smtp.from_address | quote }}
|
||||
host: {{ .Values.calckey.smtp.server | quote }}
|
||||
port: {{ .Values.calckey.smtp.port }}
|
||||
user: {{ .Values.calckey.smtp.login | quote }}
|
||||
pass: {{ .Values.calckey.smtp.password | quote }}
|
||||
useImplicitSslTls: {{ .Values.calckey.smtp.useImplicitSslTls }}
|
||||
objectStorage:
|
||||
managed: {{ .Values.calckey.objectStorage.managed }}
|
||||
baseUrl: {{ .Values.calckey.objectStorage.baseUrl | quote }}
|
||||
bucket: {{ .Values.calckey.objectStorage.bucket | quote }}
|
||||
prefix: {{ .Values.calckey.objectStorage.prefix | quote }}
|
||||
endpoint: {{ .Values.calckey.objectStorage.endpoint | quote }}
|
||||
region: {{ .Values.calckey.objectStorage.region | quote }}
|
||||
accessKey: {{ .Values.calckey.objectStorage.access_key | quote }}
|
||||
secretKey: {{ .Values.calckey.objectStorage.access_secret | quote }}
|
||||
useSsl: true
|
||||
connnectOverProxy: false
|
||||
setPublicReadOnUpload: true
|
||||
s3ForcePathStyle: true
|
||||
|
||||
# !!!!!!!!!!
|
||||
# >>>>>> AGAIN, NORMAL SELF-HOSTERS, STAY AWAY! <<<<<<
|
||||
# >>>>>> YOU DON'T NEED THIS, ABOVE SETTINGS ARE FOR MANAGED HOSTING ONLY! <<<<<<
|
||||
# !!!!!!!!!!
|
||||
|
||||
# Seriously. Do NOT fill out the above settings if you're self-hosting.
|
||||
# They're much better off being set from the control panel.
|
||||
{{- end }}
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "calckey.fullname" . }}
|
||||
labels:
|
||||
{{- include "calckey.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- if not .Values.autoscaling.enabled }}
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "calckey.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
checksum/secret-config: {{ include ( print $.Template.BasePath "/secret-config.yaml" ) . | sha256sum | quote }}
|
||||
{{- with .Values.podAnnotations }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "calckey.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "calckey.serviceAccountName" . }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
volumes:
|
||||
- name: config-volume
|
||||
secret:
|
||||
secretName: {{ template "calckey.fullname" . }}-config
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
env:
|
||||
- name: "NODE_ENV"
|
||||
value: "production"
|
||||
volumeMounts:
|
||||
- name: config-volume
|
||||
mountPath: /calckey/.config
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 3000
|
||||
protocol: TCP
|
||||
startupProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
failureThreshold: 30
|
||||
periodSeconds: 10
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
|
@ -0,0 +1,28 @@
|
|||
{{- if .Values.autoscaling.enabled }}
|
||||
apiVersion: autoscaling/v2beta1
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: {{ include "calckey.fullname" . }}
|
||||
labels:
|
||||
{{- include "calckey.labels" . | nindent 4 }}
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: {{ include "calckey.fullname" . }}
|
||||
minReplicas: {{ .Values.autoscaling.minReplicas }}
|
||||
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
|
||||
metrics:
|
||||
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
|
||||
{{- end }}
|
||||
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
|
||||
- type: Resource
|
||||
resource:
|
||||
name: memory
|
||||
targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -0,0 +1,61 @@
|
|||
{{- if .Values.ingress.enabled -}}
|
||||
{{- $fullName := include "calckey.fullname" . -}}
|
||||
{{- $svcPort := .Values.service.port -}}
|
||||
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
|
||||
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
{{- else -}}
|
||||
apiVersion: extensions/v1beta1
|
||||
{{- end }}
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $fullName }}
|
||||
labels:
|
||||
{{- include "calckey.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
|
||||
ingressClassName: {{ .Values.ingress.className }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.tls }}
|
||||
tls:
|
||||
{{- range .Values.ingress.tls }}
|
||||
- hosts:
|
||||
{{- range .hosts }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
secretName: {{ .secretName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.ingress.hosts }}
|
||||
- host: {{ .host | quote }}
|
||||
http:
|
||||
paths:
|
||||
{{- range .paths }}
|
||||
- path: {{ .path }}
|
||||
{{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
|
||||
pathType: {{ .pathType }}
|
||||
{{- end }}
|
||||
backend:
|
||||
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||
service:
|
||||
name: {{ $fullName }}
|
||||
port:
|
||||
number: {{ $svcPort }}
|
||||
{{- else }}
|
||||
serviceName: {{ $fullName }}
|
||||
servicePort: {{ $svcPort }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -0,0 +1,9 @@
|
|||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ template "calckey.fullname" . }}-config
|
||||
labels:
|
||||
{{- include "calckey.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
data:
|
||||
default.yml: {{ include "calckey.configDir.default.yml" . | b64enc }}
|
|
@ -0,0 +1,15 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "calckey.fullname" . }}
|
||||
labels:
|
||||
{{- include "calckey.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
{{- include "calckey.selectorLabels" . | nindent 4 }}
|
|
@ -0,0 +1,12 @@
|
|||
{{- if .Values.serviceAccount.create -}}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "calckey.serviceAccountName" . }}
|
||||
labels:
|
||||
{{- include "calckey.labels" . | nindent 4 }}
|
||||
{{- with .Values.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -0,0 +1,15 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: "{{ include "calckey.fullname" . }}-test-connection"
|
||||
labels:
|
||||
{{- include "calckey.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": test
|
||||
spec:
|
||||
containers:
|
||||
- name: wget
|
||||
image: busybox
|
||||
command: ['wget']
|
||||
args: ['{{ include "calckey.fullname" . }}:{{ .Values.service.port }}']
|
||||
restartPolicy: Never
|
|
@ -0,0 +1,158 @@
|
|||
# Default values for calckey.
|
||||
# This is a YAML-formatted file.
|
||||
# Declare variables to be passed into your templates.
|
||||
|
||||
replicaCount: 1
|
||||
|
||||
image:
|
||||
repository: docker.io/thatonecalculator/calckey
|
||||
pullPolicy: IfNotPresent
|
||||
# Overrides the image tag whose default is the chart appVersion.
|
||||
tag: ""
|
||||
|
||||
calckey:
|
||||
isManagedHosting: true
|
||||
domain: calckey.local
|
||||
|
||||
smtp:
|
||||
managed: true
|
||||
from_address: notifications@example.com
|
||||
port: 587
|
||||
server: smtp.mailgun.org
|
||||
useImplicitSslTls: false
|
||||
login: ""
|
||||
password: ""
|
||||
|
||||
objectStorage:
|
||||
managed: true
|
||||
access_key: ""
|
||||
access_secret: ""
|
||||
baseUrl: "" # e.g. "https://my-bucket.nyc3.cdn.digitaloceanspaces.com"
|
||||
bucket: "" # e.g. "my-bucket"
|
||||
prefix: files
|
||||
endpoint: "" # e.g. "nyc3.digitaloceanspaces.com:443"
|
||||
region: "" # e.g. "nyc3"
|
||||
|
||||
# -- If you want to allow calckey to connect to private ips, enter the cidrs here.
|
||||
allowedPrivateNetworks: []
|
||||
# - "10.0.0.0/8"
|
||||
|
||||
reservedUsernames:
|
||||
- root
|
||||
- admin
|
||||
- administrator
|
||||
- me
|
||||
- system
|
||||
|
||||
# https://github.com/bitnami/charts/tree/master/bitnami/postgresql#parameters
|
||||
postgresql:
|
||||
# -- disable if you want to use an existing db; in which case the values below
|
||||
# must match those of that external postgres instance
|
||||
enabled: true
|
||||
# postgresqlHostname: preexisting-postgresql
|
||||
# postgresqlPort: 5432
|
||||
auth:
|
||||
database: calckey_production
|
||||
username: calckey
|
||||
# you must set a password; the password generated by the postgresql chart will
|
||||
# be rotated on each upgrade:
|
||||
# https://github.com/bitnami/charts/tree/master/bitnami/postgresql#upgrade
|
||||
password: ""
|
||||
|
||||
# https://github.com/bitnami/charts/tree/master/bitnami/redis#parameters
|
||||
redis:
|
||||
# disable if you want to use an existing redis instance; in which case the
|
||||
# values below must match those of that external redis instance
|
||||
enabled: true
|
||||
hostname: ""
|
||||
port: 6379
|
||||
auth:
|
||||
# -- you must set a password; the password generated by the redis chart will be
|
||||
# rotated on each upgrade:
|
||||
password: ""
|
||||
|
||||
# -- https://github.com/bitnami/charts/tree/master/bitnami/elasticsearch#parameters
|
||||
elasticsearch:
|
||||
# disable if you want to use an existing redis instance; in which case the
|
||||
# values below must match those of that external elasticsearch instance
|
||||
enabled: false
|
||||
hostname: ""
|
||||
port: 9200
|
||||
ssl: false
|
||||
auth: {}
|
||||
# username: ""
|
||||
# password: ""
|
||||
# @ignored
|
||||
image:
|
||||
tag: 7
|
||||
|
||||
imagePullSecrets: []
|
||||
nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
|
||||
serviceAccount:
|
||||
# Specifies whether a service account should be created
|
||||
create: true
|
||||
# Annotations to add to the service account
|
||||
annotations: {}
|
||||
# The name of the service account to use.
|
||||
# If not set and create is true, a name is generated using the fullname template
|
||||
name: ""
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
podSecurityContext: {}
|
||||
# fsGroup: 2000
|
||||
|
||||
securityContext: {}
|
||||
# capabilities:
|
||||
# drop:
|
||||
# - ALL
|
||||
# readOnlyRootFilesystem: true
|
||||
# runAsNonRoot: true
|
||||
# runAsUser: 1000
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 80
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
className: ""
|
||||
annotations: {}
|
||||
# kubernetes.io/ingress.class: nginx
|
||||
# kubernetes.io/tls-acme: "true"
|
||||
hosts:
|
||||
- host: chart-example.local
|
||||
paths:
|
||||
- path: /
|
||||
pathType: ImplementationSpecific
|
||||
tls: []
|
||||
# - secretName: chart-example-tls
|
||||
# hosts:
|
||||
# - chart-example.local
|
||||
|
||||
resources: {}
|
||||
# We usually recommend not to specify default resources and to leave this as a conscious
|
||||
# choice for the user. This also increases chances charts run on environments with little
|
||||
# resources, such as Minikube. If you do want to specify resources, uncomment the following
|
||||
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
|
||||
# limits:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
# requests:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
|
||||
autoscaling:
|
||||
enabled: false
|
||||
minReplicas: 1
|
||||
maxReplicas: 100
|
||||
targetCPUUtilizationPercentage: 80
|
||||
# targetMemoryUtilizationPercentage: 80
|
||||
|
||||
nodeSelector: {}
|
||||
|
||||
tolerations: []
|
||||
|
||||
affinity: {}
|
|
@ -1,3 +0,0 @@
|
|||
url: https://example.tld/
|
||||
image: okteto.dev/misskey
|
||||
environment: production
|
|
@ -2,7 +2,6 @@ describe('After user signed in', () => {
|
|||
beforeEach(() => {
|
||||
cy.resetState();
|
||||
cy.viewport('macbook-16');
|
||||
|
||||
// インスタンス初期セットアップ
|
||||
cy.registerUser('admin', 'pass', true);
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
# 🌎 Calckey Developer Docs
|
||||
|
||||
## Nix Dev Environment
|
||||
The Calckey repo comes with a Nix-based shell environment to help make development as easy as possible!
|
||||
|
||||
Please note, however, that this environment will not work on Windows outside of a WSL2 environment.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Installed the [Nix Package Manager](https://nixos.org/download.html)
|
||||
- Installed [direnv](https://direnv.net/docs/installation.html) and added its hook to your shell.
|
||||
|
||||
Once the repo is cloned to your computer, follow these next few steps inside the Calckey folder:
|
||||
|
||||
- Run `direnv allow`. This will build the environment and install all needed tools.
|
||||
- Run `install-deps`, then `prepare-config`, to install the node dependencies and prepare the needed config files.
|
||||
- In a second terminal, run `devenv up`. This will spawn a **Redis** server, a **Postgres** server, and the **Calckey** server in dev mode.
|
||||
- Once you see the Calckey banner printed in your second terminal, run `migrate` in the first.
|
||||
- Once migrations finish, open http://localhost:3000 in your web browser.
|
||||
- You should now see the admin user creation screen!
|
||||
|
||||
Note: When you want to restart a dev server, all you need to do is run `devenv up`, no other steps are necessary.
|
|
@ -0,0 +1,45 @@
|
|||
# Running a Calckey instance with Kubernetes and Helm
|
||||
|
||||
This is a [Helm](https://helm.sh/) chart directory in the root of the project
|
||||
that you can use to deploy calckey to a Kubernetes cluster
|
||||
|
||||
## Deployment
|
||||
|
||||
1. Copy the example helm values and make your changes:
|
||||
```shell
|
||||
cp .config/helm_values_example.yml .config/helm_values.yml
|
||||
```
|
||||
|
||||
2. Update helm dependencies:
|
||||
```shell
|
||||
cd chart
|
||||
helm dependency list $dir 2> /dev/null | tail +2 | head -n -1 | awk '{ print "helm repo add " $1 " " $3 }' | while read cmd; do $cmd; done;
|
||||
cd ../
|
||||
```
|
||||
|
||||
3. Create the calckey helm release (also used to update existing deployment):
|
||||
```shell
|
||||
helm upgrade \
|
||||
--install \
|
||||
--namespace calckey \
|
||||
--create-namespace \
|
||||
calckey chart/ \
|
||||
-f .config/helm_values.yml
|
||||
```
|
||||
|
||||
4. Watch your calckey instance spin up:
|
||||
```shell
|
||||
kubectl -n calckey get po -w
|
||||
```
|
||||
|
||||
5. Initial the admin user and managed config:
|
||||
```shell
|
||||
export CALCKEY_USERNAME="my_desired_admin_handle" && \
|
||||
export CALCKEY_PASSWORD="myDesiredInitialPassword" && \
|
||||
export CALCKEY_HOST="calckey.example.com" && \
|
||||
export CALCKEY_TOKEN=$(curl -X POST https://$CALCKEY_HOST/api/admin/accounts/create -H "Content-Type: application/json" -d "{ \"username\":\"$CALCKEY_USERNAME\", \"password\":\"$CALCKEY_PASSWORD\" }" | jq -r '.token') && \
|
||||
echo "Save this token: ${CALCKEY_TOKEN}" && \
|
||||
curl -X POST -H "Authorization: Bearer $CALCKEY_TOKEN" https://$CALCKEY_HOST/api/admin/accounts/hosted
|
||||
```
|
||||
|
||||
6. Enjoy!
|
|
@ -0,0 +1,294 @@
|
|||
{
|
||||
"nodes": {
|
||||
"devenv": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat",
|
||||
"nix": "nix",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"pre-commit-hooks": "pre-commit-hooks"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1682953188,
|
||||
"narHash": "sha256-MFH6yK7QnEV6+T96Pt++lH8ozDn4YqzaOXAS6u5h3mM=",
|
||||
"owner": "cachix",
|
||||
"repo": "devenv",
|
||||
"rev": "c388b8c57116a71174d26b09c0c38b4b6b5bac3a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "cachix",
|
||||
"repo": "devenv",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"fenix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"rust-analyzer-src": "rust-analyzer-src"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1682922129,
|
||||
"narHash": "sha256-qnhkfksuuSLbN5UJM+KSCMSRC13bXosr6Ed3NwerRno=",
|
||||
"owner": "nix-community",
|
||||
"repo": "fenix",
|
||||
"rev": "c1f90f80ba4d60bea60685dd4515fb22d53279cc",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "fenix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-compat": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1673956053,
|
||||
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-parts": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": "nixpkgs-lib"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1680392223,
|
||||
"narHash": "sha256-n3g7QFr85lDODKt250rkZj2IFS3i4/8HBU2yKHO3tqw=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "dcc36e45d054d7bb554c9cdab69093debd91a0b5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils": {
|
||||
"locked": {
|
||||
"lastModified": 1667395993,
|
||||
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"gitignore": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"devenv",
|
||||
"pre-commit-hooks",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1660459072,
|
||||
"narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"rev": "a20de23b925fd8264fd7fad6454652e142fd7f73",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"lowdown-src": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1633514407,
|
||||
"narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=",
|
||||
"owner": "kristapsdz",
|
||||
"repo": "lowdown",
|
||||
"rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "kristapsdz",
|
||||
"repo": "lowdown",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nix": {
|
||||
"inputs": {
|
||||
"lowdown-src": "lowdown-src",
|
||||
"nixpkgs": [
|
||||
"devenv",
|
||||
"nixpkgs"
|
||||
],
|
||||
"nixpkgs-regression": "nixpkgs-regression"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1676545802,
|
||||
"narHash": "sha256-EK4rZ+Hd5hsvXnzSzk2ikhStJnD63odF7SzsQ8CuSPU=",
|
||||
"owner": "domenkozar",
|
||||
"repo": "nix",
|
||||
"rev": "7c91803598ffbcfe4a55c44ac6d49b2cf07a527f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "domenkozar",
|
||||
"ref": "relaxed-flakes",
|
||||
"repo": "nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1677534593,
|
||||
"narHash": "sha256-PuZSAHeq4/9pP/uYH1FcagQ3nLm/DrDrvKi/xC9glvw=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "3ad64d9e2d5bf80c877286102355b1625891ae9a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-lib": {
|
||||
"locked": {
|
||||
"dir": "lib",
|
||||
"lastModified": 1680213900,
|
||||
"narHash": "sha256-cIDr5WZIj3EkKyCgj/6j3HBH4Jj1W296z7HTcWj1aMA=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "e3652e0735fbec227f342712f180f4f21f0594f2",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"dir": "lib",
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-regression": {
|
||||
"locked": {
|
||||
"lastModified": 1643052045,
|
||||
"narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-stable": {
|
||||
"locked": {
|
||||
"lastModified": 1673800717,
|
||||
"narHash": "sha256-SFHraUqLSu5cC6IxTprex/nTsI81ZQAtDvlBvGDWfnA=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "2f9fd351ec37f5d479556cd48be4ca340da59b8f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-22.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1682929865,
|
||||
"narHash": "sha256-jxVrgnf5QNjO+XoxDxUWtN2G5xyJSGZ5SWDQFxMuHxc=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "f2e9a130461950270f87630b11132323706b4d91",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"pre-commit-hooks": {
|
||||
"inputs": {
|
||||
"flake-compat": [
|
||||
"devenv",
|
||||
"flake-compat"
|
||||
],
|
||||
"flake-utils": "flake-utils",
|
||||
"gitignore": "gitignore",
|
||||
"nixpkgs": [
|
||||
"devenv",
|
||||
"nixpkgs"
|
||||
],
|
||||
"nixpkgs-stable": "nixpkgs-stable"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1677160285,
|
||||
"narHash": "sha256-tBzpCjMP+P3Y3nKLYvdBkXBg3KvTMo3gvi8tLQaqXVY=",
|
||||
"owner": "cachix",
|
||||
"repo": "pre-commit-hooks.nix",
|
||||
"rev": "2bd861ab81469428d9c823ef72c4bb08372dd2c4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "cachix",
|
||||
"repo": "pre-commit-hooks.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"devenv": "devenv",
|
||||
"fenix": "fenix",
|
||||
"flake-parts": "flake-parts",
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
}
|
||||
},
|
||||
"rust-analyzer-src": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1682886915,
|
||||
"narHash": "sha256-FPQKPvlHIU2DsDF6GMoRtrZhil0vHi6MFd8vpKEx/n8=",
|
||||
"owner": "rust-lang",
|
||||
"repo": "rust-analyzer",
|
||||
"rev": "3a27518fee5a723005299cf49e2d58a842a261ca",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "rust-lang",
|
||||
"ref": "nightly",
|
||||
"repo": "rust-analyzer",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
{
|
||||
description = "Calckey development flake";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
|
||||
# Flake Parts framework(https://flake.parts)
|
||||
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||
# Devenv for better devShells(https://devenv.sh)
|
||||
devenv.url = "github:cachix/devenv";
|
||||
# Fenix for rust development
|
||||
fenix.url = "github:nix-community/fenix";
|
||||
fenix.inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
outputs = inputs@{ flake-parts, ... }:
|
||||
flake-parts.lib.mkFlake { inherit inputs; } {
|
||||
imports = [
|
||||
inputs.devenv.flakeModule
|
||||
];
|
||||
|
||||
# Define the systems that this works on. Only tested with x66_64-linux, add more if you test and it works.
|
||||
systems = [
|
||||
"x86_64-linux"
|
||||
];
|
||||
# Expose these attributes for every system defined above.
|
||||
perSystem = { config, pkgs, ... }: {
|
||||
# Devenv shells
|
||||
devenv = {
|
||||
shells = {
|
||||
# The default shell, used by nix-direnv
|
||||
default = {
|
||||
name = "calckey-dev-shell";
|
||||
# Add additional packages to our environment
|
||||
packages = [
|
||||
pkgs.nodePackages.pnpm
|
||||
|
||||
pkgs.python3
|
||||
];
|
||||
# No need to warn on a new version, we'll update as needed.
|
||||
devenv.warnOnNewVersion = false;
|
||||
# Enable typescript support
|
||||
languages.typescript.enable = true;
|
||||
# Enable javascript for NPM and PNPM
|
||||
languages.javascript.enable = true;
|
||||
languages.javascript.package = pkgs.nodejs_19;
|
||||
# Enable stable Rust for the backend
|
||||
languages.rust.enable = true;
|
||||
languages.rust.version = "stable";
|
||||
processes = {
|
||||
dev-server.exec = "pnpm run dev";
|
||||
};
|
||||
scripts = {
|
||||
build.exec = "pnpm run build";
|
||||
clean.exec = "pnpm run clean";
|
||||
clear-state.exec = "rm -rf .devenv/state/redis .devenv/state/postgres";
|
||||
format.exec = "pnpm run format";
|
||||
install-deps.exec = "pnpm install";
|
||||
migrate.exec = "pnpm run migrate";
|
||||
prepare-config.exec = "cp .config/devenv.yml .config/default.yml";
|
||||
};
|
||||
services = {
|
||||
postgres = {
|
||||
enable = true;
|
||||
package = pkgs.postgresql_12;
|
||||
initialDatabases = [{
|
||||
name = "calckey";
|
||||
}];
|
||||
initialScript = ''
|
||||
CREATE USER calckey WITH PASSWORD 'calckey';
|
||||
ALTER USER calckey WITH SUPERUSER;
|
||||
GRANT ALL ON DATABASE calckey TO calckey;
|
||||
'';
|
||||
listen_addresses = "127.0.0.1";
|
||||
port = 5432;
|
||||
};
|
||||
redis = {
|
||||
enable = true;
|
||||
bind = "127.0.0.1";
|
||||
port = 6379;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,18 +1,18 @@
|
|||
_lang_: "Català"
|
||||
headlineMisskey: "Una xarxa social de codi obert, descentralitzada i gratuita per\
|
||||
\ sempre \U0001F680"
|
||||
introMisskey: "Benvinguts! Calckey es una plataforma social de codi obert, descentralitzada\
|
||||
\ i gratuita per sempre! \U0001F680"
|
||||
headlineMisskey: "Una xarxa social de codi obert, descentralitzada i gratuïta per\
|
||||
\ a sempre! \U0001F680"
|
||||
introMisskey: "Benvinguts! Calckey és una plataforma social de codi obert, descentralitzada\
|
||||
\ i gratuïta per a sempre! \U0001F680"
|
||||
monthAndDay: "{day}/{month}"
|
||||
search: "Cercar"
|
||||
search: "Cerca"
|
||||
notifications: "Notificacions"
|
||||
username: "Nom d'usuari"
|
||||
password: "Contrasenya"
|
||||
forgotPassword: "Contrasenya oblidada"
|
||||
fetchingAsApObject: "Cercant en el Fediverse"
|
||||
ok: "OK"
|
||||
ok: "D'acord"
|
||||
gotIt: "Ho he entès!"
|
||||
cancel: "Cancel·lar"
|
||||
cancel: "Cancel·la"
|
||||
enterUsername: "Introdueix el teu nom d'usuari"
|
||||
renotedBy: "Impulsat per {user}"
|
||||
noNotes: "Cap publicació"
|
||||
|
@ -21,69 +21,69 @@ instance: "Instància"
|
|||
settings: "Preferències"
|
||||
basicSettings: "Configuració bàsica"
|
||||
otherSettings: "Altres opcions"
|
||||
openInWindow: "Obrir en una finestra nova"
|
||||
openInWindow: "Obre en una finestra nova"
|
||||
profile: "Perfil"
|
||||
timeline: "Línia de temps"
|
||||
noAccountDescription: "Aquest usuari encara no ha escrit la seva biografia."
|
||||
login: "Iniciar sessió"
|
||||
login: "Inicia sessió"
|
||||
loggingIn: "Iniciant sessió"
|
||||
logout: "Tancar sessió"
|
||||
signup: "Registrar-se"
|
||||
uploading: "Pujant..."
|
||||
save: "Desar"
|
||||
logout: "Tanca la sessió"
|
||||
signup: "Registra'm"
|
||||
uploading: "S'està pujant…"
|
||||
save: "Desa"
|
||||
users: "Usuaris"
|
||||
addUser: "Afegir un usuari"
|
||||
favorite: "Afegir a favorits"
|
||||
favorites: "Favorits"
|
||||
unfavorite: "Eliminar de favorits"
|
||||
favorited: "Afegit a favorits."
|
||||
alreadyFavorited: "Ja s'ha afegit a favorits."
|
||||
cantFavorite: "No s'ha pogut afegir a favorits."
|
||||
pin: "Fixar al perfil"
|
||||
unpin: "Deixar de fixar al perfil"
|
||||
copyContent: "Còpia el contingut"
|
||||
copyLink: "Còpia l'enllaç"
|
||||
delete: "Esborra"
|
||||
deleteAndEdit: "Esborrar i edita"
|
||||
deleteAndEditConfirm: "Estàs segur que vols esborrar aquesta publicació i editar-la?\
|
||||
\ Perdràs totes les reaccions, impulsos i respostes."
|
||||
addToList: "Afegir a la llista"
|
||||
sendMessage: "Enviar un missatge"
|
||||
copyUsername: "Còpia nom d'usuari"
|
||||
searchUser: "Cercar un usuari"
|
||||
addUser: "Afegeix un usuari"
|
||||
favorite: "Afegeix als marcadors"
|
||||
favorites: "Marcadors"
|
||||
unfavorite: "Elimina dels marcadors"
|
||||
favorited: "S'ha afegit el marcador."
|
||||
alreadyFavorited: "Ja està afegida als marcadors."
|
||||
cantFavorite: "No s'ha pogut afegir als marcadors."
|
||||
pin: "Fixa al perfil"
|
||||
unpin: "Deixa de fixar al perfil"
|
||||
copyContent: "Copia el contingut"
|
||||
copyLink: "Copia l'enllaç"
|
||||
delete: "Elimina"
|
||||
deleteAndEdit: "Elimina i edita"
|
||||
deleteAndEditConfirm: "Segur que vols eliminar la publicació i editar-la? Perdràs\
|
||||
\ totes les reaccions, impulsos i respostes."
|
||||
addToList: "Afegeix a la llista"
|
||||
sendMessage: "Envia un missatge"
|
||||
copyUsername: "Copia el nom d'usuari"
|
||||
searchUser: "Cerca un usuari"
|
||||
reply: "Respon"
|
||||
loadMore: "Carregar més"
|
||||
showMore: "Veure més"
|
||||
loadMore: "Carrega'n més"
|
||||
showMore: "Mostra'n més"
|
||||
youGotNewFollower: "t'ha seguit"
|
||||
receiveFollowRequest: "Sol·licitud de seguiment rebuda"
|
||||
followRequestAccepted: "Sol·licitud de seguiment acceptada"
|
||||
mention: "Menció"
|
||||
mentions: "Mencions"
|
||||
directNotes: "Missatges directes"
|
||||
importAndExport: "Importar / Exportar Dades"
|
||||
import: "Importar"
|
||||
export: "Exportar"
|
||||
importAndExport: "Importa/exporta dades"
|
||||
import: "Importa"
|
||||
export: "Exporta"
|
||||
files: "Fitxers"
|
||||
download: "Descarregar"
|
||||
driveFileDeleteConfirm: "Estàs segur que vols esborrar el fitxer \"{nom}\"? S'eliminarà\
|
||||
\ de totes les notes que el continguin com a fitxer adjunt."
|
||||
unfollowConfirm: "Estàs segur que vols deixar de seguir {name}?"
|
||||
download: "Baixa"
|
||||
driveFileDeleteConfirm: "Segur que vols eliminar el fitxer «{name}»? S'eliminarà de\
|
||||
\ totes les notes que el continguin com a fitxer adjunt."
|
||||
unfollowConfirm: "Segur que vols deixar de seguir {name}?"
|
||||
exportRequested: "Has sol·licitat una exportació. Això pot trigar una estona. S'afegirà\
|
||||
\ al teu Disc un cop completada."
|
||||
importRequested: "Has sol·licitat una importació. Això pot trigar una estona."
|
||||
lists: "Llistes"
|
||||
noLists: "No tens cap llista"
|
||||
noLists: "No teniu cap llista"
|
||||
note: "Publicació"
|
||||
notes: "Notes"
|
||||
notes: "Publicacions"
|
||||
following: "Seguint"
|
||||
followers: "Seguidors"
|
||||
followsYou: "Et segueix"
|
||||
createList: "Crear llista"
|
||||
manageLists: "Gestionar les llistes"
|
||||
createList: "Crea una llista"
|
||||
manageLists: "Gestiona les llistes"
|
||||
error: "Error"
|
||||
somethingHappened: "S'ha produït un error"
|
||||
retry: "Torna-ho a intentar"
|
||||
pageLoadError: "Alguna cosa a sortit malament al carregar la pàgina."
|
||||
pageLoadError: "S'ha produït un error en carregar la pàgina."
|
||||
pageLoadErrorDescription: "Això normalment es deu a errors de xarxa o a la memòria\
|
||||
\ cau del navegador. Prova d'esborrar la memòria cau i torna-ho a provar després\
|
||||
\ d'esperar una estona."
|
||||
|
@ -94,32 +94,32 @@ enterListName: "Introdueix un nom per a la llista"
|
|||
privacy: "Privadesa"
|
||||
makeFollowManuallyApprove: "Les sol·licituds de seguiment requereixen aprovació"
|
||||
defaultNoteVisibility: "Visibilitat per defecte"
|
||||
follow: "Seguir"
|
||||
followRequest: "Enviar sol·licitud de seguiment"
|
||||
follow: "Segueix"
|
||||
followRequest: "Segueix"
|
||||
followRequests: "Sol·licituds de seguiment"
|
||||
unfollow: "Deixar de seguir"
|
||||
unfollow: "Deixa de seguir"
|
||||
followRequestPending: "Sol·licituds de seguiment pendents"
|
||||
enterEmoji: "Introduir un emoji"
|
||||
renote: "Impuls"
|
||||
unrenote: "Anul·lar impuls"
|
||||
renoted: "Impulsat."
|
||||
enterEmoji: "Introdueix un emoji"
|
||||
renote: "Impulsa"
|
||||
unrenote: "Anul·la l'impuls"
|
||||
renoted: "S'ha impulsat."
|
||||
cantRenote: "Aquesta publicació no es pot impulsar."
|
||||
cantReRenote: "No es pot impulsar un impuls."
|
||||
quote: "Cita"
|
||||
pinnedNote: "Publicació fixada"
|
||||
pinned: "Fixar al perfil"
|
||||
pinned: "Fixa al perfil"
|
||||
you: "Tu"
|
||||
clickToShow: "Fes clic per mostrar"
|
||||
clickToShow: "Fes clic per a mostrar"
|
||||
sensitive: "NSFW"
|
||||
add: "Afegir"
|
||||
add: "Afegeix"
|
||||
reaction: "Reaccions"
|
||||
reactionSetting: "Reaccions a mostrar al selector de reaccions"
|
||||
reactionSettingDescription2: "Arrossega per reordenar, fes clic per suprimir, prem\
|
||||
\ \"+\" per afegir."
|
||||
rememberNoteVisibility: "Recorda la configuració de visibilitat de les notes"
|
||||
attachCancel: "Eliminar el fitxer adjunt"
|
||||
markAsSensitive: "Marcar com a NSFW"
|
||||
unmarkAsSensitive: "Desmarcar com a NSFW"
|
||||
attachCancel: "Elimina el fitxer adjunt"
|
||||
markAsSensitive: "Marca com a NSFW"
|
||||
unmarkAsSensitive: "Desmarca com a NSFW"
|
||||
enterFileName: "Introdueix un nom de fitxer"
|
||||
mute: "Silencia"
|
||||
unmute: "Deixa de silenciar"
|
||||
|
@ -128,7 +128,7 @@ unblock: "Desbloqueja"
|
|||
suspend: "Suspèn"
|
||||
unsuspend: "Treu la suspensió"
|
||||
instances: "Instàncies"
|
||||
remove: "Eliminar"
|
||||
remove: "Elimina"
|
||||
nsfw: "NSFW"
|
||||
pinnedNotes: "Publicacions fixades"
|
||||
userList: "Llistes"
|
||||
|
@ -738,39 +738,39 @@ _deck:
|
|||
swapLeft: Canvia amb la columna de l'esquerra
|
||||
renameProfile: Canvia el nom de l'espai de treball
|
||||
nameAlreadyExists: Aquest nom d'espai de treball ja existeix.
|
||||
blockConfirm: Estás segur que vols bloquejar aquest compte?
|
||||
unsuspendConfirm: Estás segur que vols treure la suspensió d'aquest compte?
|
||||
unblockConfirm: Estás segur que vols treure el bloqueig d'aquest compte?
|
||||
suspendConfirm: Estás segur que vols suspendre aquest compte?
|
||||
blockConfirm: Segur que vols bloquejar aquest compte?
|
||||
unsuspendConfirm: Segur que vols treure la suspensió d'aquest compte?
|
||||
unblockConfirm: Segur que vols treure el bloqueig d'aquest compte?
|
||||
suspendConfirm: Segur que vols suspendre aquest compte?
|
||||
selectList: Selecciona una llista
|
||||
selectAntenna: Selecciona una antena
|
||||
selectWidget: Selecciona un giny
|
||||
editWidgets: Edita ginys
|
||||
editWidgets: Edita els ginys
|
||||
editWidgetsExit: Fet
|
||||
customEmojis: Emoji personalitzat
|
||||
cacheRemoteFilesDescription: Quant aquesta opció es deshabilitada, els fitxers remots
|
||||
es carregant directament de l'instància remota. Deshabilitar això farà que baixi
|
||||
l'ús d'emmagatzematge, però incrementa el tràfic, perquè les miniatures no es generarán.
|
||||
flagAsBot: Marca aquest compte com un bot
|
||||
customEmojis: Emojis personalitzats
|
||||
cacheRemoteFilesDescription: Quan aquesta opció està desactivada, els fitxers remots
|
||||
es carreguin directament de la instància remota. Desactivar-la farà que baixi l'ús
|
||||
d'emmagatzematge, però incrementa el tràfic, perquè les miniatures no es generaran.
|
||||
flagAsBot: Marca aquest compte com a bot
|
||||
flagAsBotDescription: Activa aquesta opció si aquest compte és controlat per un programa.
|
||||
Si s'activa, això actuarà com una bandera per a altres desenvolupadors i ajuda a
|
||||
prevenir cadenes de interaccions infinites amb altres bots a més d'ajustar els sistemes
|
||||
interns de Calckey per tractar aquest compte com un bot.
|
||||
flagAsCat: Ets un gat? 🐱
|
||||
flagShowTimelineReplies: Mostrar respostes a la línea de temps
|
||||
flagShowTimelineReplies: Mostra respostes a la línia de temps
|
||||
flagAsCatDescription: Guanyaràs unes orelles de gat i parlares com un gat!
|
||||
flagShowTimelineRepliesDescription: Mostrará respostes d'usuaris a notes d'altres
|
||||
usuaris si s'activa.
|
||||
flagShowTimelineRepliesDescription: Si s'activa, es mostraran les respostes d'usuaris
|
||||
a publicacions d'altres usuaris.
|
||||
general: General
|
||||
autoAcceptFollowed: Aprova automàticament les peticions de seguiment d'usuaris que
|
||||
segueixes
|
||||
accountMoved: "L'usuari s'ha mogut a un compte nou:"
|
||||
addAccount: Afegir un compte
|
||||
addAccount: Afegeix un compte
|
||||
loginFailed: No s'ha pogut iniciar sessió
|
||||
showOnRemote: Veure a l'instància remota
|
||||
showOnRemote: Mostra a la instància remota
|
||||
wallpaper: Fons de pantalla
|
||||
setWallpaper: Estableix fons de pantalla
|
||||
removeWallpaper: Esborra fons de pantalla
|
||||
removeWallpaper: Elimina el fons de pantalla
|
||||
followConfirm: Segur que vols seguir a l'usuari {name}?
|
||||
proxyAccount: Compte proxy
|
||||
proxyAccountDescription: Un compte proxy es un compte que actua com un seguidor remot
|
||||
|
@ -781,127 +781,127 @@ host: Amfitrió
|
|||
selectUser: Selecciona un usuari
|
||||
latestStatus: Últim estat
|
||||
storageUsage: Ús del emmagatzematge
|
||||
metadata: Metadata
|
||||
metadata: Metadades
|
||||
withNFiles: '{n} fitxer(s)'
|
||||
monitor: Seguiment
|
||||
software: Programari
|
||||
version: Versió
|
||||
jobQueue: Cua de Feina
|
||||
cpuAndMemory: CPU i Memòria
|
||||
jobQueue: Cua de feina
|
||||
cpuAndMemory: CPU i memòria
|
||||
network: Xarxa
|
||||
disk: Disc
|
||||
instanceInfo: Informació de l'instància
|
||||
instanceInfo: Informació de la instància
|
||||
statistics: Estadístiques
|
||||
clearCachedFiles: Neteja la memòria cau
|
||||
clearCachedFiles: Esborra la memòria cau
|
||||
clearQueueConfirmText: Qualsevol publicació que continuï a la cua sense entregar no
|
||||
será federada. Normalment aquesta operació no es necessària.
|
||||
clearCachedFilesConfirm: Segur que vols esborrar els fitxers remots de la memòria
|
||||
cau?
|
||||
blockedUsers: Usuaris blocats
|
||||
noUsers: No hi han usuaris
|
||||
editProfile: Editar perfil
|
||||
noteDeleteConfirm: Segur que vols esborrar aquesta publicació?
|
||||
noUsers: No hi ha cap usuari
|
||||
editProfile: Edita el perfil
|
||||
noteDeleteConfirm: Segur que vols eliminar la publicació?
|
||||
pinLimitExceeded: No pots fixar més notes
|
||||
muteAndBlock: Silenciats i Bloquejats
|
||||
muteAndBlock: Silenciats i blocats
|
||||
mutedUsers: Usuaris silenciats
|
||||
done: Fet
|
||||
preview: Vista prèvia
|
||||
default: Per defecte
|
||||
intro: La instalació de Calckey a acabat! Si us plau crea un compte d'usuari.
|
||||
processing: Processant...
|
||||
noCustomEmojis: No hi ha emoji
|
||||
noJobs: No hi han feines
|
||||
intro: La instal·lació de Calckey ha acabat! Crea un compte d'usuari d'administració.
|
||||
processing: S'està processant…
|
||||
noCustomEmojis: No hi ha cap emoji
|
||||
noJobs: No hi ha cap feina
|
||||
federating: Federant
|
||||
blocked: Bloquejat
|
||||
subscribing: Subscrivint
|
||||
publishing: Publicant
|
||||
notResponding: Sense resposta
|
||||
instanceUsers: Usuaris d'aquesta instància
|
||||
instanceFollowing: Seguint a l'instància
|
||||
instanceFollowing: Seguint a la instància
|
||||
instanceFollowers: Seguidors de l'instància
|
||||
security: Seguretat
|
||||
newPasswordRetype: Torna a entrar la nova contrasenya
|
||||
more: Més!
|
||||
featured: Destacat
|
||||
usernameOrUserId: Nom d'usuari o id d'usuari
|
||||
usernameOrUserId: Nom o ID d'usuari
|
||||
noSuchUser: No s'ha trobat l'usuari
|
||||
lookup: Cercar
|
||||
attachFile: Afegeix un arxiu
|
||||
lookup: Cerca
|
||||
attachFile: Afegeix un fitxer
|
||||
currentPassword: Contrasenya actual
|
||||
newPassword: Nova contrasenya
|
||||
announcements: Anuncis
|
||||
imageUrl: URL de la imatge
|
||||
removed: S'ha esborrat correctament
|
||||
removeAreYouSure: Segur que vols esborrar "{x}"?
|
||||
deleteAreYouSure: Segur que vols esborrar "{x}"?
|
||||
resetAreYouSure: Restablir? Segur?
|
||||
fromUrl: Des de URL
|
||||
saved: Desat
|
||||
removed: S'ha eliminat correctament
|
||||
removeAreYouSure: Segur que vols eliminar «{x}»?
|
||||
deleteAreYouSure: Segur que vols eliminar «{x}»?
|
||||
resetAreYouSure: Segur que vols restablir?
|
||||
fromUrl: Des d'una URL
|
||||
saved: S'ha desat
|
||||
messaging: Xat
|
||||
upload: Pujar
|
||||
keepOriginalUploading: Desa imatge original
|
||||
upload: Puja
|
||||
keepOriginalUploading: Desa la imatge original
|
||||
keepOriginalUploadingDescription: Desa la imatge original pujada tal com es. Si es
|
||||
desactiva, es generarà una versió per mostrar en la web al pujar.
|
||||
fromDrive: Des de Drive
|
||||
uploadFromUrl: Puja des de una adreça URL
|
||||
fromDrive: Des del Disc
|
||||
uploadFromUrl: Puja des d'una adreça URL
|
||||
uploadFromUrlDescription: Adreça URL del fitxer que vols pujar
|
||||
uploadFromUrlRequested: Pujada demanada
|
||||
noMoreHistory: S'ha acabat la historia
|
||||
tos: Termes d'us
|
||||
start: Començar
|
||||
startMessaging: Comença un nou xat
|
||||
noMoreHistory: No hi ha més historial
|
||||
tos: Condicions d'ús
|
||||
start: Comença
|
||||
startMessaging: Comença una conversa
|
||||
manageGroups: Gestiona els grups
|
||||
nUsersRead: llegit per {n}
|
||||
agreeTo: Estic d'acord amb {0}
|
||||
activity: Activitat
|
||||
home: Inici
|
||||
remoteUserCaution: L'informació d'usuaris remots pot estar incompleta.
|
||||
remoteUserCaution: La informació dels usuaris remots pot estar incompleta.
|
||||
themeForDarkMode: Tema a fer servir en mode fosc
|
||||
light: Clar
|
||||
registeredDate: Data de registre
|
||||
dark: Fosc
|
||||
lightThemes: Temes clars
|
||||
location: Lloc
|
||||
location: Ubicació
|
||||
theme: Temes
|
||||
themeForLightMode: Tema a fer servir en mode clar
|
||||
drive: Disc
|
||||
selectFile: Tria un fitxer
|
||||
selectFiles: Tria fitxers
|
||||
darkThemes: Temes foscos
|
||||
syncDeviceDarkMode: Sincronitza el Mode Fosc amb la configuració del teu dispositiu
|
||||
syncDeviceDarkMode: Sincronitza el mode fosc amb la configuració del teu dispositiu
|
||||
fileName: Nom del fitxer
|
||||
createFolder: Crea una carpeta
|
||||
renameFolder: Posa un nom nou a aquesta carpeta
|
||||
deleteFolder: Esborra aquesta carpeta
|
||||
renameFolder: Canvia-li el nom a la carpeta
|
||||
deleteFolder: Elimina la carpeta
|
||||
selectFolder: Tria una carpeta
|
||||
selectFolders: Tria carpetes
|
||||
renameFile: Canvia el nom del fitxer
|
||||
folderName: Nom de la carpeta
|
||||
inputNewFolderName: Escriu un nou nom per la carpeta
|
||||
inputNewFolderName: Escriu un nom de carpeta nou
|
||||
addFile: Afegeix un fitxer
|
||||
emptyDrive: El teu Disc és buit
|
||||
emptyFolder: Aquesta carpeta és buida
|
||||
unableToDelete: No es pot esborrar
|
||||
unableToDelete: No es pot eliminar
|
||||
inputNewFileName: Escriu un nou nom per al fitxer
|
||||
inputNewDescription: Escriu una nova descripció
|
||||
circularReferenceFolder: La carpeta de destí es una subcarpeta de la carpeta que vols
|
||||
inputNewDescription: Escriu una descripció nova
|
||||
circularReferenceFolder: La carpeta de destí és una subcarpeta de la carpeta que vols
|
||||
moure.
|
||||
hasChildFilesOrFolders: Degut a que aquesta carpeta no es buida, no es pot esborrar.
|
||||
hasChildFilesOrFolders: Aquesta carpeta no es pot eliminar perquè no és buida.
|
||||
whenServerDisconnected: Quant es perd la conexió amb el servidor
|
||||
disconnectedFromServer: S'ha perdut la conexió al servidor
|
||||
reload: Torna a carregar
|
||||
avatar: Avatar
|
||||
banner: Banner
|
||||
banner: Bàner
|
||||
doNothing: Ignora
|
||||
reloadConfirm: Vols tornar a carregar la línea temporal?
|
||||
watch: Veure
|
||||
maintainerName: Administrador
|
||||
maintainerEmail: Correu electrònic de l'administrador
|
||||
instanceName: Nom de l'instància
|
||||
instanceDescription: Descripció de l'instància
|
||||
instanceName: Nom de la instància
|
||||
instanceDescription: Descripció de la instància
|
||||
today: Avui
|
||||
dayX: '{day}'
|
||||
tosUrl: Adreça URL dels terminis d'ús
|
||||
tosUrl: URL de les Condicions d'ús
|
||||
thisYear: Any
|
||||
thisMonth: Mes
|
||||
integration: Integracions
|
||||
|
@ -928,37 +928,37 @@ enableGlobalTimeline: Activa la línia de temps global
|
|||
disablingTimelinesInfo: Els Administradors i Moderadors sempre tenen accés a totes
|
||||
les líneas temporals, inclòs si hi són desactivades.
|
||||
showLess: Tanca
|
||||
clearQueue: Neteja la cua
|
||||
clearQueue: Esborra la cua
|
||||
uploadFromUrlMayTakeTime: Pot trigar un temps fins que la pujada es completi.
|
||||
noThankYou: No, gràcies
|
||||
addInstance: Afegir una instància
|
||||
emoji: Emoji
|
||||
emojis: Emoji
|
||||
addInstance: Afegeix una instància
|
||||
emoji: Emojis
|
||||
emojis: Emojis
|
||||
emojiName: Nom del emoji
|
||||
emojiUrl: URL del emoji
|
||||
addEmoji: Afegir
|
||||
emojiUrl: URL de l'emoji
|
||||
addEmoji: Afegeix
|
||||
settingGuide: Configuració recomenada
|
||||
searchWith: 'Cercar: {q}'
|
||||
searchWith: 'Cerca: {q}'
|
||||
youHaveNoLists: No tens cap llista
|
||||
flagSpeakAsCat: Parla com un gat
|
||||
selectInstance: Selecciona una instància
|
||||
flagSpeakAsCatDescription: Les teves notes es transformaran en miols quant estiguis
|
||||
flagSpeakAsCatDescription: Les teves publicacions es transformaran en miols quan estiguis
|
||||
en mode gat
|
||||
recipient: Destinatari(s)
|
||||
annotation: Comentaris
|
||||
blockedInstances: Instàncies Bloquejades
|
||||
blockedInstances: Instàncies bloquejades
|
||||
blockedInstancesDescription: Llista les adreces de les instàncies que vols bloquejar.
|
||||
Les instàncies de la llista no podrán comunicarse amb aquesta instància.
|
||||
hiddenTags: Etiquetes Ocultes
|
||||
hiddenTags: Etiquetes amagades
|
||||
hiddenTagsDescription: 'Enumereu les etiquetes (sense el #) que voleu ocultar de tendències
|
||||
i explorar. Les etiquetes ocultes encara es poden descobrir per altres mitjans.
|
||||
Les instàncies bloquejades no es veuen afectades encara que s''enumerin aquí.'
|
||||
noInstances: No hi han instàncies
|
||||
noInstances: No hi ha cap instància
|
||||
defaultValueIs: 'Per defecte: {value}'
|
||||
suspended: Suspès
|
||||
all: Tot
|
||||
changePassword: Canvia la contrasenya
|
||||
clearQueueConfirmTitle: Segur que vols netejar la cua?
|
||||
clearQueueConfirmTitle: Segur que vols esborrar la cua?
|
||||
retypedNotMatch: Els camps no coincideixen.
|
||||
normal: Normal
|
||||
monthX: '{month}'
|
||||
|
@ -975,25 +975,25 @@ registration: Registre
|
|||
showEmojisInReactionNotifications: Mostra els emojis a les notificacions de les reaccions
|
||||
renoteMute: Silencia els impulsos
|
||||
renoteUnmute: Treu el silenci als impulsos
|
||||
cacheRemoteFiles: Fitxers remots a la memoria cau
|
||||
cacheRemoteFiles: Fitxers remots a la memòria cau
|
||||
federation: Federació
|
||||
registeredAt: Registrat a
|
||||
latestRequestSentAt: Última petició enviada
|
||||
latestRequestReceivedAt: Última petició rebuda
|
||||
charts: Gràfics
|
||||
perHour: Per Hora
|
||||
perDay: Per Dia
|
||||
perHour: Per hora
|
||||
perDay: Per dia
|
||||
stopActivityDelivery: Para d'enviar activitats
|
||||
operations: Operacions
|
||||
explore: Explorar
|
||||
messageRead: Llegir
|
||||
explore: Explora
|
||||
messageRead: Llegit
|
||||
images: Imatges
|
||||
birthday: Aniversari
|
||||
yearsOld: '{age} anys'
|
||||
copyUrl: Copiar l'adreça URL
|
||||
copyUrl: Copia l'adreça URL
|
||||
rename: Renombrar
|
||||
unwatch: Deixa de veure
|
||||
accept: Acceptar
|
||||
accept: Accepta
|
||||
reject: Rebutja
|
||||
yearX: '{year}'
|
||||
pages: Pàgines
|
||||
|
@ -1511,7 +1511,7 @@ seperateRenoteQuote: Botons d'impuls i de citació separats
|
|||
searchResult: Resultats de la cerca
|
||||
hashtags: Etiquetes
|
||||
troubleshooting: Resolució de problemes
|
||||
learnMore: Aprèn més
|
||||
learnMore: Més informació
|
||||
misskeyUpdated: Calckey s'ha actualitzat!
|
||||
translate: Tradueix
|
||||
translatedFrom: Traduït per {x}
|
||||
|
@ -1599,7 +1599,7 @@ squareAvatars: Mostra avatars quadrats
|
|||
secureModeInfo: Quan es faci una solicitut d'altres instàncies no contestar sense
|
||||
una prova.
|
||||
privateModeInfo: Quan està activat, només les instàncies de la llista blanca es poden
|
||||
federar amb les vostres instàncies. Totes les notes s'amagaran al públic.
|
||||
federar amb la vostra instància. Totes les publicacions s'amagaran al públic.
|
||||
useBlurEffect: Utilitzeu efectes de desenfocament a la interfície d'usuari
|
||||
accountDeletionInProgress: La supressió del compte està en curs
|
||||
unmuteThread: Desfés el silenci al fil
|
||||
|
@ -1815,6 +1815,8 @@ _channel:
|
|||
usersCount: '{n} Participants'
|
||||
following: Seguit
|
||||
notesCount: '{n} Notes'
|
||||
nameAndDescription: Nom i descripció
|
||||
nameOnly: Només nom
|
||||
_instanceMute:
|
||||
instanceMuteDescription: Això silenciarà les notes o els impulsos de les instàncies
|
||||
indicades, incloses les dels usuaris que responguin a un usuari des d'una instància
|
||||
|
@ -2020,24 +2022,7 @@ _relayStatus:
|
|||
requesting: Pendent
|
||||
accepted: Acceptat
|
||||
rejected: Rebutjat
|
||||
_apps:
|
||||
crossPlatform: Multiplataforma
|
||||
mobile: Mòbil
|
||||
firstParty: Primer partit
|
||||
secondClass: Segona classe
|
||||
thirdClass: Tercera classe
|
||||
pwa: Instal·lar PWA
|
||||
kaiteki: Kaiteki
|
||||
milktea: Milktea
|
||||
missLi: MissLi
|
||||
mona: Mona
|
||||
lesskey: Lesskey
|
||||
firstClass: Primera classe
|
||||
free: Gratuït
|
||||
paid: Pagament
|
||||
theDesk: TheDesk
|
||||
apps: Aplicacions
|
||||
deleted: Esborrat
|
||||
deleted: Eliminat
|
||||
editNote: Edita la nota
|
||||
edited: Editat
|
||||
findOtherInstance: Cercar un altre servidor
|
||||
|
@ -2047,3 +2032,10 @@ signupsDisabled: Actualment, les inscripcions en aquest servidor estan desactiva
|
|||
userSaysSomethingReasonQuote: '{name} ha citat una publicació que conté {reason}'
|
||||
userSaysSomethingReasonReply: '{name} ha respost a una publicació que conté {reason}'
|
||||
userSaysSomethingReasonRenote: '{name} ha impulsat una publicació que conté {reason}'
|
||||
highlightCw: Ressalta el contingut de les publicacions advertides
|
||||
apps: Aplicacions
|
||||
sendModMail: Envia avís de moderació
|
||||
preventAiLearning: Evita l'indexació dels bots
|
||||
preventAiLearningDescription: Sol·liciteu que els models de llenguatge d'IA de tercers
|
||||
no estudiïn el contingut que pengeu, com ara publicacions i imatges.
|
||||
pwa: Instal·lar PWA
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
---
|
||||
_lang_: "Čeština"
|
||||
headlineMisskey: "Síť propojená poznámkami"
|
||||
introMisskey: "Vítejte! Misskey je otevřený a decentralizovaný microblogový servis.\n\"Poznámkami\" můžete sdílet co se zrovna děje se všemi ve Vašem okolí. 📡\nPomocí \"reakcí\" můžete sdílet své názory a pocity na ostatní poznámky. 👍\nPojďte objevovat nový svět! 🚀"
|
||||
introMisskey: "Vítejte! Misskey je otevřený a decentralizovaný microblogový servis.\n\
|
||||
\"Poznámkami\" můžete sdílet co se zrovna děje se všemi ve Vašem okolí. \U0001F4E1\
|
||||
\nPomocí \"reakcí\" můžete sdílet své názory a pocity na ostatní poznámky. \U0001F44D\
|
||||
\nPojďte objevovat nový svět! \U0001F680"
|
||||
monthAndDay: "{day}. {month}."
|
||||
search: "Vyhledávání"
|
||||
notifications: "Oznámení"
|
||||
|
@ -44,7 +46,8 @@ copyContent: "Zkopírovat obsah"
|
|||
copyLink: "Kopírovat odkaz"
|
||||
delete: "Smazat"
|
||||
deleteAndEdit: "Smazat a upravit"
|
||||
deleteAndEditConfirm: "Jste si jistí že chcete smazat tuto poznámku a editovat ji? Ztratíte tím všechny reakce, sdílení a odpovědi na ni."
|
||||
deleteAndEditConfirm: "Jste si jistí že chcete smazat tuto poznámku a editovat ji?\
|
||||
\ Ztratíte tím všechny reakce, sdílení a odpovědi na ni."
|
||||
addToList: "Přidat do seznamu"
|
||||
sendMessage: "Odeslat zprávu"
|
||||
copyUsername: "Kopírovat uživatelské jméno"
|
||||
|
@ -63,9 +66,11 @@ import: "Importovat"
|
|||
export: "Exportovat"
|
||||
files: "Soubor(ů)"
|
||||
download: "Stáhnout"
|
||||
driveFileDeleteConfirm: "Opravdu chcete smazat soubor \"{name}\"? Poznámky, ke kterým je tento soubor připojen, budou také smazány."
|
||||
driveFileDeleteConfirm: "Opravdu chcete smazat soubor \"{name}\"? Soubor bude odstraněn\
|
||||
\ ze všech příspěvků, které ji obsahují jako přílohu."
|
||||
unfollowConfirm: "Jste si jisti že už nechcete sledovat {name}?"
|
||||
exportRequested: "Požádali jste o export. To může chvíli trvat. Přidáme ho na váš Disk až bude dokončen."
|
||||
exportRequested: "Požádali jste o export. To může chvíli trvat. Přidáme ho na váš\
|
||||
\ Disk až bude dokončen."
|
||||
importRequested: "Požádali jste o export. To může chvilku trvat."
|
||||
lists: "Seznamy"
|
||||
noLists: "Nemáte žádné seznamy"
|
||||
|
@ -81,7 +86,8 @@ somethingHappened: "Jejda. Něco se nepovedlo."
|
|||
retry: "Opakovat"
|
||||
pageLoadError: "Nepodařilo se načíst stránku"
|
||||
serverIsDead: "Server neodpovídá. Počkejte chvíli a zkuste to znovu."
|
||||
youShouldUpgradeClient: "Pro zobrazení této stránky obnovte stránku pro aktualizaci klienta."
|
||||
youShouldUpgradeClient: "Pro zobrazení této stránky obnovte stránku pro aktualizaci\
|
||||
\ klienta."
|
||||
enterListName: "Jméno seznamu"
|
||||
privacy: "Soukromí"
|
||||
makeFollowManuallyApprove: "Žádosti o sledování vyžadují potvrzení"
|
||||
|
@ -105,7 +111,8 @@ clickToShow: "Klikněte pro zobrazení"
|
|||
sensitive: "NSFW"
|
||||
add: "Přidat"
|
||||
reaction: "Reakce"
|
||||
reactionSettingDescription2: "Přetažením změníte pořadí, kliknutím smažete, zmáčkněte \"+\" k přidání"
|
||||
reactionSettingDescription2: "Přetažením změníte pořadí, kliknutím smažete, zmáčkněte\
|
||||
\ \"+\" k přidání"
|
||||
rememberNoteVisibility: "Zapamatovat nastavení zobrazení poznámky"
|
||||
attachCancel: "Odstranit přílohu"
|
||||
markAsSensitive: "Označit jako NSFW"
|
||||
|
@ -134,13 +141,18 @@ emojiUrl: "URL obrázku"
|
|||
addEmoji: "Přidat emoji"
|
||||
settingGuide: "Doporučené nastavení"
|
||||
cacheRemoteFiles: "Ukládání vzdálených souborů do mezipaměti"
|
||||
cacheRemoteFilesDescription: "Zakázání tohoto nastavení způsobí, že vzdálené soubory budou odkazovány přímo, místo aby byly ukládány do mezipaměti. Tím se ušetří úložiště na serveru, ale zvýší se provoz, protože se negenerují miniatury."
|
||||
cacheRemoteFilesDescription: "Zakázání tohoto nastavení způsobí, že vzdálené soubory\
|
||||
\ budou odkazovány přímo, místo aby byly ukládány do mezipaměti. Tím se ušetří úložiště\
|
||||
\ na serveru, ale zvýší se provoz, protože se negenerují miniatury."
|
||||
flagAsBot: "Tento účet je bot"
|
||||
flagAsBotDescription: "Pokud je tento účet kontrolován programem zaškrtněte tuto možnost. To označí tento účet jako bot pro ostatní vývojáře a zabrání tak nekonečným interakcím s ostatními boty a upraví Misskey systém aby se choval k tomuhle účtu jako bot."
|
||||
flagAsBotDescription: "Pokud je tento účet kontrolován programem zaškrtněte tuto možnost.\
|
||||
\ To označí tento účet jako bot pro ostatní vývojáře a zabrání tak nekonečným interakcím\
|
||||
\ s ostatními boty a upraví Misskey systém aby se choval k tomuhle účtu jako bot."
|
||||
flagAsCat: "Tenhle účet je kočka"
|
||||
flagAsCatDescription: "Vyberte tuto možnost aby tento účet byl označen jako kočka."
|
||||
flagShowTimelineReplies: "Zobrazovat odpovědi na časové ose"
|
||||
flagShowTimelineRepliesDescription: "Je-li zapnuto, zobrazí odpovědi uživatelů na poznámky jiných uživatelů na vaší časové ose."
|
||||
flagShowTimelineRepliesDescription: "Je-li zapnuto, zobrazí odpovědi uživatelů na\
|
||||
\ poznámky jiných uživatelů na vaší časové ose."
|
||||
autoAcceptFollowed: "Automaticky akceptovat následování od účtů které sledujete"
|
||||
addAccount: "Přidat účet"
|
||||
loginFailed: "Přihlášení se nezdařilo."
|
||||
|
@ -153,7 +165,10 @@ searchWith: "Hledat: {q}"
|
|||
youHaveNoLists: "Nemáte žádné seznamy"
|
||||
followConfirm: "Jste si jisti, že chcete sledovat {name}?"
|
||||
proxyAccount: "Proxy účet"
|
||||
proxyAccountDescription: "Proxy účet je účet, který za určitých podmínek sleduje uživatele na dálku vaším jménem. Například když uživatel zařadí vzdáleného uživatele do seznamu, pokud nikdo nesleduje uživatele na seznamu, aktivita nebude doručena instanci, takže místo toho bude uživatele sledovat účet proxy."
|
||||
proxyAccountDescription: "Proxy účet je účet, který za určitých podmínek sleduje uživatele\
|
||||
\ na dálku vaším jménem. Například když uživatel zařadí vzdáleného uživatele do\
|
||||
\ seznamu, pokud nikdo nesleduje uživatele na seznamu, aktivita nebude doručena\
|
||||
\ instanci, takže místo toho bude uživatele sledovat účet proxy."
|
||||
host: "Hostitel"
|
||||
selectUser: "Vyberte uživatele"
|
||||
recipient: "Pro"
|
||||
|
@ -239,7 +254,8 @@ agreeTo: "Souhlasím s {0}"
|
|||
tos: "Podmínky užívání"
|
||||
start: "Začít"
|
||||
home: "Domů"
|
||||
remoteUserCaution: "Tyto informace nemusí být aktuální jelikož uživatel je ze vzdálené instance."
|
||||
remoteUserCaution: "Tyto informace nemusí být aktuální jelikož uživatel je ze vzdálené\
|
||||
\ instance."
|
||||
activity: "Aktivita"
|
||||
images: "Obrázky"
|
||||
birthday: "Datum narození"
|
||||
|
@ -548,7 +564,8 @@ info: "Informace"
|
|||
unknown: "Neznámý"
|
||||
onlineStatus: "Online status"
|
||||
hideOnlineStatus: "Skrýt Váš online status"
|
||||
hideOnlineStatusDescription: "Skrytí vašeho online stavu může snížit funkcionalitu některých funkcí, například vyhledávání."
|
||||
hideOnlineStatusDescription: "Skrytí vašeho online stavu může snížit funkcionalitu\
|
||||
\ některých funkcí, například vyhledávání."
|
||||
online: "Online"
|
||||
active: "Aktivní"
|
||||
offline: "Offline"
|
||||
|
@ -928,3 +945,66 @@ _deck:
|
|||
antenna: "Antény"
|
||||
list: "Seznamy"
|
||||
mentions: "Zmínění"
|
||||
noteDeleteConfirm: Chcete opravdu smazat tento příspěvek?
|
||||
defaultValueIs: 'Výchozí: {value}'
|
||||
lookup: Hledat
|
||||
keepOriginalUploading: Ponechat originální obrázek
|
||||
uploadFromUrlRequested: Vyžádáno nahrání souboru
|
||||
manageGroups: Spravovat skupiny
|
||||
reloadConfirm: Znovu načíst časovou osu?
|
||||
driveCapacityPerRemoteAccount: Místo na disku pro vzdálené uživatele
|
||||
silenceThisInstance: Ztlumit tuto instance
|
||||
silencedInstances: Ztlumené instance
|
||||
blockedInstancesDescription: Zadejte seznam domén instancí, jež chcete blokovat. Uvedené
|
||||
instance nebudou moci s touto instancí komunikovat.
|
||||
hiddenTags: Skryté hashtagy
|
||||
noInstances: Nejsou zde žádné instance
|
||||
silenced: Ztlumené
|
||||
disablingTimelinesInfo: Administrátoři a moderátoři budou vždy mít přístup ke všem
|
||||
časovým osám, i pokud jsou vypnuté.
|
||||
deleted: Vymazáno
|
||||
editNote: Upravit poznámku
|
||||
edited: Upraveno
|
||||
silencedInstancesDescription: Vypište hostnames instancí, které chcete ztlumit. Účty
|
||||
v uvedených instancích jsou považovány za "ztlumené", mohou pouze zadávat požadavky
|
||||
na sledování a nemohou zmiňovat místní účty, pokud nejsou sledovány. Na blokované
|
||||
instance toto nebude mít vliv.
|
||||
hiddenTagsDescription: 'Vypište hashtagy (bez #), které chcete skrýt před trendy a
|
||||
prozkoumat. Skryté hashtagy jsou stále zjistitelné jinými způsoby. Blokované případy
|
||||
nejsou ovlivněny, i když jsou zde uvedeny.'
|
||||
circularReferenceFolder: Cílová složka je podsložka přesouvané složky.
|
||||
whenServerDisconnected: Při ztrátě spojení se serverem
|
||||
pinnedUsersDescription: Uveďte uživatelská jména uživatelů připnutých na stránce "Procházet",
|
||||
jedno na řádek.
|
||||
pinnedPagesDescription: Zadejte cesty ke stránkám, které chcete připnout na horní
|
||||
stránku této instance, oddělené zlomy řádků.
|
||||
pageLoadErrorDescription: Toto je obvykle způsobeno chybami sítě nebo mezipaměti prohlížeče.
|
||||
Zkuste vymazat mezipaměť a po chvíli čekání to zkuste znovu.
|
||||
emptyDrive: Váš disk je prázdný
|
||||
inputNewDescription: Zadejte nový popisek
|
||||
hasChildFilesOrFolders: Složka nemůže být smazána, protože není prázdná.
|
||||
noThankYou: Ne, děkuji
|
||||
addInstance: Přidat instance
|
||||
selectInstance: Vybrat si instance
|
||||
blockedUsers: Zablokovaní uživatelé
|
||||
muteAndBlock: Ztlumení a blokace
|
||||
noJobs: Žádné úlohy
|
||||
federating: Federace
|
||||
clearQueueConfirmText: Nedoručené příspěvky, které zůstanou ve frontě, nebudou federovány.
|
||||
Obvykle tato operace není potřeba.
|
||||
clearCachedFilesConfirm: Chcete opravdu vymazat mezipaměť všech vzdálených souborů?
|
||||
accountMoved: 'Uživatel/ka se přesunul/a na nový účet:'
|
||||
keepOriginalUploadingDescription: Ponechá originálně nahraný obrázek tak, jak je.
|
||||
Pokud vypnuto, verze pro zobrazení na webu bude vygenerována při nahrání.
|
||||
mutedUsers: Ztlumení uživatelé
|
||||
enableRecommendedTimeline: Povolit doporučenou časovou osu
|
||||
driveCapacityPerLocalAccount: Místo na disku pro místní uživatele
|
||||
pinnedPages: Připnuté Stránky
|
||||
directNotes: Přímé zprávy
|
||||
enableEmojiReactions: Povolit reakce pomocí emoji
|
||||
showEmojisInReactionNotifications: Zobrazit emotikony v oznámeních o reakcích
|
||||
reactionSetting: Reakce, které se mají zobrazit v seznamu reakcí
|
||||
renoteMute: Ztlumit přeposílání
|
||||
renoteUnmute: Zrušit ztlumení přeposílání
|
||||
flagSpeakAsCat: Mluvit jako kočka
|
||||
flagSpeakAsCatDescription: Vaše příspěvky budou v kočičím režimu nyanifikovány.
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -874,7 +874,7 @@ instanceSecurity: "Instance Security"
|
|||
secureModeInfo: "When requesting from other instances, do not send back without proof."
|
||||
privateMode: "Private Mode"
|
||||
privateModeInfo: "When enabled, only whitelisted instances can federate with your\
|
||||
\ instances. All posts will be hidden from the public."
|
||||
\ instance. All posts will be hidden from the public."
|
||||
allowedInstances: "Whitelisted Instances"
|
||||
allowedInstancesDescription: "Hosts of instances to be whitelisted for federation,\
|
||||
\ each separated by a new line (only applies in private mode)."
|
||||
|
@ -886,7 +886,6 @@ global: "Global"
|
|||
recommended: "Recommended"
|
||||
squareAvatars: "Display squared avatars"
|
||||
seperateRenoteQuote: "Separate boost and quote buttons"
|
||||
highlightCw: "Highlight content warned posts"
|
||||
sent: "Sent"
|
||||
received: "Received"
|
||||
searchResult: "Search results"
|
||||
|
@ -1078,8 +1077,15 @@ customKaTeXMacroDescription: "Set up macros to write mathematical expressions ea
|
|||
\ supported; advanced syntax, such as conditional branching, cannot be used here."
|
||||
enableCustomKaTeXMacro: "Enable custom KaTeX macros"
|
||||
noteId: "Post ID"
|
||||
signupsDisabled: "Signups on this server are currently disabled, but you can always sign up at another server! If you have an invitation code for this server, please enter it below."
|
||||
signupsDisabled: "Signups on this server are currently disabled, but you can always\
|
||||
\ sign up at another server! If you have an invitation code for this server, please\
|
||||
\ enter it below."
|
||||
findOtherInstance: "Find another server"
|
||||
apps: "Apps"
|
||||
sendModMail: "Send Moderation Notice"
|
||||
preventAiLearning: "Prevent AI bot scraping"
|
||||
preventAiLearningDescription: "Request third-party AI language models not to study content you upload, such as posts and images."
|
||||
|
||||
|
||||
_sensitiveMediaDetection:
|
||||
description: "Reduces the effort of server moderation through automatically recognizing\
|
||||
|
@ -1187,6 +1193,10 @@ _nsfw:
|
|||
ignore: "Don't hide NSFW media"
|
||||
force: "Hide all media"
|
||||
_mfm:
|
||||
play: "Play MFM"
|
||||
stop: "Stop MFM"
|
||||
warn: "MFM may contain rapidly moving or flashy animations"
|
||||
alwaysPlay: "Always autoplay all animated MFM"
|
||||
cheatSheet: "MFM Cheatsheet"
|
||||
intro: "MFM is a markup language used on Misskey, Calckey, Akkoma, and more that\
|
||||
\ can be used in many places. Here you can view a list of all available MFM syntax."
|
||||
|
@ -1998,20 +2008,3 @@ _deck:
|
|||
list: "List"
|
||||
mentions: "Mentions"
|
||||
direct: "Direct messages"
|
||||
_apps:
|
||||
apps: "Apps"
|
||||
crossPlatform: "Cross platform"
|
||||
mobile: "Mobile"
|
||||
firstParty: "First party"
|
||||
firstClass: "First class"
|
||||
secondClass: "Second class"
|
||||
thirdClass: "Third class"
|
||||
free: "Free"
|
||||
paid: "Paid"
|
||||
pwa: "Install PWA"
|
||||
kaiteki: "Kaiteki"
|
||||
milktea: "Milktea"
|
||||
missLi: "MissLi"
|
||||
mona: "Mona"
|
||||
theDesk: "TheDesk"
|
||||
lesskey: "Lesskey"
|
||||
|
|
|
@ -14,7 +14,7 @@ ok: "OK"
|
|||
gotIt: "¡Lo tengo!"
|
||||
cancel: "Cancelar"
|
||||
enterUsername: "Introduce el nombre de usuario"
|
||||
renotedBy: "Reposteado por {user}"
|
||||
renotedBy: "Impulsado por {user}"
|
||||
noNotes: "No hay publicaciones"
|
||||
noNotifications: "No hay notificaciones"
|
||||
instance: "Instancia"
|
||||
|
@ -46,7 +46,7 @@ copyLink: "Copiar enlace"
|
|||
delete: "Borrar"
|
||||
deleteAndEdit: "Borrar y editar"
|
||||
deleteAndEditConfirm: "¿Estás seguro de que quieres borrar esta publicación y editarla?\
|
||||
\ Perderás todas las reacciones, impulsados y respuestas."
|
||||
\ Perderás todas las reacciones, impulsos y respuestas."
|
||||
addToList: "Agregar a lista"
|
||||
sendMessage: "Enviar un mensaje"
|
||||
copyUsername: "Copiar nombre de usuario"
|
||||
|
@ -342,7 +342,7 @@ dayX: "Día {day}"
|
|||
monthX: "Mes {month}"
|
||||
yearX: "Año {year}"
|
||||
pages: "Páginas"
|
||||
integration: "Integración"
|
||||
integration: "Integraciones"
|
||||
connectService: "Conectar"
|
||||
disconnectService: "Desconectar"
|
||||
enableLocalTimeline: "Habilitar linea de tiempo local"
|
||||
|
@ -366,7 +366,7 @@ pinnedPages: "Páginas fijadas"
|
|||
pinnedPagesDescription: "Describa las rutas de las páginas que desea fijar a la página\
|
||||
\ principal de la instancia, separadas por lineas nuevas"
|
||||
pinnedClipId: "Id del clip fijado"
|
||||
pinnedNotes: "Nota fijada"
|
||||
pinnedNotes: "Publicación fijada"
|
||||
hcaptcha: "hCaptcha"
|
||||
enableHcaptcha: "Habilitar hCaptcha"
|
||||
hcaptchaSiteKey: "Clave del sitio"
|
||||
|
@ -386,14 +386,14 @@ antennaKeywords: "Palabras clave para recibir"
|
|||
antennaExcludeKeywords: "Palabras clave para excluir"
|
||||
antennaKeywordsDescription: "Separar con espacios es una declaración AND, separar\
|
||||
\ con una linea nueva es una declaración OR"
|
||||
notifyAntenna: "Notificar nueva nota"
|
||||
withFileAntenna: "Sólo notas con archivos adjuntados"
|
||||
notifyAntenna: "Notificar nueva publicación"
|
||||
withFileAntenna: "Sólo publicaciones con archivos adjuntados"
|
||||
enableServiceworker: "Activar ServiceWorker"
|
||||
antennaUsersDescription: "Elegir nombres de usuarios separados por una linea nueva"
|
||||
caseSensitive: "Distinguir mayúsculas de minúsculas"
|
||||
withReplies: "Incluir respuestas"
|
||||
connectedTo: "Estas cuentas están conectadas"
|
||||
notesAndReplies: "Notas y respuestas"
|
||||
notesAndReplies: "Publicaciones y respuestas"
|
||||
withFiles: "Adjuntos"
|
||||
silence: "Silenciar"
|
||||
silenceConfirm: "¿Desea silenciar al usuario?"
|
||||
|
@ -430,7 +430,7 @@ notFoundDescription: "No se encontró la página correspondiente a la URL elegid
|
|||
uploadFolder: "Carpeta de subidas por defecto"
|
||||
cacheClear: "Borrar caché"
|
||||
markAsReadAllNotifications: "Marcar todas las notificaciones como leídas"
|
||||
markAsReadAllUnreadNotes: "Marcar todas las notas como leídas"
|
||||
markAsReadAllUnreadNotes: "Marcar todas las publicaciones como leídas"
|
||||
markAsReadAllTalkMessages: "Marcar todos los chats como leídos"
|
||||
help: "Ayuda"
|
||||
inputMessageHere: "Escribe el mensaje aquí"
|
||||
|
@ -451,7 +451,7 @@ text: "Texto"
|
|||
enable: "Activar"
|
||||
next: "Siguiente"
|
||||
retype: "Intentar de nuevo"
|
||||
noteOf: "Notas de {user}"
|
||||
noteOf: "Publicaciones de {user}"
|
||||
inviteToGroup: "Invitar al grupo"
|
||||
quoteAttached: "Cita añadida"
|
||||
quoteQuestion: "¿Quiere añadir una cita?"
|
||||
|
@ -511,8 +511,8 @@ accountSettings: "Ajustes de cuenta"
|
|||
promotion: "Promovido"
|
||||
promote: "Promover"
|
||||
numberOfDays: "Cantidad de dias"
|
||||
hideThisNote: "Ocultar esta nota"
|
||||
showFeaturedNotesInTimeline: "Mostrar notas destacadas en la línea de tiempo"
|
||||
hideThisNote: "Ocultar esta publicación"
|
||||
showFeaturedNotesInTimeline: "Mostrar publicaciones destacadas en la línea de tiempo"
|
||||
objectStorage: "Almacenamiento de objetos"
|
||||
useObjectStorage: "Usar almacenamiento de objetos"
|
||||
objectStorageBaseUrl: "Base URL"
|
||||
|
@ -542,7 +542,7 @@ objectStorageSetPublicRead: "Seleccionar \"public-read\" al subir "
|
|||
serverLogs: "Registros del servidor"
|
||||
deleteAll: "Eliminar todos"
|
||||
showFixedPostForm: "Mostrar el formulario de las entradas encima de la línea de tiempo"
|
||||
newNoteRecived: "Tienes una nota nuevo"
|
||||
newNoteRecived: "Tienes unas publicaciones nuevas"
|
||||
sounds: "Sonidos"
|
||||
listen: "Escuchar"
|
||||
none: "Ninguna"
|
||||
|
@ -575,7 +575,7 @@ deleteAllFiles: "Borrar todos los archivos"
|
|||
deleteAllFilesConfirm: "¿Desea borrar todos los archivos?"
|
||||
removeAllFollowing: "Retener todos los siguientes"
|
||||
removeAllFollowingDescription: "Cancelar todos los siguientes del servidor {host}.\
|
||||
\ Ejecutar en caso de que esta instancia haya dejado de existir"
|
||||
\ Ejecutar en caso de que esta instancia haya dejado de existir."
|
||||
userSuspended: "Este usuario ha sido suspendido."
|
||||
userSilenced: "Este usuario ha sido silenciado."
|
||||
yourAccountSuspendedTitle: "Esta cuenta ha sido suspendida"
|
||||
|
@ -590,8 +590,8 @@ addRelay: "Agregar relé"
|
|||
inboxUrl: "Inbox URL"
|
||||
addedRelays: "Relés añadidos"
|
||||
serviceworkerInfo: "Se necesita activar para usar las notificaciones push"
|
||||
deletedNote: "Nota eliminada"
|
||||
invisibleNote: "Nota oculta"
|
||||
deletedNote: "Publicación eliminada"
|
||||
invisibleNote: "Publicación oculta"
|
||||
enableInfiniteScroll: "Activar scroll infinito"
|
||||
visibility: "Visibilidad"
|
||||
poll: "Encuesta"
|
||||
|
@ -1154,6 +1154,7 @@ _mfm:
|
|||
plain: "Plano"
|
||||
plainDescription: "Desactiva los efectos de todo el contenido MFM con este efecto\
|
||||
\ MFM."
|
||||
position: Posición
|
||||
_instanceTicker:
|
||||
none: "No mostrar"
|
||||
remote: "Mostrar a usuarios remotos"
|
||||
|
@ -1173,6 +1174,8 @@ _channel:
|
|||
following: "Siguiendo"
|
||||
usersCount: "{n} participantes"
|
||||
notesCount: "{n} notas"
|
||||
nameOnly: Nombre solamente
|
||||
nameAndDescription: Nombre y descripción
|
||||
_menuDisplay:
|
||||
sideFull: "Horizontal"
|
||||
sideIcon: "Horizontal (ícono)"
|
||||
|
@ -1900,18 +1903,6 @@ moveFrom: Mueve a esta cuenta de una cuenta antigua
|
|||
moveFromLabel: 'La cuenta que estás moviendo de:'
|
||||
moveAccountDescription: ''
|
||||
license: Licencia
|
||||
_apps:
|
||||
apps: Aplicaciones
|
||||
crossPlatform: Plataforma Cruzada
|
||||
mobile: Teléfono móvil
|
||||
secondClass: Segunda clase
|
||||
lesskey: ''
|
||||
firstClass: Primera clase
|
||||
thirdClass: Tercera clase
|
||||
theDesk: ''
|
||||
pwa: Instalar PWA
|
||||
free: Gratis
|
||||
paid: Pagado
|
||||
noThankYou: No gracias
|
||||
userSaysSomethingReason: '{name} dijo {reason}'
|
||||
hiddenTags: Etiquetas Ocultas
|
||||
|
@ -1928,3 +1919,12 @@ _messaging:
|
|||
groups: Grupos
|
||||
dms: Privado
|
||||
pushNotification: Notificaciones
|
||||
apps: Aplicaciones
|
||||
migration: Migración
|
||||
silenced: Silenciado
|
||||
deleted: Eliminado
|
||||
edited: Editado
|
||||
editNote: Editar nota
|
||||
silenceThisInstance: Silenciar esta instancia
|
||||
findOtherInstance: Buscar otro servidor
|
||||
userSaysSomethingReasonRenote: '{name} impulsó una publicación que contiene {reason]'
|
||||
|
|
|
@ -70,7 +70,7 @@ export: "Exporter"
|
|||
files: "Fichiers"
|
||||
download: "Télécharger"
|
||||
driveFileDeleteConfirm: "Êtes-vous sûr·e de vouloir supprimer le fichier \"{name}\"\
|
||||
\ ? Les notes liées à ce fichier seront aussi supprimées."
|
||||
\ ? Il sera retiré de toutes ses notes liées."
|
||||
unfollowConfirm: "Désirez-vous vous désabonner de {name} ?"
|
||||
exportRequested: "Vous avez demandé une exportation. L’opération pourrait prendre\
|
||||
\ un peu de temps. Une terminée, le fichier résultant sera ajouté au Drive."
|
||||
|
@ -1931,7 +1931,8 @@ flagSpeakAsCatDescription: Vos messages seront nyanifiés en mode chat
|
|||
hiddenTags: Hashtags cachés
|
||||
hiddenTagsDescription: "Lister les hashtags (sans le #) que vous souhaitez cacher\
|
||||
\ de tendances et explorer. Les hashtags cachés sont toujours découvrables par d'autres\
|
||||
\ moyens."
|
||||
\ moyens. Les instances bloqués ne sont pas ne sont pas affectés, même si ils sont\
|
||||
\ présent dans cette liste."
|
||||
antennaInstancesDescription: Lister un hôte d'instance par ligne
|
||||
userSaysSomethingReason: '{name} a dit {reason}'
|
||||
breakFollowConfirm: Êtes vous sur de vouloir retirer l'abonné ?
|
||||
|
@ -2000,3 +2001,12 @@ customKaTeXMacroDescription: "Définissez des macros pour écrire des expression
|
|||
\ Seulement de simples fonctions de substitution de chaines sont supportées; la\
|
||||
\ syntaxe avancée, telle que la ramification conditionnelle, ne peut pas être utilisée\
|
||||
\ ici."
|
||||
enableRecommendedTimeline: Activer la chronologie recommandée
|
||||
silenceThisInstance: Ne plus montrer cet instance
|
||||
silencedInstances: Instances silencieuses
|
||||
silenced: Silencieux
|
||||
deleted: Effacé
|
||||
editNote: Modifier note
|
||||
edited: Modifié
|
||||
flagShowTimelineRepliesDescription: Si activé, affiche dans le fil les réponses des
|
||||
personnes aux publications des autres.
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
---
|
||||
_lang_: "Bahasa Indonesia"
|
||||
headlineMisskey: "Jaringan terhubung melalui catatan"
|
||||
introMisskey: "Selamat datang! Misskey adalah perangkat mikroblog tercatu bersifat sumber terbuka.\nMulailah menuliskan catatan, bagikan peristiwa terkini, serta ceritakan segala tentangmu.📡\nTunjukkan juga reaksimu pada catatan pengguna lain.👍\nMari jelajahi dunia baru🚀"
|
||||
introMisskey: "Selamat datang! Misskey adalah perangkat mikroblog tercatu bersifat\
|
||||
\ sumber terbuka.\nMulailah menuliskan catatan, bagikan peristiwa terkini, serta\
|
||||
\ ceritakan segala tentangmu.\U0001F4E1\nTunjukkan juga reaksimu pada catatan pengguna\
|
||||
\ lain.\U0001F44D\nMari jelajahi dunia baru\U0001F680"
|
||||
monthAndDay: "{day} {month}"
|
||||
search: "Penelusuran"
|
||||
notifications: "Pemberitahuan"
|
||||
|
@ -44,7 +46,8 @@ copyContent: "Salin konten"
|
|||
copyLink: "Salin tautan"
|
||||
delete: "Hapus"
|
||||
deleteAndEdit: "Hapus dan sunting"
|
||||
deleteAndEditConfirm: "Apakah kamu yakin ingin menghapus note ini dan menyuntingnya? Kamu akan kehilangan semua reaksi, renote dan balasan di note ini."
|
||||
deleteAndEditConfirm: "Apakah kamu yakin ingin menghapus note ini dan menyuntingnya?\
|
||||
\ Kamu akan kehilangan semua reaksi, renote dan balasan di note ini."
|
||||
addToList: "Tambahkan ke daftar"
|
||||
sendMessage: "Kirim pesan"
|
||||
copyUsername: "Salin nama pengguna"
|
||||
|
@ -66,7 +69,8 @@ files: "Berkas"
|
|||
download: "Unduh"
|
||||
driveFileDeleteConfirm: "Hapus {name}? Catatan dengan berkas terkait juga akan terhapus."
|
||||
unfollowConfirm: "Berhenti mengikuti {name}?"
|
||||
exportRequested: "Kamu telah meminta ekspor. Ini akan memakan waktu sesaat. Setelah ekspor selesai, berkas yang dihasilkan akan ditambahkan ke Drive"
|
||||
exportRequested: "Kamu telah meminta ekspor. Ini akan memakan waktu sesaat. Setelah\
|
||||
\ ekspor selesai, berkas yang dihasilkan akan ditambahkan ke Drive"
|
||||
importRequested: "Kamu telah meminta impor. Ini akan memakan waktu sesaat."
|
||||
lists: "Daftar"
|
||||
noLists: "Kamu tidak memiliki daftar apapun"
|
||||
|
@ -81,9 +85,12 @@ error: "Galat"
|
|||
somethingHappened: "Terjadi kesalahan"
|
||||
retry: "Coba lagi"
|
||||
pageLoadError: "Gagal memuat halaman."
|
||||
pageLoadErrorDescription: "Umumnya disebabkan jaringan atau tembolok perambah. Cobalah bersihkan tembolok peramban lalu tunggu sesaat sebelum mencoba kembali."
|
||||
serverIsDead: "Tidak ada respon dari peladen. Mohon tunggu dan coba beberapa saat lagi."
|
||||
youShouldUpgradeClient: "Untuk melihat halaman ini, mohon muat ulang untuk memutakhirkan klienmu."
|
||||
pageLoadErrorDescription: "Umumnya disebabkan jaringan atau tembolok perambah. Cobalah\
|
||||
\ bersihkan tembolok peramban lalu tunggu sesaat sebelum mencoba kembali."
|
||||
serverIsDead: "Tidak ada respon dari peladen. Mohon tunggu dan coba beberapa saat\
|
||||
\ lagi."
|
||||
youShouldUpgradeClient: "Untuk melihat halaman ini, mohon muat ulang untuk memutakhirkan\
|
||||
\ klienmu."
|
||||
enterListName: "Masukkan nama daftar"
|
||||
privacy: "Privasi"
|
||||
makeFollowManuallyApprove: "Permintaan mengikuti membutuhkan persetujuan"
|
||||
|
@ -108,7 +115,8 @@ sensitive: "Konten sensitif"
|
|||
add: "Tambahkan"
|
||||
reaction: "Reaksi"
|
||||
reactionSetting: "Reaksi untuk dimunculkan di bilah reaksi"
|
||||
reactionSettingDescription2: "Geser untuk memindah urutkan, klik untuk menghapus, tekan \"+\" untuk menambahkan"
|
||||
reactionSettingDescription2: "Geser untuk memindah urutkan, klik untuk menghapus,\
|
||||
\ tekan \"+\" untuk menambahkan"
|
||||
rememberNoteVisibility: "Ingat pengaturan visibilitas catatan"
|
||||
attachCancel: "Hapus lampiran"
|
||||
markAsSensitive: "Tandai sebagai konten sensitif"
|
||||
|
@ -137,14 +145,22 @@ emojiUrl: "URL Emoji"
|
|||
addEmoji: "Tambahkan emoji"
|
||||
settingGuide: "Pengaturan rekomendasi"
|
||||
cacheRemoteFiles: "Tembolokkan berkas remote"
|
||||
cacheRemoteFilesDescription: "Ketika pengaturan ini dinonaktifkan, berkas luar akan dimuat langsung dari instansi luar. Menonaktifkan ini akan mengurangi penggunaan penyimpanan, namun dapat menyebabkan meningkatkan lalu lintas bandwidth, karena thumbnail tidak dihasilkan."
|
||||
cacheRemoteFilesDescription: "Ketika pengaturan ini dinonaktifkan, berkas luar akan\
|
||||
\ dimuat langsung dari instansi luar. Menonaktifkan ini akan mengurangi penggunaan\
|
||||
\ penyimpanan, namun dapat menyebabkan meningkatkan lalu lintas bandwidth, karena\
|
||||
\ thumbnail tidak dihasilkan."
|
||||
flagAsBot: "Atur akun ini sebagai Bot"
|
||||
flagAsBotDescription: "Jika akun ini dikendalikan oleh program, tetapkanlah opsi ini. Jika diaktifkan, ini akan berfungsi sebagai tanda bagi pengembang lain untuk mencegah interaksi berantai dengan bot lain dan menyesuaikan sistem internal Misskey untuk memperlakukan akun ini sebagai bot."
|
||||
flagAsBotDescription: "Jika akun ini dikendalikan oleh program, tetapkanlah opsi ini.\
|
||||
\ Jika diaktifkan, ini akan berfungsi sebagai tanda bagi pengembang lain untuk mencegah\
|
||||
\ interaksi berantai dengan bot lain dan menyesuaikan sistem internal Misskey untuk\
|
||||
\ memperlakukan akun ini sebagai bot."
|
||||
flagAsCat: "Atur akun ini sebagai kucing"
|
||||
flagAsCatDescription: "Nyalakan tanda ini untuk menandai akun ini sebagai kucing."
|
||||
flagShowTimelineReplies: "Tampilkan balasan di linimasa"
|
||||
flagShowTimelineRepliesDescription: "Menampilkan balasan pengguna dari note pengguna lain di linimasa apabila dinyalakan."
|
||||
autoAcceptFollowed: "Setujui otomatis permintaan mengikuti dari pengguna yang kamu ikuti"
|
||||
flagShowTimelineRepliesDescription: "Menampilkan balasan pengguna dari note pengguna\
|
||||
\ lain di linimasa apabila dinyalakan."
|
||||
autoAcceptFollowed: "Setujui otomatis permintaan mengikuti dari pengguna yang kamu\
|
||||
\ ikuti"
|
||||
addAccount: "Tambahkan akun"
|
||||
loginFailed: "Gagal untuk masuk"
|
||||
showOnRemote: "Lihat profil asli"
|
||||
|
@ -156,7 +172,11 @@ searchWith: "Cari: {q}"
|
|||
youHaveNoLists: "Kamu tidak memiliki daftar apapun"
|
||||
followConfirm: "Apakah kamu yakin ingin mengikuti {name}?"
|
||||
proxyAccount: "Akun proksi"
|
||||
proxyAccountDescription: "Akun proksi merupakan sebuah akun yang bertindak sebagai pengikut luar untuk pengguna dalam kondisi tertentu. Sebagai contoh, ketika pengguna menambahkan seorang pengguna luar ke dalam daftar, aktivitas dari pengguna luar tidak akan disampaikan ke instansi apabila tidak ada pengguna lokal yang mengikuti pengguna tersebut, dengan begitu akun proksilah yang akan mengikutinya."
|
||||
proxyAccountDescription: "Akun proksi merupakan sebuah akun yang bertindak sebagai\
|
||||
\ pengikut luar untuk pengguna dalam kondisi tertentu. Sebagai contoh, ketika pengguna\
|
||||
\ menambahkan seorang pengguna luar ke dalam daftar, aktivitas dari pengguna luar\
|
||||
\ tidak akan disampaikan ke instansi apabila tidak ada pengguna lokal yang mengikuti\
|
||||
\ pengguna tersebut, dengan begitu akun proksilah yang akan mengikutinya."
|
||||
host: "Host"
|
||||
selectUser: "Pilih pengguna"
|
||||
recipient: "Penerima"
|
||||
|
@ -187,11 +207,15 @@ instanceInfo: "Informasi Instansi"
|
|||
statistics: "Statistik"
|
||||
clearQueue: "Bersihkan antrian"
|
||||
clearQueueConfirmTitle: "Apakah kamu yakin ingin membersihkan antrian?"
|
||||
clearQueueConfirmText: "Seluruh sisa catatan yang tidak tersampaikan di dalam antrian tidak akan difederasi. Biasanya operasi ini TIDAK dibutuhkan."
|
||||
clearQueueConfirmText: "Seluruh sisa catatan yang tidak tersampaikan di dalam antrian\
|
||||
\ tidak akan difederasi. Biasanya operasi ini TIDAK dibutuhkan."
|
||||
clearCachedFiles: "Hapus tembolok"
|
||||
clearCachedFilesConfirm: "Apakah kamu yakin ingin menghapus seluruh tembolok berkas remote?"
|
||||
clearCachedFilesConfirm: "Apakah kamu yakin ingin menghapus seluruh tembolok berkas\
|
||||
\ remote?"
|
||||
blockedInstances: "Instansi terblokir"
|
||||
blockedInstancesDescription: "Daftar nama host dari instansi yang diperlukan untuk diblokir. Instansi yang didaftarkan tidak akan dapat berkomunikasi dengan instansi ini."
|
||||
blockedInstancesDescription: "Daftar nama host dari instansi yang diperlukan untuk\
|
||||
\ diblokir. Instansi yang didaftarkan tidak akan dapat berkomunikasi dengan instansi\
|
||||
\ ini."
|
||||
muteAndBlock: "Bisukan / Blokir"
|
||||
mutedUsers: "Pengguna yang dibisukan"
|
||||
blockedUsers: "Pengguna yang diblokir"
|
||||
|
@ -239,7 +263,8 @@ saved: "Telah disimpan"
|
|||
messaging: "Pesan"
|
||||
upload: "Unggah"
|
||||
keepOriginalUploading: "Simpan gambar asli"
|
||||
keepOriginalUploadingDescription: "Simpan gambar yang diunggah sebagaimana gambar aslinya. Bila dimatikan, versi tampilan web akan dihasilkan pada saat diunggah."
|
||||
keepOriginalUploadingDescription: "Simpan gambar yang diunggah sebagaimana gambar\
|
||||
\ aslinya. Bila dimatikan, versi tampilan web akan dihasilkan pada saat diunggah."
|
||||
fromDrive: "Dari Drive"
|
||||
fromUrl: "Dari URL"
|
||||
uploadFromUrl: "Unggah dari URL"
|
||||
|
@ -255,7 +280,8 @@ agreeTo: "Saya setuju kepada {0}"
|
|||
tos: "Syarat dan ketentuan"
|
||||
start: "Mulai"
|
||||
home: "Beranda"
|
||||
remoteUserCaution: "Informasi ini mungkin tidak mutakhir, karena pengguna ini berasal dari instansi luar."
|
||||
remoteUserCaution: "Informasi ini mungkin tidak mutakhir, karena pengguna ini berasal\
|
||||
\ dari instansi luar."
|
||||
activity: "Aktivitas"
|
||||
images: "Gambar"
|
||||
birthday: "Tanggal lahir"
|
||||
|
@ -288,7 +314,8 @@ unableToDelete: "Tidak dapat menghapus"
|
|||
inputNewFileName: "Masukkan nama berkas yang baru"
|
||||
inputNewDescription: "Masukkan keterangan disini"
|
||||
inputNewFolderName: "Masukkan nama folder yang baru"
|
||||
circularReferenceFolder: "Folder tujuan adalah subfolder dari folder yang ingin kamu pindahkan."
|
||||
circularReferenceFolder: "Folder tujuan adalah subfolder dari folder yang ingin kamu\
|
||||
\ pindahkan."
|
||||
hasChildFilesOrFolders: "Karena folder ini tidak kosong, maka tidak dapat dihapus."
|
||||
copyUrl: "Salin tautan"
|
||||
rename: "Ubah nama"
|
||||
|
@ -322,7 +349,8 @@ connectService: "Sambungkan"
|
|||
disconnectService: "Putuskan"
|
||||
enableLocalTimeline: "Nyalakan linimasa lokal"
|
||||
enableGlobalTimeline: "Nyalakan linimasa global"
|
||||
disablingTimelinesInfo: "Admin dan Moderator akan selalu memiliki akses ke semua linimasa meskipun linimasa tersebut tidak diaktifkan."
|
||||
disablingTimelinesInfo: "Admin dan Moderator akan selalu memiliki akses ke semua linimasa\
|
||||
\ meskipun linimasa tersebut tidak diaktifkan."
|
||||
registration: "Pendaftaran"
|
||||
enableRegistration: "Nyalakan pendaftaran pengguna baru"
|
||||
invite: "Undang"
|
||||
|
@ -334,9 +362,11 @@ bannerUrl: "URL Banner"
|
|||
backgroundImageUrl: "URL Gambar latar"
|
||||
basicInfo: "Informasi Umum"
|
||||
pinnedUsers: "Pengguna yang disematkan"
|
||||
pinnedUsersDescription: "Tuliskan satu nama pengguna dalam satu baris. Pengguna yang dituliskan disini akan disematkan dalam bilah \"Jelajahi\"."
|
||||
pinnedUsersDescription: "Tuliskan satu nama pengguna dalam satu baris. Pengguna yang\
|
||||
\ dituliskan disini akan disematkan dalam bilah \"Jelajahi\"."
|
||||
pinnedPages: "Halaman yang disematkan"
|
||||
pinnedPagesDescription: "Masukkan tautan dari halaman yang kamu ingin sematkan ke halaman utama dari instansi ini, dipisah dengan membuat baris baru."
|
||||
pinnedPagesDescription: "Masukkan tautan dari halaman yang kamu ingin sematkan ke\
|
||||
\ halaman utama dari instansi ini, dipisah dengan membuat baris baru."
|
||||
pinnedClipId: "ID dari klip yang disematkan"
|
||||
pinnedNotes: "Catatan yang disematkan"
|
||||
hcaptcha: "hCaptcha"
|
||||
|
@ -347,14 +377,17 @@ recaptcha: "reCAPTCHA"
|
|||
enableRecaptcha: "Nyalakan reCAPTCHA"
|
||||
recaptchaSiteKey: "Site key"
|
||||
recaptchaSecretKey: "Secret Key"
|
||||
avoidMultiCaptchaConfirm: "Menggunakan banyak Captcha dapat menyebabkan gangguan. Apakah kamu ingin untuk menonaktifkan Captcha yang lain? Kamu dapat membiarkan fitur ini tetap aktif dengan menekan tombol batal."
|
||||
avoidMultiCaptchaConfirm: "Menggunakan banyak Captcha dapat menyebabkan gangguan.\
|
||||
\ Apakah kamu ingin untuk menonaktifkan Captcha yang lain? Kamu dapat membiarkan\
|
||||
\ fitur ini tetap aktif dengan menekan tombol batal."
|
||||
antennas: "Antena"
|
||||
manageAntennas: "Pengelola Antena"
|
||||
name: "Nama"
|
||||
antennaSource: "Sumber Antenna"
|
||||
antennaKeywords: "Kata kunci yang diterima"
|
||||
antennaExcludeKeywords: "Kata kunci yang dikecualikan"
|
||||
antennaKeywordsDescription: "Pisahkan dengan spasi untuk kondisi AND. Pisahkan dengan baris baru untuk kondisi OR."
|
||||
antennaKeywordsDescription: "Pisahkan dengan spasi untuk kondisi AND. Pisahkan dengan\
|
||||
\ baris baru untuk kondisi OR."
|
||||
notifyAntenna: "Beritahu untuk catatan baru"
|
||||
withFileAntenna: "Hanya tampilkan catatan dengan berkas yang dilampirkan"
|
||||
enableServiceworker: "Aktifkan ServiceWorker"
|
||||
|
@ -441,7 +474,8 @@ strongPassword: "Kata sandi kuat"
|
|||
passwordMatched: "Kata sandi sama"
|
||||
passwordNotMatched: "Kata sandi tidak sama"
|
||||
signinWith: "Masuk dengan {x}"
|
||||
signinFailed: "Tidak dapat masuk. Nama pengguna atau kata sandi yang kamu masukkan salah."
|
||||
signinFailed: "Tidak dapat masuk. Nama pengguna atau kata sandi yang kamu masukkan\
|
||||
\ salah."
|
||||
tapSecurityKey: "Ketuk kunci keamanan kamu"
|
||||
or: "atau"
|
||||
language: "Bahasa"
|
||||
|
@ -482,19 +516,29 @@ showFeaturedNotesInTimeline: "Tampilkan catatan yang diunggulkan di linimasa"
|
|||
objectStorage: "Object Storage"
|
||||
useObjectStorage: "Gunakan object storage"
|
||||
objectStorageBaseUrl: "Base URL"
|
||||
objectStorageBaseUrlDesc: "Prefix URL digunakan untuk mengkonstruksi URL ke object (media) referencing. Tentukan URL jika kamu menggunakan CDN atau Proxy, jika tidak tentukan alamat yang dapat diakses secara publik sesuai dengan panduan dari layanan yang akan kamu gunakan, contohnya. 'https://<bucket>.s3.amazonaws.com' untuk AWS S3, dan 'https://storage.googleapis.com/<bucket>' untuk GCS."
|
||||
objectStorageBaseUrlDesc: "Prefix URL digunakan untuk mengkonstruksi URL ke object\
|
||||
\ (media) referencing. Tentukan URL jika kamu menggunakan CDN atau Proxy, jika tidak\
|
||||
\ tentukan alamat yang dapat diakses secara publik sesuai dengan panduan dari layanan\
|
||||
\ yang akan kamu gunakan, contohnya. 'https://<bucket>.s3.amazonaws.com' untuk AWS\
|
||||
\ S3, dan 'https://storage.googleapis.com/<bucket>' untuk GCS."
|
||||
objectStorageBucket: "Bucket"
|
||||
objectStorageBucketDesc: "Mohon tentukan nama bucket yang digunakan pada layanan yang telah dikonfigurasi."
|
||||
objectStorageBucketDesc: "Mohon tentukan nama bucket yang digunakan pada layanan yang\
|
||||
\ telah dikonfigurasi."
|
||||
objectStoragePrefix: "Prefix"
|
||||
objectStoragePrefixDesc: "Berkas tidak akan disimpan dalam direktori dari prefix ini."
|
||||
objectStorageEndpoint: "Endpoint"
|
||||
objectStorageEndpointDesc: "Kosongkan bagian ini jika kamu menggunakan AWS S3, jika tidak tentukan endpoint sebagai '<host>' atau '<host>:<port>' sesuai dengan panduan dari layanan yang akan kamu gunakan."
|
||||
objectStorageEndpointDesc: "Kosongkan bagian ini jika kamu menggunakan AWS S3, jika\
|
||||
\ tidak tentukan endpoint sebagai '<host>' atau '<host>:<port>' sesuai dengan panduan\
|
||||
\ dari layanan yang akan kamu gunakan."
|
||||
objectStorageRegion: "Region"
|
||||
objectStorageRegionDesc: "Tentukan region seperti 'xx-east-1'. Jika layanan kamu tidak memiliki perbedaan mengenai region, kosongkan saja atau isi dengan 'us-east-1'."
|
||||
objectStorageRegionDesc: "Tentukan region seperti 'xx-east-1'. Jika layanan kamu tidak\
|
||||
\ memiliki perbedaan mengenai region, kosongkan saja atau isi dengan 'us-east-1'."
|
||||
objectStorageUseSSL: "Gunakan SSL"
|
||||
objectStorageUseSSLDesc: "Matikan ini jika kamu tidak akan menggunakan HTTPS untuk koneksi API"
|
||||
objectStorageUseSSLDesc: "Matikan ini jika kamu tidak akan menggunakan HTTPS untuk\
|
||||
\ koneksi API"
|
||||
objectStorageUseProxy: "Hubungkan melalui Proxy"
|
||||
objectStorageUseProxyDesc: "Matikan ini jika kamu tidak akan menggunakan Proxy untuk koneksi ObjectStorage"
|
||||
objectStorageUseProxyDesc: "Matikan ini jika kamu tidak akan menggunakan Proxy untuk\
|
||||
\ koneksi ObjectStorage"
|
||||
objectStorageSetPublicRead: "Setel \"public-read\" disaat mengunggah"
|
||||
serverLogs: "Log Peladen"
|
||||
deleteAll: "Hapus semua"
|
||||
|
@ -522,7 +566,9 @@ sort: "Urutkan"
|
|||
ascendingOrder: "Urutkan naik"
|
||||
descendingOrder: "Urutkan menurun"
|
||||
scratchpad: "Scratchpad"
|
||||
scratchpadDescription: "Scratchpad menyediakan lingkungan eksperimen untuk AiScript. Kamu bisa menulis, mengeksuksi, serta mengecek hasil yang berinteraksi dengan Misskey."
|
||||
scratchpadDescription: "Scratchpad menyediakan lingkungan eksperimen untuk AiScript.\
|
||||
\ Kamu bisa menulis, mengeksuksi, serta mengecek hasil yang berinteraksi dengan\
|
||||
\ Misskey."
|
||||
output: "Keluaran"
|
||||
script: "Script"
|
||||
disablePagesScript: "Nonaktifkan script pada halaman"
|
||||
|
@ -530,11 +576,14 @@ updateRemoteUser: "Perbaharui informasi pengguna luar"
|
|||
deleteAllFiles: "Hapus semua berkas"
|
||||
deleteAllFilesConfirm: "Apakah kamu yakin ingin menghapus semua berkas?"
|
||||
removeAllFollowing: "Tahan semua mengikuti"
|
||||
removeAllFollowingDescription: "Batal mengikuti semua akun dari {host}. Mohon jalankan ini ketika instansi sudah tidak ada lagi."
|
||||
removeAllFollowingDescription: "Batal mengikuti semua akun dari {host}. Mohon jalankan\
|
||||
\ ini ketika instansi sudah tidak ada lagi."
|
||||
userSuspended: "Pengguna ini telah dibekukan."
|
||||
userSilenced: "Pengguna ini telah dibungkam."
|
||||
yourAccountSuspendedTitle: "Akun ini dibekukan"
|
||||
yourAccountSuspendedDescription: "Akun ini dibekukan karena melanggar ketentuan penggunaan layanan peladen atau semacamnya. Hubungi admin apabila ingin tahu alasan lebih lanjut. Mohon untuk tidak membuat akun baru."
|
||||
yourAccountSuspendedDescription: "Akun ini dibekukan karena melanggar ketentuan penggunaan\
|
||||
\ layanan peladen atau semacamnya. Hubungi admin apabila ingin tahu alasan lebih\
|
||||
\ lanjut. Mohon untuk tidak membuat akun baru."
|
||||
menu: "Menu"
|
||||
divider: "Pembagi"
|
||||
addItem: "Tambahkan item"
|
||||
|
@ -579,7 +628,8 @@ notificationType: "Jenis pemberitahuan"
|
|||
edit: "Sunting"
|
||||
emailServer: "Peladen surel"
|
||||
enableEmail: "Nyalakan distribusi surel"
|
||||
emailConfigInfo: "Digunakan untuk mengonfirmasi surel kamu disaat mendaftar dan lupa kata sandi"
|
||||
emailConfigInfo: "Digunakan untuk mengonfirmasi surel kamu disaat mendaftar dan lupa\
|
||||
\ kata sandi"
|
||||
email: "Surel"
|
||||
emailAddress: "Alamat surel"
|
||||
smtpConfig: "Konfigurasi peladen SMTP"
|
||||
|
@ -587,13 +637,15 @@ smtpHost: "Host"
|
|||
smtpPort: "Port"
|
||||
smtpUser: "Nama Pengguna"
|
||||
smtpPass: "Kata sandi"
|
||||
emptyToDisableSmtpAuth: "Kosongkan nama pengguna dan kata sandi untuk menonaktifkan verifikasi SMTP"
|
||||
emptyToDisableSmtpAuth: "Kosongkan nama pengguna dan kata sandi untuk menonaktifkan\
|
||||
\ verifikasi SMTP"
|
||||
smtpSecure: "Gunakan SSL/TLS implisit untuk koneksi SMTP"
|
||||
smtpSecureInfo: "Matikan ini ketika menggunakan STARTTLS"
|
||||
testEmail: "Tes pengiriman surel"
|
||||
wordMute: "Bisukan kata"
|
||||
regexpError: "Kesalahan ekspresi reguler"
|
||||
regexpErrorDescription: "Galat terjadi pada baris {line} ekspresi reguler dari {tab} kata yang dibisukan:"
|
||||
regexpErrorDescription: "Galat terjadi pada baris {line} ekspresi reguler dari {tab}\
|
||||
\ kata yang dibisukan:"
|
||||
instanceMute: "Bisuka instansi"
|
||||
userSaysSomething: "{name} mengatakan sesuatu"
|
||||
makeActive: "Aktifkan"
|
||||
|
@ -609,30 +661,37 @@ create: "Buat"
|
|||
notificationSetting: "Pengaturan Pemberitahuan"
|
||||
notificationSettingDesc: "Pilih tipe pemberitahuan untuk ditampilkan"
|
||||
useGlobalSetting: "Gunakan setelan global"
|
||||
useGlobalSettingDesc: "Jika dinyalakan, setelan pemberitahuan akun kamu akan digunakan. Jika dimatikan, konfigurasi secara individu dapat dibuat."
|
||||
useGlobalSettingDesc: "Jika dinyalakan, setelan pemberitahuan akun kamu akan digunakan.\
|
||||
\ Jika dimatikan, konfigurasi secara individu dapat dibuat."
|
||||
other: "Lainnya"
|
||||
regenerateLoginToken: "Perbarui token login"
|
||||
regenerateLoginTokenDescription: "Perbarui token yang digunakan secara internal saat login. Normalnya aksi ini tidak diperlukan. Jika diperbarui, semua perangkat akan dilogout."
|
||||
setMultipleBySeparatingWithSpace: "Kamu dapat menyetel banyak dengan memisahkannya menggunakan spasi."
|
||||
regenerateLoginTokenDescription: "Perbarui token yang digunakan secara internal saat\
|
||||
\ login. Normalnya aksi ini tidak diperlukan. Jika diperbarui, semua perangkat akan\
|
||||
\ dilogout."
|
||||
setMultipleBySeparatingWithSpace: "Kamu dapat menyetel banyak dengan memisahkannya\
|
||||
\ menggunakan spasi."
|
||||
fileIdOrUrl: "File-ID atau URL"
|
||||
behavior: "Perilaku"
|
||||
sample: "Contoh"
|
||||
abuseReports: "Laporkan"
|
||||
reportAbuse: "Laporkan"
|
||||
reportAbuseOf: "Laporkan {name}"
|
||||
fillAbuseReportDescription: "Mohon isi rincian laporan. Jika laporan ini mengenai catatan yang spesifik, mohon lampirkan serta URL catatan tersebut."
|
||||
fillAbuseReportDescription: "Mohon isi rincian laporan. Jika laporan ini mengenai\
|
||||
\ catatan yang spesifik, mohon lampirkan serta URL catatan tersebut."
|
||||
abuseReported: "Laporan kamu telah dikirimkan. Terima kasih."
|
||||
reporter: "Pelapor"
|
||||
reporteeOrigin: "Yang dilaporkan"
|
||||
reporterOrigin: "Pelapor"
|
||||
forwardReport: "Teruskan laporan ke instansi luar"
|
||||
forwardReportIsAnonymous: "Untuk melindungi privasi akun kamu, akun anonim dari sistem akan digunakan sebagai pelapor pada instansi luar."
|
||||
forwardReportIsAnonymous: "Untuk melindungi privasi akun kamu, akun anonim dari sistem\
|
||||
\ akan digunakan sebagai pelapor pada instansi luar."
|
||||
send: "Kirim"
|
||||
abuseMarkAsResolved: "Tandai laporan sebagai selesai"
|
||||
openInNewTab: "Buka di tab baru"
|
||||
openInSideView: "Buka di tampilan samping"
|
||||
defaultNavigationBehaviour: "Navigasi bawaan"
|
||||
editTheseSettingsMayBreakAccount: "Menyunting pengaturan ini memiliki kemungkinan untuk merusak akun kamu."
|
||||
editTheseSettingsMayBreakAccount: "Menyunting pengaturan ini memiliki kemungkinan\
|
||||
\ untuk merusak akun kamu."
|
||||
instanceTicker: "Informasi pengguna pada instansi"
|
||||
waitingFor: "Menunggu untuk {x}"
|
||||
random: "Acak"
|
||||
|
@ -644,9 +703,11 @@ createNew: "Buat baru"
|
|||
optional: "Opsional"
|
||||
createNewClip: "Buat klip baru"
|
||||
unclip: "Batalkan klip"
|
||||
confirmToUnclipAlreadyClippedNote: "Catatan ini sudah disertakan di klip \"{name}\". Yakin ingin membatalkan catatan dari klip ini?"
|
||||
confirmToUnclipAlreadyClippedNote: "Catatan ini sudah disertakan di klip \"{name}\"\
|
||||
. Yakin ingin membatalkan catatan dari klip ini?"
|
||||
public: "Publik"
|
||||
i18nInfo: "Calckey diterjemahkan ke dalam banyak bahasa oleh sukarelawan. Kamu dapat ikut membantu di {link}."
|
||||
i18nInfo: "Calckey diterjemahkan ke dalam banyak bahasa oleh sukarelawan. Kamu dapat\
|
||||
\ ikut membantu di {link}."
|
||||
manageAccessTokens: "Kelola access token"
|
||||
accountInfo: "Informasi akun"
|
||||
notesCount: "Jumlah catatan"
|
||||
|
@ -665,12 +726,16 @@ no: "Tidak"
|
|||
driveFilesCount: "Jumlah berkas drive"
|
||||
driveUsage: "Penggunaan ruang penyimpanan drive"
|
||||
noCrawle: "Tolak pengindeksan crawler"
|
||||
noCrawleDescription: "Meminta mesin pencari untuk tidak mengindeks halaman profil kamu, catatan, Halaman, dll."
|
||||
lockedAccountInfo: "Kecuali kamu menyetel visibilitas catatan milikmu ke \"Hanya pengikut\", catatan milikmu akan dapat dilihat oleh siapa saja, bahkan jika kamu memerlukan pengikut untuk disetujui secara manual."
|
||||
noCrawleDescription: "Meminta mesin pencari untuk tidak mengindeks halaman profil\
|
||||
\ kamu, catatan, Halaman, dll."
|
||||
lockedAccountInfo: "Kecuali kamu menyetel visibilitas catatan milikmu ke \"Hanya pengikut\"\
|
||||
, catatan milikmu akan dapat dilihat oleh siapa saja, bahkan jika kamu memerlukan\
|
||||
\ pengikut untuk disetujui secara manual."
|
||||
alwaysMarkSensitive: "Tandai media dalam catatan sebagai media sensitif"
|
||||
loadRawImages: "Tampilkan lampiran gambar secara penuh daripada thumbnail"
|
||||
disableShowingAnimatedImages: "Jangan mainkan gambar bergerak"
|
||||
verificationEmailSent: "Surel verifikasi telah dikirimkan. Mohon akses tautan yang telah disertakan untuk menyelesaikan verifikasi."
|
||||
verificationEmailSent: "Surel verifikasi telah dikirimkan. Mohon akses tautan yang\
|
||||
\ telah disertakan untuk menyelesaikan verifikasi."
|
||||
notSet: "Tidak disetel"
|
||||
emailVerified: "Surel telah diverifikasi"
|
||||
noteFavoritesCount: "Jumlah catatan yang difavoritkan"
|
||||
|
@ -682,14 +747,16 @@ clips: "Klip"
|
|||
experimentalFeatures: "Fitur eksperimental"
|
||||
developer: "Pengembang"
|
||||
makeExplorable: "Buat akun tampil di \"Jelajahi\""
|
||||
makeExplorableDescription: "Jika kamu mematikan ini, akun kamu tidak akan muncul di bagian \"Jelajahi:"
|
||||
makeExplorableDescription: "Jika kamu mematikan ini, akun kamu tidak akan muncul di\
|
||||
\ bagian \"Jelajahi:"
|
||||
showGapBetweenNotesInTimeline: "Tampilkan jarak diantara catatan pada linimasa"
|
||||
duplicate: "Duplikat"
|
||||
left: "Kiri"
|
||||
center: "Tengah"
|
||||
wide: "Lebar"
|
||||
narrow: "Sempit"
|
||||
reloadToApplySetting: "Pengaturan ini akan diterapkan saat memuat halaman kembali. Apakah kamu ingin memuat halaman kembali sekarang?"
|
||||
reloadToApplySetting: "Pengaturan ini akan diterapkan saat memuat halaman kembali.\
|
||||
\ Apakah kamu ingin memuat halaman kembali sekarang?"
|
||||
needReloadToApply: "Pengaturan ini hanya akan diterapkan setelah memuat ulang halaman."
|
||||
showTitlebar: "Tampilkan bilah judul"
|
||||
clearCache: "Hapus tembolok"
|
||||
|
@ -697,7 +764,10 @@ onlineUsersCount: "{n} orang sedang daring"
|
|||
nUsers: "{n} Pengguna"
|
||||
nNotes: "{n} Catatan"
|
||||
sendErrorReports: "Kirim laporan kesalahan"
|
||||
sendErrorReportsDescription: "Ketika dinyalakan, informasi kesalahan rinci akan dibagikan dengan Misskey ketika masalah terjadi, hal ini untuk membantu kualitas Misskey. Fitur ini memungkinkan memuat informasi seperti sistem operasi yang kamu gunakan dan versinya, aplikasi peramban yang kamu gunakan, riwayat aktivitas kamu, dll."
|
||||
sendErrorReportsDescription: "Ketika dinyalakan, informasi kesalahan rinci akan dibagikan\
|
||||
\ dengan Misskey ketika masalah terjadi, hal ini untuk membantu kualitas Misskey.\
|
||||
\ Fitur ini memungkinkan memuat informasi seperti sistem operasi yang kamu gunakan\
|
||||
\ dan versinya, aplikasi peramban yang kamu gunakan, riwayat aktivitas kamu, dll."
|
||||
myTheme: "Tema saya"
|
||||
backgroundColor: "Latar Belakang"
|
||||
accentColor: "Aksen"
|
||||
|
@ -736,14 +806,17 @@ unlikeConfirm: "Yakin ingin hapus sukamu?"
|
|||
fullView: "Tampilan penuh"
|
||||
quitFullView: "Keluar tampilan penuh"
|
||||
addDescription: "Tambahkan deskripsi"
|
||||
userPagePinTip: "Kamu dapat membuat catatan untuk ditampilkan disini dengan memilih \"Sematkan ke profil\" dari menu pada catatan individu."
|
||||
notSpecifiedMentionWarning: "Catatan ini mengandung sebutan dari pengguna yang tidak dimuat sebagai penerima"
|
||||
userPagePinTip: "Kamu dapat membuat catatan untuk ditampilkan disini dengan memilih\
|
||||
\ \"Sematkan ke profil\" dari menu pada catatan individu."
|
||||
notSpecifiedMentionWarning: "Catatan ini mengandung sebutan dari pengguna yang tidak\
|
||||
\ dimuat sebagai penerima"
|
||||
info: "Informasi"
|
||||
userInfo: "Informasi pengguna"
|
||||
unknown: "Tidak diketahui"
|
||||
onlineStatus: "Status daring"
|
||||
hideOnlineStatus: "Sembunyikan status daring"
|
||||
hideOnlineStatusDescription: "Menyembunyikan status daring kamu umengurangi kenyamanan untuk beberapa fungsi seperti contohnya pencarian."
|
||||
hideOnlineStatusDescription: "Menyembunyikan status daring kamu umengurangi kenyamanan\
|
||||
\ untuk beberapa fungsi seperti contohnya pencarian."
|
||||
online: "Daring"
|
||||
active: "Aktif"
|
||||
offline: "Luring"
|
||||
|
@ -778,7 +851,8 @@ emailNotConfiguredWarning: "Alamat surel tidak disetel."
|
|||
ratio: "Rasio"
|
||||
previewNoteText: "Tampilkan pratinjau"
|
||||
customCss: "Custom CSS"
|
||||
customCssWarn: "Pengaturan ini seharusnya digunakan jika kamu tahu cara kerjanya. Memasukkan nilai yang tidak tepat dapat menyebabkan klien tidak berfungsi semestinya."
|
||||
customCssWarn: "Pengaturan ini seharusnya digunakan jika kamu tahu cara kerjanya.\
|
||||
\ Memasukkan nilai yang tidak tepat dapat menyebabkan klien tidak berfungsi semestinya."
|
||||
global: "Global"
|
||||
squareAvatars: "Tampilkan avatar sebagai persegi"
|
||||
sent: "Kirim"
|
||||
|
@ -793,7 +867,9 @@ whatIsNew: "Lihat perubahan pemutakhiran"
|
|||
translate: "Terjemahkan"
|
||||
translatedFrom: "Terjemahkan dari {x}"
|
||||
accountDeletionInProgress: "Penghapusan akun sedang dalam proses"
|
||||
usernameInfo: "Nama yang mengidentifikasikan akun kamu dari yang lain pada peladen ini. Kamu dapat menggunakan alfabet (a~z, A~Z), digit (0~9) atau garis bawah (_). Username tidak dapat diubah setelahnya."
|
||||
usernameInfo: "Nama yang mengidentifikasikan akun kamu dari yang lain pada peladen\
|
||||
\ ini. Kamu dapat menggunakan alfabet (a~z, A~Z), digit (0~9) atau garis bawah (_).\
|
||||
\ Username tidak dapat diubah setelahnya."
|
||||
aiChanMode: "Mode Ai"
|
||||
keepCw: "Biarkan Peringatan Konten"
|
||||
pubSub: "Akun Pub/Sub"
|
||||
|
@ -809,12 +885,14 @@ filter: "Saring"
|
|||
controlPanel: "Panel kendali"
|
||||
manageAccounts: "Kelola Akun"
|
||||
makeReactionsPublic: "Tampilkan riwayat reaksi ke publik"
|
||||
makeReactionsPublicDescription: "Pengaturan ini akan membuat daftar dari semua reaksi masa lalu kamu ditampilkan secara publik."
|
||||
makeReactionsPublicDescription: "Pengaturan ini akan membuat daftar dari semua reaksi\
|
||||
\ masa lalu kamu ditampilkan secara publik."
|
||||
classic: "Klasik"
|
||||
muteThread: "Bisukan thread"
|
||||
unmuteThread: "Suarakan thread"
|
||||
ffVisibility: "Visibilitas Mengikuti/Pengikut"
|
||||
ffVisibilityDescription: "Mengatur siapa yang dapat melihat pengikutmu dan yang kamu ikuti."
|
||||
ffVisibilityDescription: "Mengatur siapa yang dapat melihat pengikutmu dan yang kamu\
|
||||
\ ikuti."
|
||||
continueThread: "Lihat lanjutan thread"
|
||||
deleteAccountConfirm: "Akun akan dihapus. Apakah kamu yakin?"
|
||||
incorrectPassword: "Kata sandi salah."
|
||||
|
@ -824,7 +902,8 @@ leaveGroup: "Keluar grup"
|
|||
leaveGroupConfirm: "Apakah kamu yakin untuk keluar dari \"{name}\"?"
|
||||
useDrawerReactionPickerForMobile: "Tampilkan bilah reaksi sebagai laci di ponsel"
|
||||
welcomeBackWithName: "Selamat datang kembali, {name}."
|
||||
clickToFinishEmailVerification: "Mohon klik [{ok}] untuk menyelesaikan verifikasi email."
|
||||
clickToFinishEmailVerification: "Mohon klik [{ok}] untuk menyelesaikan verifikasi\
|
||||
\ email."
|
||||
overridedDeviceKind: "Tipe perangkat"
|
||||
smartphone: "Ponsel"
|
||||
tablet: "Tablet"
|
||||
|
@ -866,11 +945,16 @@ _ffVisibility:
|
|||
_signup:
|
||||
almostThere: "Hampir selesai"
|
||||
emailAddressInfo: "Mohon masukkan alamat surel kamu."
|
||||
emailSent: "Konfirmasi surel telah dikirimkan ke alamat surel kamu ({email}). Mohon klik tautan yang tercantum di dalamnya untuk menyelesaikan pembuatan akun."
|
||||
emailSent: "Konfirmasi surel telah dikirimkan ke alamat surel kamu ({email}). Mohon\
|
||||
\ klik tautan yang tercantum di dalamnya untuk menyelesaikan pembuatan akun."
|
||||
_accountDelete:
|
||||
accountDelete: "Hapus akun"
|
||||
mayTakeTime: "Karena penghapusan akun merupakan proses yang berat dan intensif, kemungkinan dapat membutuhkan waktu untuk menyelesaikan tergantung daripada berapa banyak konten yang kamu buat dan berapa banyak berkas yang telah kamu unggah."
|
||||
sendEmail: "Setelah penghapusan akun selesai, pemberitahuan akan dikirimkan ke alamat surel yang terdaftarkan pada akun ini."
|
||||
mayTakeTime: "Karena penghapusan akun merupakan proses yang berat dan intensif,\
|
||||
\ kemungkinan dapat membutuhkan waktu untuk menyelesaikan tergantung daripada\
|
||||
\ berapa banyak konten yang kamu buat dan berapa banyak berkas yang telah kamu\
|
||||
\ unggah."
|
||||
sendEmail: "Setelah penghapusan akun selesai, pemberitahuan akan dikirimkan ke alamat\
|
||||
\ surel yang terdaftarkan pada akun ini."
|
||||
requestAccountDelete: "Minta penghapusan akun"
|
||||
started: "Penghapusan telah dimulai"
|
||||
inProgress: "Penghapusan sedang dalam proses"
|
||||
|
@ -878,9 +962,13 @@ _ad:
|
|||
back: "Kembali"
|
||||
reduceFrequencyOfThisAd: "Tampilkan iklan ini lebih sedikit"
|
||||
_forgotPassword:
|
||||
enterEmail: "Masukkan alamat surel yang kamu gunakan pada saat mendaftar. Sebuah tautan untuk mengatur ulang kata sandi kamu akan dikirimkan ke alamat surel tersebut."
|
||||
ifNoEmail: "Apabila kamu tidak menggunakan surel pada saat pendaftaran, mohon hubungi admin segera."
|
||||
contactAdmin: "Instansi ini tidak mendukung menggunakan alamat surel, mohon kontak admin untuk mengatur ulang password kamu."
|
||||
enterEmail: "Masukkan alamat surel yang kamu gunakan pada saat mendaftar. Sebuah\
|
||||
\ tautan untuk mengatur ulang kata sandi kamu akan dikirimkan ke alamat surel\
|
||||
\ tersebut."
|
||||
ifNoEmail: "Apabila kamu tidak menggunakan surel pada saat pendaftaran, mohon hubungi\
|
||||
\ admin segera."
|
||||
contactAdmin: "Instansi ini tidak mendukung menggunakan alamat surel, mohon kontak\
|
||||
\ admin untuk mengatur ulang password kamu."
|
||||
_gallery:
|
||||
my: "Postingan saya"
|
||||
liked: "Postingan yang disukai"
|
||||
|
@ -902,13 +990,15 @@ _registry:
|
|||
domain: "Domain"
|
||||
createKey: "Buat kunci"
|
||||
_aboutMisskey:
|
||||
about: "Misskey adalah perangkat lunak sumber terbuka yang sedang dikembangkan oleh syuilo sejak 2014."
|
||||
about: "Misskey adalah perangkat lunak sumber terbuka yang sedang dikembangkan oleh\
|
||||
\ syuilo sejak 2014."
|
||||
contributors: "Kontributor utama"
|
||||
allContributors: "Seluruh kontributor"
|
||||
source: "Sumber kode"
|
||||
translation: "Terjemahkan Misskey"
|
||||
donate: "Donasi ke Misskey"
|
||||
morePatrons: "Kami sangat mengapresiasi dukungan dari banyak penolong lain yang tidak tercantum disini. Terima kasih! 🥰"
|
||||
morePatrons: "Kami sangat mengapresiasi dukungan dari banyak penolong lain yang\
|
||||
\ tidak tercantum disini. Terima kasih! \U0001F970"
|
||||
patrons: "Pendukung"
|
||||
_nsfw:
|
||||
respect: "Sembunyikan media NSFW"
|
||||
|
@ -916,10 +1006,12 @@ _nsfw:
|
|||
force: "Sembunyikan semua media"
|
||||
_mfm:
|
||||
cheatSheet: "Contekan MFM"
|
||||
intro: "MFM adalah Misskey-exclusive Markup Language yang dapat digunakan di banyak tempat. Berikut kamu bisa melihat daftar dari syntax MFM yang ada."
|
||||
intro: "MFM adalah Misskey-exclusive Markup Language yang dapat digunakan di banyak\
|
||||
\ tempat. Berikut kamu bisa melihat daftar dari syntax MFM yang ada."
|
||||
dummy: "Misskey membentangkan dunia Fediverse"
|
||||
mention: "Sebut"
|
||||
mentionDescription: "Kamu dapat menentukan pengguna tertentu dengan menggunakan simbol-At dan nama engguna mereka."
|
||||
mentionDescription: "Kamu dapat menentukan pengguna tertentu dengan menggunakan\
|
||||
\ simbol-At dan nama engguna mereka."
|
||||
hashtag: "Tagar"
|
||||
hashtagDescription: "Kamu dapat menentukan tagar dengan menggunakan angka dan teks."
|
||||
url: "URL"
|
||||
|
@ -935,15 +1027,18 @@ _mfm:
|
|||
inlineCode: "Kode (Dalam baris)"
|
||||
inlineCodeDescription: "Menampilkan sorotan sintaks dalam baris untuk kode(program-)."
|
||||
blockCode: "Kode (Blok)"
|
||||
blockCodeDescription: "Menampilkan sorotan sintaks untuk kode(program-) multi baris dalam sebuah blok."
|
||||
blockCodeDescription: "Menampilkan sorotan sintaks untuk kode(program-) multi baris\
|
||||
\ dalam sebuah blok."
|
||||
inlineMath: "Matematika (Dalam baris)"
|
||||
inlineMathDescription: "Menampilkan formula matematika (KaTeX) dalam baris."
|
||||
blockMath: "Matematika (Blok)"
|
||||
blockMathDescription: "Menampilkan formula matematika (KaTeX) multibaris dalam sebuah blok."
|
||||
blockMathDescription: "Menampilkan formula matematika (KaTeX) multibaris dalam sebuah\
|
||||
\ blok."
|
||||
quote: "Kutip"
|
||||
quoteDescription: "Menampilkan konten sebagai kutipan."
|
||||
emoji: "Emoji kustom"
|
||||
emojiDescription: "Emoji kustom dapat ditampilkan dengan mengurung nama emoji kustom menggunakan tanda titik dua."
|
||||
emojiDescription: "Emoji kustom dapat ditampilkan dengan mengurung nama emoji kustom\
|
||||
\ menggunakan tanda titik dua."
|
||||
search: "Penelusuran"
|
||||
searchDescription: "Menampilkan kotak pencarian dengan teks yang sudah dimasukkan."
|
||||
flip: "Balik"
|
||||
|
@ -969,7 +1064,8 @@ _mfm:
|
|||
x4: "Sangat besar"
|
||||
x4Description: "Tampilka konten menjadi sangat besar."
|
||||
blur: "Buram"
|
||||
blurDescription: "Konten dapat diburamkan dengan efek ini. Konten dapat ditampilkan dengan jelas dengan melayangkan kursor tetikus di atasnya."
|
||||
blurDescription: "Konten dapat diburamkan dengan efek ini. Konten dapat ditampilkan\
|
||||
\ dengan jelas dengan melayangkan kursor tetikus di atasnya."
|
||||
font: "Font"
|
||||
fontDescription: "Setel font yang ditampilkan untuk konten."
|
||||
rainbow: "Pelangi"
|
||||
|
@ -1003,15 +1099,21 @@ _menuDisplay:
|
|||
hide: "Sembunyikan"
|
||||
_wordMute:
|
||||
muteWords: "Kata yang dibisukan"
|
||||
muteWordsDescription: "Pisahkan dengan spasi untuk kondisi AND. Pisahkan dengan baris baru untuk kondisi OR."
|
||||
muteWordsDescription2: "Kurung kata kunci dengan garis miring untuk menggunakan regular expressions."
|
||||
muteWordsDescription: "Pisahkan dengan spasi untuk kondisi AND. Pisahkan dengan\
|
||||
\ baris baru untuk kondisi OR."
|
||||
muteWordsDescription2: "Kurung kata kunci dengan garis miring untuk menggunakan\
|
||||
\ regular expressions."
|
||||
softDescription: "Sembunyikan catatan yang memenuhi aturan kondisi dari linimasa."
|
||||
hardDescription: "Cegah catatan memenuhi aturan kondisi dari ditambahkan ke linimasa. Dengan tambahan, catatan berikut tidak akan ditambahkan ke linimasa meskipun jika kondisi tersebut diubah."
|
||||
hardDescription: "Cegah catatan memenuhi aturan kondisi dari ditambahkan ke linimasa.\
|
||||
\ Dengan tambahan, catatan berikut tidak akan ditambahkan ke linimasa meskipun\
|
||||
\ jika kondisi tersebut diubah."
|
||||
soft: "Lembut"
|
||||
hard: "Keras"
|
||||
mutedNotes: "Catatan yang dibisukan"
|
||||
_instanceMute:
|
||||
instanceMuteDescription: "Pengaturan ini akan membisukan note/renote apa saja dari instansi yang terdaftar, termasuk pengguna yang membalas pengguna lain dalam instansi yang dibisukan."
|
||||
instanceMuteDescription: "Pengaturan ini akan membisukan note/renote apa saja dari\
|
||||
\ instansi yang terdaftar, termasuk pengguna yang membalas pengguna lain dalam\
|
||||
\ instansi yang dibisukan."
|
||||
instanceMuteDescription2: "Pisah dengan baris baru"
|
||||
title: "Sembunyikan note dari instansi terdaftar."
|
||||
heading: "Daftar instansi yang akan dibisukan"
|
||||
|
@ -1043,7 +1145,8 @@ _theme:
|
|||
darken: "Mengelamkan"
|
||||
lighten: "Menerangkan"
|
||||
inputConstantName: "Masukkan nama untuk konstanta"
|
||||
importInfo: "Jika kamu memasukkan kode tema disini, kamu dapat mengimpornya ke penyunting tema"
|
||||
importInfo: "Jika kamu memasukkan kode tema disini, kamu dapat mengimpornya ke penyunting\
|
||||
\ tema"
|
||||
deleteConstantConfirm: "apakah kamu ingin menghapus konstanta {const}?"
|
||||
keys:
|
||||
accent: "Aksen"
|
||||
|
@ -1115,36 +1218,56 @@ _time:
|
|||
_tutorial:
|
||||
title: "Cara menggunakan Misskey"
|
||||
step1_1: "Selamat datang!"
|
||||
step1_2: "Halaman ini disebut \"linimasa\". Halaman ini menampilkan \"catatan\" yang diurutkan secara kronologis dari orang-orang yang kamu \"ikuti\"."
|
||||
step1_3: "Linimasa kamu kosong, karena kamu belum mencatat catatan apapun atau mengikuti siapapun."
|
||||
step2_1: "Selesaikan menyetel profilmu sebelum menulis sebuah catatan atau mengikuti seseorang."
|
||||
step2_2: "Menyediakan beberapa informasi tentang siapa kamu akan membuat orang lain mudah untuk mengikutimu kembali."
|
||||
step3_1: "Selesai menyetel profil kamu?"
|
||||
step3_2: "Langkah selanjutnya adalah membuat catatan. Kamu bisa lakukan ini dengan mengklik ikon pensil pada layar kamu."
|
||||
step3_3: "Isilah di dalam modal dan tekan tombol pada atas kanan untuk memcatat catatan kamu."
|
||||
step3_4: "Bingung tidak berpikiran untuk mengatakan sesuatu? Coba saja \"baru aja ikutan bikin akun misskey punyaku\"!"
|
||||
step1_2: "Halaman ini disebut \"linimasa\". Halaman ini menampilkan \"catatan\"\
|
||||
\ yang diurutkan secara kronologis dari orang-orang yang kamu \"ikuti\"."
|
||||
step1_3: "Linimasa kamu kosong, karena kamu belum mencatat catatan apapun atau mengikuti\
|
||||
\ siapapun."
|
||||
step2_1: "Selesaikan menyetel profilmu sebelum menulis sebuah catatan atau mengikuti\
|
||||
\ seseorang."
|
||||
step2_2: "Menyediakan beberapa informasi tentang siapa kamu akan membuat orang lain\
|
||||
\ mudah untuk mengikutimu kembali."
|
||||
step3_1: "Sekarang saatnya mengikuti beberapa orang!"
|
||||
step3_2: "Langkah selanjutnya adalah membuat catatan. Kamu bisa lakukan ini dengan\
|
||||
\ mengklik ikon pensil pada layar kamu."
|
||||
step3_3: "Isilah di dalam modal dan tekan tombol pada atas kanan untuk memcatat\
|
||||
\ catatan kamu."
|
||||
step3_4: "Bingung tidak berpikiran untuk mengatakan sesuatu? Coba saja \"baru aja\
|
||||
\ ikutan bikin akun misskey punyaku\"!"
|
||||
step4_1: "Selesai mencatat catatan pertamamu?"
|
||||
step4_2: "Horee! Sekarang catatan pertamamu sudah ditampilkan di linimasa milikmu."
|
||||
step5_1: "Sekarang, mari mencoba untuk membuat linimasamu lebih hidup dengan mengikuti orang lain."
|
||||
step5_2: "{featured} akan memperlihatkan catatan yang sedang tren saat ini untuk kamu. {explore} akan membantumu untuk mencari pengguna yang sedang tren juga saat ini. Coba ikuti seseorang yang kamu suka!"
|
||||
step5_3: "Untuk mengikuti pengguna lain, klik pada ikon mereka dan tekan tombol follow pada profil mereka."
|
||||
step5_4: "Jika pengguna lain memiliki ikon gembok di sebelah nama mereka, maka pengguna rersebut harus menyetujui permintaan mengikuti dari kamu secara manual."
|
||||
step5_1: "Sekarang, mari mencoba untuk membuat linimasamu lebih hidup dengan mengikuti\
|
||||
\ orang lain."
|
||||
step5_2: "{featured} akan memperlihatkan catatan yang sedang tren saat ini untuk\
|
||||
\ kamu. {explore} akan membantumu untuk mencari pengguna yang sedang tren juga\
|
||||
\ saat ini. Coba ikuti seseorang yang kamu suka!"
|
||||
step5_3: "Untuk mengikuti pengguna lain, klik pada ikon mereka dan tekan tombol\
|
||||
\ follow pada profil mereka."
|
||||
step5_4: "Jika pengguna lain memiliki ikon gembok di sebelah nama mereka, maka pengguna\
|
||||
\ rersebut harus menyetujui permintaan mengikuti dari kamu secara manual."
|
||||
step6_1: "Sekarang kamu dapat melihat catatan pengguna lain pada linimasamu."
|
||||
step6_2: "Kamu juga bisa memberikan \"reaksi\" ke catatan orang lain untuk merespon dengan cepat."
|
||||
step6_3: "Untuk memberikan \"reaksi\", tekan tanda \"+\" pada catatan pengguna lain dan pilih emoji yang kamu suka untuk memberikan reaksimu kepada mereka."
|
||||
step6_2: "Kamu juga bisa memberikan \"reaksi\" ke catatan orang lain untuk merespon\
|
||||
\ dengan cepat."
|
||||
step6_3: "Untuk memberikan \"reaksi\", tekan tanda \"+\" pada catatan pengguna lain\
|
||||
\ dan pilih emoji yang kamu suka untuk memberikan reaksimu kepada mereka."
|
||||
step7_1: "Yay, Selamat! Kamu sudah menyelesaikan tutorial dasar Misskey."
|
||||
step7_2: "Jika kamu ingin mempelajari lebih lanjut tentang Misskey, cobalah berkunjung ke bagian {help}."
|
||||
step7_3: "Semoga berhasil dan bersenang-senanglah! 🚀"
|
||||
step7_2: "Jika kamu ingin mempelajari lebih lanjut tentang Misskey, cobalah berkunjung\
|
||||
\ ke bagian {help}."
|
||||
step7_3: "Semoga berhasil dan bersenang-senanglah! \U0001F680"
|
||||
_2fa:
|
||||
alreadyRegistered: "Kamu telah mendaftarkan perangkat otentikasi dua faktor."
|
||||
registerDevice: "Daftarkan perangkat baru"
|
||||
registerKey: "Daftarkan kunci keamanan baru"
|
||||
step1: "Pertama, pasang aplikasi otentikasi (seperti {a} atau {b}) di perangkat kamu."
|
||||
step1: "Pertama, pasang aplikasi otentikasi (seperti {a} atau {b}) di perangkat\
|
||||
\ kamu."
|
||||
step2: "Lalu, pindai kode QR yang ada di layar."
|
||||
step2Url: "Di aplikasi desktop, masukkan URL berikut:"
|
||||
step3: "Masukkan token yang telah disediakan oleh aplikasimu untuk menyelesaikan pemasangan."
|
||||
step4: "Mulai sekarang, upaya login apapun akan meminta token login dari aplikasi otentikasi kamu."
|
||||
securityKeyInfo: "Kamu dapat memasang otentikasi WebAuthN untuk mengamankan proses login lebih lanjut dengan tidak hanya perangkat keras kunci keamanan yang mendukung FIDO2, namun juga sidik jari atau otentikasi PIN pada perangkatmu."
|
||||
step3: "Masukkan token yang telah disediakan oleh aplikasimu untuk menyelesaikan\
|
||||
\ pemasangan."
|
||||
step4: "Mulai sekarang, upaya login apapun akan meminta token login dari aplikasi\
|
||||
\ otentikasi kamu."
|
||||
securityKeyInfo: "Kamu dapat memasang otentikasi WebAuthN untuk mengamankan proses\
|
||||
\ login lebih lanjut dengan tidak hanya perangkat keras kunci keamanan yang mendukung\
|
||||
\ FIDO2, namun juga sidik jari atau otentikasi PIN pada perangkatmu."
|
||||
_permissions:
|
||||
"read:account": "Lihat informasi akun"
|
||||
"write:account": "Sunting informasi akun"
|
||||
|
@ -1180,7 +1303,8 @@ _permissions:
|
|||
"write:gallery-likes": "Sunting daftar postingan galeri yang disukai"
|
||||
_auth:
|
||||
shareAccess: "Apakah kamu ingin mengijinkan \"{name}\" untuk mengakses akun ini?"
|
||||
shareAccessAsk: "Apakah kamu ingin mengijinkan aplikasi ini untuk mengakses akun kamu?"
|
||||
shareAccessAsk: "Apakah kamu ingin mengijinkan aplikasi ini untuk mengakses akun\
|
||||
\ kamu?"
|
||||
permissionAsk: "Aplikasi ini membutuhkan beberapa ijin, yaitu:"
|
||||
pleaseGoBack: "Mohon kembali ke aplikasi kamu"
|
||||
callback: "Mengembalikan kamu ke aplikasi"
|
||||
|
@ -1275,7 +1399,8 @@ _profile:
|
|||
youCanIncludeHashtags: "Kamu juga dapat menambahkan tagar ke dalam bio."
|
||||
metadata: "Informasi tambahan"
|
||||
metadataEdit: "Sunting informasi tambahan"
|
||||
metadataDescription: "Kamu dapat menampilkan hingga 4 bagian informasi tambahan ke dalam profilmu."
|
||||
metadataDescription: "Kamu dapat menampilkan hingga 4 bagian informasi tambahan\
|
||||
\ ke dalam profilmu."
|
||||
metadataLabel: "Label"
|
||||
metadataContent: "Isi"
|
||||
changeAvatar: "Ubah avatar"
|
||||
|
@ -1596,7 +1721,8 @@ _pages:
|
|||
_for:
|
||||
arg1: "Jumlah angka untuk diulangi"
|
||||
arg2: "Aksi"
|
||||
typeError: "Slot {slot} menerima tipe \"{expect}\", sayangnya nilai yang disediakan adalah \"{actual}\"!"
|
||||
typeError: "Slot {slot} menerima tipe \"{expect}\", sayangnya nilai yang disediakan\
|
||||
\ adalah \"{actual}\"!"
|
||||
thereIsEmptySlot: "Slot {slot} kosong!"
|
||||
types:
|
||||
string: "Teks"
|
||||
|
|
|
@ -973,6 +973,8 @@ customKaTeXMacroDescription: "数式入力を楽にするためのマクロを
|
|||
name}{content} または \\newcommand{\\add}[2]{#1 + #2} のように記述します。後者の例では \\add{3}{foo}\
|
||||
\ が 3 + foo に展開されます。また、マクロの名前を囲む波括弧を丸括弧 () および角括弧 [] に変更した場合、マクロの引数に使用する括弧が変更されます。マクロの定義は一行に一つのみで、途中で改行はできません。マクロの定義が無効な行は無視されます。文字列を単純に置換する機能のみに対応していて、条件分岐などの高度な構文は使用できません。"
|
||||
enableCustomKaTeXMacro: "カスタムKaTeXマクロを有効にする"
|
||||
preventAiLearning: "AIによる学習を防止"
|
||||
preventAiLearningDescription: "投稿したノート、添付した画像などのコンテンツを学習の対象にしないようAIに要求します。これはnoaiフラグをHTMLレスポンスに含めることによって実現されます。"
|
||||
|
||||
_sensitiveMediaDetection:
|
||||
description: "機械学習を使って自動でセンシティブなメディアを検出し、モデレーションに役立てられます。サーバーの負荷が少し増えます。"
|
||||
|
@ -1837,23 +1839,7 @@ _deck:
|
|||
list: "リスト"
|
||||
mentions: "あなた宛て"
|
||||
direct: "ダイレクト"
|
||||
_apps:
|
||||
apps: "アプリ"
|
||||
crossPlatform: "クロスプラットフォーム"
|
||||
mobile: "モバイル"
|
||||
firstParty: "ファーストパーティ"
|
||||
firstClass: "対応度◎"
|
||||
secondClass: "対応度○"
|
||||
thirdClass: "対応度△"
|
||||
free: "無料"
|
||||
paid: "有料"
|
||||
pwa: "PWAをインストール"
|
||||
kaiteki: "Kaiteki"
|
||||
milktea: "Milktea"
|
||||
missLi: "MissLi"
|
||||
mona: "Mona"
|
||||
theDesk: "TheDesk"
|
||||
lesskey: "Lesskey"
|
||||
noteId: 投稿のID
|
||||
hiddenTagsDescription: 'トレンドと「みつける」から除外したいハッシュタグを(先頭の # を除いて)改行区切りで入力してください。この設定はトレンドと「みつける」以外には影響しません。'
|
||||
hiddenTags: 非表示にするハッシュタグ
|
||||
apps: "アプリ"
|
||||
|
|
|
@ -66,8 +66,8 @@ import: "Importuj"
|
|||
export: "Eksportuj"
|
||||
files: "Pliki"
|
||||
download: "Pobierz"
|
||||
driveFileDeleteConfirm: "Czy chcesz usunąć plik \"{name}\"? Zniknie również wpis,\
|
||||
\ do której dołączony jest ten plik."
|
||||
driveFileDeleteConfirm: "Czy chcesz usunąć plik \"{name}\"? Wszystkie wpisy zawierające\
|
||||
\ ten plik również zostaną usunięte."
|
||||
unfollowConfirm: "Czy na pewno chcesz przestać obserwować {name}?"
|
||||
exportRequested: "Zażądałeś eksportu. Może to zająć chwilę. Po zakończeniu eksportu\
|
||||
\ zostanie on dodany do Twojego dysku."
|
||||
|
@ -787,7 +787,7 @@ active: "Aktywny"
|
|||
offline: "Offline"
|
||||
notRecommended: "Nie zalecane"
|
||||
botProtection: "Zabezpieczenie przed botami"
|
||||
instanceBlocking: "Zablokowane instancje"
|
||||
instanceBlocking: "Zablokowane/wyciszone instancje"
|
||||
selectAccount: "Wybierz konto"
|
||||
switchAccount: "Przełącz konto"
|
||||
enabled: "Właczono"
|
||||
|
@ -1075,6 +1075,14 @@ _mfm:
|
|||
inlineMath: Matematyka (Inline)
|
||||
inlineMathDescription: Pokaż formuły matematyczne (KaTeX) w linii
|
||||
blockMathDescription: Pokaż wieloliniowe formuły matematyczne (KaTeX) w bloku
|
||||
background: Kolor tła
|
||||
backgroundDescription: Zmień kolor tła tekstu.
|
||||
foregroundDescription: Zmień kolor pierwszoplanowy tekstu.
|
||||
positionDescription: Przesuń treść o określoną odległość.
|
||||
position: Pozycjonuj
|
||||
foreground: Kolor pierwszoplanowy
|
||||
scaleDescription: Skaluj treść o określoną wielkość.
|
||||
scale: Skaluj
|
||||
_instanceTicker:
|
||||
none: "Nigdy nie pokazuj"
|
||||
remote: "Pokaż dla zdalnych użytkowników"
|
||||
|
@ -1094,6 +1102,8 @@ _channel:
|
|||
following: "Śledzeni"
|
||||
usersCount: "{n} uczestnicy"
|
||||
notesCount: "{n} wpisy"
|
||||
nameAndDescription: Nazwa i opis
|
||||
nameOnly: Tylko nazwa
|
||||
_menuDisplay:
|
||||
top: "Góra"
|
||||
hide: "Ukryj"
|
||||
|
@ -1222,13 +1232,13 @@ _tutorial:
|
|||
step2_1: "Najpierw, proszę wypełnij swój profil."
|
||||
step2_2: "Podanie kilku informacji o tym, kim jesteś, ułatwi innym stwierdzenie,\
|
||||
\ czy chcą zobaczyć Twoje wpisy lub śledzić Cię."
|
||||
step3_1: "Teraz czas na śledzenie niektórych osób!"
|
||||
step3_1: "Pora znaleźć osoby do śledzenia!"
|
||||
step3_2: "Twoje domowe i społeczne linie czasu opierają się na tym, kogo śledzisz,\
|
||||
\ więc spróbuj śledzić kilka kont, aby zacząć.\nKliknij kółko z plusem w prawym\
|
||||
\ górnym rogu profilu, aby go śledzić."
|
||||
step4_1: "Pozwól, że zabierzemy Cię tam."
|
||||
step4_2: "Dla twojego pierwszego postu, niektórzy ludzie lubią zrobić {introduction}\
|
||||
\ post lub prosty \"Hello world!\""
|
||||
step4_2: "W pierwszym wpisie możesz się przedstawić lub wysłać powitanie - \"Witaj,\
|
||||
\ świecie!\""
|
||||
step5_1: "Osie czasu, wszędzie widzę osie czasu!"
|
||||
step5_2: "Twoja instancja ma włączone {timelines} różne osie czasu."
|
||||
step5_3: "Główna {icon} oś czasu to miejsce, w którym możesz zobaczyć posty od użytkowników\
|
||||
|
@ -1811,8 +1821,8 @@ privateMode: Tryb prywatny
|
|||
allowedInstances: Dopuszczone instancje
|
||||
recommended: Polecane
|
||||
allowedInstancesDescription: Hosty instancji które mają być dopuszczone do federacji,
|
||||
każda separowana nową linią (dotyczy tylko trybu prywatnego).
|
||||
seperateRenoteQuote: Oddziel przyciski podbicia i cytatów
|
||||
każdy separowany nową linią (dotyczy tylko trybu prywatnego).
|
||||
seperateRenoteQuote: Oddziel przyciski podbicia i cytowania
|
||||
refreshInterval: 'Częstotliwość aktualizacji '
|
||||
slow: Wolna
|
||||
_messaging:
|
||||
|
@ -1845,10 +1855,10 @@ swipeOnDesktop: Zezwól na przeciąganie w stylu mobilnym na desktopie
|
|||
moveFromDescription: To utworzy alias twojego starego konta, w celu umożliwienia migracji
|
||||
z tamtego konta na to. Zrób to ZANIM rozpoczniesz przenoszenie się z tamtego konta.
|
||||
Proszę wpisz tag konta w formacie @person@instance.com
|
||||
migrationConfirm: "Czy jesteś na 200% pewn* tego, że chcesz przenieść swoje konto\
|
||||
\ na {account}? Gdy to zrobisz, odwrócenie tego będzie nie możliwe, i nie będziesz\
|
||||
\ w stanie ponownie używać normalnie z tego konta.\nUpewnij się, że to konto zostało\
|
||||
\ ustawione jako konto z którego się przenosisz."
|
||||
migrationConfirm: "Czy jesteś absolutnie pewn* tego, że chcesz przenieść swoje konto\
|
||||
\ na {account}? Tego działania nie można odwrócić. Nieodwracalnie stracisz możliwość\
|
||||
\ normalnego korzystania z konta.\nUpewnij się, że to konto zostało ustawione jako\
|
||||
\ konto z którego się przenosisz."
|
||||
noThankYou: Nie, dziękuję
|
||||
addInstance: Dodaj instancję
|
||||
renoteMute: Wycisz podbicia
|
||||
|
@ -1894,25 +1904,9 @@ indexNotice: Indeksuję. Zapewne zajmie to chwilę, nie restartuj serwera przez
|
|||
customKaTeXMacro: Niestandardowe makra KaTeX
|
||||
enableCustomKaTeXMacro: Włącz niestandardowe makra KaTeX
|
||||
noteId: ID wpisu
|
||||
_apps:
|
||||
apps: Aplikacje
|
||||
crossPlatform: Wieloplatformowe
|
||||
mobile: Mobilne
|
||||
firstParty: Oficjalne
|
||||
firstClass: Pierwszej klasy
|
||||
secondClass: Drugiej klasy
|
||||
thirdClass: Trzeciej klasy
|
||||
free: Darmowe
|
||||
paid: Płatne
|
||||
pwa: Zainstaluj PWA
|
||||
kaiteki: Kaiteki
|
||||
milktea: Milktea
|
||||
missLi: MissLi
|
||||
mona: Mona
|
||||
theDesk: TheDesk
|
||||
lesskey: Lesskey
|
||||
hiddenTagsDescription: 'Wypisz tagi (bez #) hashtagów które masz zamiar ukryć z "Na
|
||||
czasie" i "Eksploruj". Na ukryte hashtagi można dalej wejść innymi sposobami.'
|
||||
czasie" i "Eksploruj". Na ukryte hashtagi można dalej wejść innymi sposobami. Ta
|
||||
lista nie ma wpływu na zablokowane instancje.'
|
||||
proxyAccountDescription: Konto proxy jest kontem które w określonych sytuacjach zachowuje
|
||||
się jak zdalny obserwujący. Na przykład, kiedy użytkownik dodaje zdalnego użytkownika
|
||||
do listy, oraz żaden lokalny użytkownik nie obserwuje tego konta, aktywność owego
|
||||
|
@ -1927,7 +1921,7 @@ sendErrorReportsDescription: "Gdy ta opcja jest włączona, szczegółowe inform
|
|||
\ Calckey.\nZawrze to informacje takie jak wersja twojego systemu operacyjnego,\
|
||||
\ przeglądarki, Twoja aktywność na Calckey itd."
|
||||
privateModeInfo: Jeśli włączone, tylko dopuszczone instancje będą mogły federować
|
||||
z Twoją instancją. Wszystkie posty będą ukryte przed publiką.
|
||||
z Twoją instancją. Wszystkie posty będą jedynie widoczne na Twojej instancji.
|
||||
oneHour: Godzina
|
||||
oneDay: Dzień
|
||||
oneWeek: Tydzień
|
||||
|
@ -1999,3 +1993,23 @@ themeColor: Kolor znacznika instancji
|
|||
instanceDefaultLightTheme: Domyślny jasny motyw instancji
|
||||
enableEmojiReactions: Włącz reakcje emoji
|
||||
showEmojisInReactionNotifications: Pokazuj emoji w powiadomieniach reakcyjnych
|
||||
apps: Aplikacje
|
||||
silenceThisInstance: Wycisz tę instancję
|
||||
silencedInstances: Wyciszone instancje
|
||||
deleted: Usunięte
|
||||
editNote: Edytuj wpis
|
||||
edited: Edytowany
|
||||
silenced: Wyciszony
|
||||
findOtherInstance: Znajdź inny serwer
|
||||
userSaysSomethingReasonReply: '{name} odpowiedział na wpis zawierający {reason}'
|
||||
userSaysSomethingReasonRenote: '{name} podbił post zawierający {reason}'
|
||||
signupsDisabled: Rejestracja na tym serwerze jest obecnie zamknięta, ale zawsze możesz
|
||||
się zapisać na innym! Jeśli masz kod zaproszeniowy na ten serwer, wpisz go poniżej.
|
||||
userSaysSomethingReasonQuote: '{name} zacytował wpis zawierający {reason}'
|
||||
silencedInstancesDescription: Wymień nazwy domenowe instancji, które chcesz wyciszyć.
|
||||
Profile w wyciszonych instancjach są traktowane jako "Wyciszony", mogą jedynie wysyłać
|
||||
prośby obserwacji, i nie mogą oznaczać w wzmiankach profili lokalnych jeśli nie
|
||||
są obserwowane. To nie będzie miało wpływu na zablokowane instancje.
|
||||
cannotUploadBecauseExceedsFileSizeLimit: Ten plik nie mógł być przesłany, ponieważ
|
||||
jego wielkość przekracza dozwolony limit.
|
||||
sendModMail: Wyślij Powiadomienie Moderacyjne
|
||||
|
|
|
@ -1937,23 +1937,6 @@ _preferencesBackups:
|
|||
cannotLoad: Загрузка не удалась
|
||||
invalidFile: Неправильный формат файла
|
||||
enableEmojiReactions: Включить эмодзи реакции
|
||||
_apps:
|
||||
paid: Платные
|
||||
lesskey: Lesskey
|
||||
pwa: Установить PWA
|
||||
free: Бесплатные
|
||||
apps: Приложения
|
||||
crossPlatform: Кроссплатформенные
|
||||
mobile: Мобильные
|
||||
firstParty: От разработчиков
|
||||
firstClass: Первый класс
|
||||
thirdClass: Третий класс
|
||||
kaiteki: Kaiteki
|
||||
milktea: Milktea
|
||||
missLi: MissLi
|
||||
mona: Mona
|
||||
theDesk: TheDesk
|
||||
secondClass: Второй класс
|
||||
migrationConfirm: "Вы абсолютно уверены что хотите мигрировать ваш аккаунт на {account}?\
|
||||
\ Как только вы сделаете, вы не сможете отменить это и не сможете нормально использовать\
|
||||
\ аккаунт снова.\nТакже, пожалуйста, убедитесь, что вы установили эту текущую учетную\
|
||||
|
@ -2000,3 +1983,4 @@ customKaTeXMacroDescription: 'Настройте макросы чтобы ле
|
|||
ветвление, здесь использоваться не может.'
|
||||
cannotUploadBecauseExceedsFileSizeLimit: Этот файл не может быть загружен так как
|
||||
он превышает максимально разрешённый размер.
|
||||
apps: Приложения
|
||||
|
|
|
@ -1790,10 +1790,6 @@ moveAccountDescription: '這個過程是不可逆的。 在遷移前,請確保
|
|||
moveFrom: 由舊帳戶移至此帳戶
|
||||
moveFromDescription: '這將為你的舊帳戶設置一個別名(Alias),以便你可以從該帳戶轉移到當前帳戶。 在你的舊帳戶移動之前請執行此操作。 請輸入帳戶標籤
|
||||
(格式: @person@instance.com)'
|
||||
_apps:
|
||||
crossPlatform: 跨平台
|
||||
free: 免費
|
||||
paid: 付費
|
||||
enableEmojiReactions: 啟用表情符號反應
|
||||
breakFollowConfirm: 您確定要移除該關注者嗎?
|
||||
socialTimeline: 社交時間軸
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "calckey",
|
||||
"version": "14.0.0-dev3",
|
||||
"version": "14.0.0-dev10",
|
||||
"codename": "aqua",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://codeberg.org/calckey/calckey.git"
|
||||
},
|
||||
"packageManager": "pnpm@8.3.1",
|
||||
"packageManager": "pnpm@8.5.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"rebuild": "pnpm run clean && pnpm -r run build && pnpm run gulp",
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
<!-- needed for adaptive design -->
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
|
||||
|
||||
<!--
|
||||
ReDoc doesn't change outer page styles
|
||||
|
|
|
@ -4,10 +4,10 @@ export class AddSomeUrls1557761316509 {
|
|||
`ALTER TABLE "meta" ADD "ToSUrl" character varying(512)`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "meta" ADD "repositoryUrl" character varying(512) NOT NULL DEFAULT 'https://github.com/misskey-dev/misskey'`,
|
||||
`ALTER TABLE "meta" ADD "repositoryUrl" character varying(512) NOT NULL DEFAULT 'https://codeberg.org/calckey/calckey'`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "meta" ADD "feedbackUrl" character varying(512) DEFAULT 'https://github.com/misskey-dev/misskey/issues/new'`,
|
||||
`ALTER TABLE "meta" ADD "feedbackUrl" character varying(512) DEFAULT 'https://codeberg.org/calckey/calckey/issues'`,
|
||||
);
|
||||
}
|
||||
async down(queryRunner) {
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
export class PreventAiLearning1683682889948 {
|
||||
name = "PreventAiLearning1683682889948";
|
||||
|
||||
async up(queryRunner) {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "user_profile" ADD "preventAiLearning" boolean NOT NULL DEFAULT true`,
|
||||
);
|
||||
}
|
||||
|
||||
async down(queryRunner) {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "user_profile" DROP COLUMN "preventAiLearning"`,
|
||||
);
|
||||
}
|
||||
}
|
|
@ -37,6 +37,7 @@
|
|||
"@sinonjs/fake-timers": "9.1.2",
|
||||
"@syuilo/aiscript": "0.11.1",
|
||||
"@tensorflow/tfjs": "^4.2.0",
|
||||
"adm-zip": "^0.5.10",
|
||||
"ajv": "8.11.2",
|
||||
"archiver": "5.3.1",
|
||||
"argon2": "^0.30.3",
|
||||
|
@ -126,7 +127,6 @@
|
|||
"twemoji-parser": "14.0.0",
|
||||
"typeorm": "0.3.11",
|
||||
"ulid": "2.3.0",
|
||||
"unzipper": "0.10.11",
|
||||
"uuid": "9.0.0",
|
||||
"web-push": "3.5.0",
|
||||
"websocket": "1.0.34",
|
||||
|
@ -135,6 +135,7 @@
|
|||
"devDependencies": {
|
||||
"@swc/cli": "^0.1.62",
|
||||
"@swc/core": "^1.3.50",
|
||||
"@types/adm-zip": "^0.5.0",
|
||||
"@types/bcryptjs": "2.4.2",
|
||||
"@types/bull": "3.15.9",
|
||||
"@types/cbor": "6.0.0",
|
||||
|
|
|
@ -154,6 +154,11 @@ export class UserProfile {
|
|||
})
|
||||
public noCrawle: boolean;
|
||||
|
||||
@Column('boolean', {
|
||||
default: true,
|
||||
})
|
||||
public preventAiLearning: boolean;
|
||||
|
||||
@Column('boolean', {
|
||||
default: false,
|
||||
})
|
||||
|
|
|
@ -535,6 +535,7 @@ export const UserRepository = db.getRepository(User).extend({
|
|||
carefulBot: profile!.carefulBot,
|
||||
autoAcceptFollowed: profile!.autoAcceptFollowed,
|
||||
noCrawle: profile!.noCrawle,
|
||||
preventAiLearning: profile!.preventAiLearning,
|
||||
isExplorable: user.isExplorable,
|
||||
isDeleted: user.isDeleted,
|
||||
hideOnlineStatus: user.hideOnlineStatus,
|
||||
|
|
|
@ -394,6 +394,11 @@ export const packedMeDetailedOnlySchema = {
|
|||
nullable: true,
|
||||
optional: false,
|
||||
},
|
||||
preventAiLearning: {
|
||||
type: "boolean",
|
||||
nullable: true,
|
||||
optional: false,
|
||||
},
|
||||
isExplorable: {
|
||||
type: "boolean",
|
||||
nullable: false,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import type Bull from "bull";
|
||||
import * as fs from "node:fs";
|
||||
import unzipper from "unzipper";
|
||||
import AdmZip from "adm-zip";
|
||||
|
||||
import { queueLogger } from "../../logger.js";
|
||||
import { createTempDir } from "@/misc/create-temp.js";
|
||||
|
@ -47,8 +47,9 @@ export async function importCustomEmojis(
|
|||
|
||||
const outputPath = `${path}/emojis`;
|
||||
const unzipStream = fs.createReadStream(destPath);
|
||||
const extractor = unzipper.Extract({ path: outputPath });
|
||||
extractor.on("close", async () => {
|
||||
const zip = new AdmZip(destPath);
|
||||
zip.extractAllToAsync(outputPath, true, false, async (error) => {
|
||||
if (error) throw error;
|
||||
const metaRaw = fs.readFileSync(`${outputPath}/meta.json`, "utf-8");
|
||||
const meta = JSON.parse(metaRaw);
|
||||
|
||||
|
@ -86,6 +87,5 @@ export async function importCustomEmojis(
|
|||
logger.succ("Imported");
|
||||
done();
|
||||
});
|
||||
unzipStream.pipe(extractor);
|
||||
logger.succ(`Unzipping to ${outputPath}`);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@ import type { DbUserImportPostsJobData } from "@/queue/types.js";
|
|||
import { queueLogger } from "../../logger.js";
|
||||
import type Bull from "bull";
|
||||
import { htmlToMfm } from "@/remote/activitypub/misc/html-to-mfm.js";
|
||||
import { resolveNote } from "@/remote/activitypub/models/note.js";
|
||||
import { Note } from "@/models/entities/note.js";
|
||||
|
||||
const logger = queueLogger.createSubLogger("import-posts");
|
||||
|
||||
|
@ -79,46 +81,49 @@ export async function importPosts(
|
|||
} else if (parsed instanceof Object) {
|
||||
logger.info("Parsing animal style posts");
|
||||
for (const post of parsed.orderedItems) {
|
||||
try {
|
||||
linenum++;
|
||||
if (post.object.inReplyTo != null) {
|
||||
continue;
|
||||
}
|
||||
if (post.directMessage) {
|
||||
continue;
|
||||
}
|
||||
if (job.data.signatureCheck) {
|
||||
if (!post.signature) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
let text;
|
||||
async () => {
|
||||
try {
|
||||
text = htmlToMfm(post.object.content, post.object.tag);
|
||||
} catch (e) {
|
||||
continue;
|
||||
}
|
||||
logger.info(`Posting[${linenum}] ...`);
|
||||
linenum++;
|
||||
let reply: Note | null = null;
|
||||
if (post.object.inReplyTo != null) {
|
||||
reply = await resolveNote(post.object.inReplyTo);
|
||||
}
|
||||
if (post.directMessage) {
|
||||
return;
|
||||
}
|
||||
if (job.data.signatureCheck) {
|
||||
if (!post.signature) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
let text;
|
||||
try {
|
||||
text = htmlToMfm(post.object.content, post.object.tag);
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
logger.info(`Posting[${linenum}] ...`);
|
||||
|
||||
const note = await create(user, {
|
||||
createdAt: new Date(post.object.published),
|
||||
files: undefined,
|
||||
poll: undefined,
|
||||
text: text || undefined,
|
||||
reply: null,
|
||||
renote: null,
|
||||
cw: post.sensitive,
|
||||
localOnly: false,
|
||||
visibility: "hidden",
|
||||
visibleUsers: [],
|
||||
channel: null,
|
||||
apMentions: new Array(0),
|
||||
apHashtags: undefined,
|
||||
apEmojis: undefined,
|
||||
});
|
||||
} catch (e) {
|
||||
logger.warn(`Error in line:${linenum} ${e}`);
|
||||
}
|
||||
const note = await create(user, {
|
||||
createdAt: new Date(post.object.published),
|
||||
files: undefined,
|
||||
poll: undefined,
|
||||
text: text || undefined,
|
||||
reply,
|
||||
renote: null,
|
||||
cw: post.sensitive,
|
||||
localOnly: false,
|
||||
visibility: "hidden",
|
||||
visibleUsers: [],
|
||||
channel: null,
|
||||
apMentions: new Array(0),
|
||||
apHashtags: undefined,
|
||||
apEmojis: undefined,
|
||||
});
|
||||
} catch (e) {
|
||||
logger.warn(`Error in line:${linenum} ${e}`);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
|
|
|
@ -16,7 +16,6 @@ export default async function renderNote(
|
|||
dive = true,
|
||||
isTalk = false,
|
||||
): Promise<Record<string, unknown>> {
|
||||
note.visibility = note.visibility === "hidden" ? "home" : note.visibility;
|
||||
const getPromisedFiles = async (ids: string[]) => {
|
||||
if (!ids || ids.length === 0) return [];
|
||||
const items = await DriveFiles.findBy({ id: In(ids) });
|
||||
|
|
|
@ -53,6 +53,7 @@ import * as ep___admin_resetPassword from "./endpoints/admin/reset-password.js";
|
|||
import * as ep___admin_resolveAbuseUserReport from "./endpoints/admin/resolve-abuse-user-report.js";
|
||||
import * as ep___admin_search_indexAll from "./endpoints/admin/search/index-all.js";
|
||||
import * as ep___admin_sendEmail from "./endpoints/admin/send-email.js";
|
||||
import * as ep___admin_sendModMail from "./endpoints/admin/send-mod-mail.js";
|
||||
import * as ep___admin_serverInfo from "./endpoints/admin/server-info.js";
|
||||
import * as ep___admin_showModerationLogs from "./endpoints/admin/show-moderation-logs.js";
|
||||
import * as ep___admin_showUser from "./endpoints/admin/show-user.js";
|
||||
|
@ -404,6 +405,7 @@ const eps = [
|
|||
["admin/resolve-abuse-user-report", ep___admin_resolveAbuseUserReport],
|
||||
["admin/search/index-all", ep___admin_search_indexAll],
|
||||
["admin/send-email", ep___admin_sendEmail],
|
||||
["admin/send-mod-mail", ep___admin_sendModMail],
|
||||
["admin/server-info", ep___admin_serverInfo],
|
||||
["admin/show-moderation-logs", ep___admin_showModerationLogs],
|
||||
["admin/show-user", ep___admin_showUser],
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
import * as sanitizeHtml from "sanitize-html";
|
||||
import define from "../../define.js";
|
||||
import { Users, UserProfiles } from "@/models/index.js";
|
||||
import { ApiError } from "../../error.js";
|
||||
import { sendEmail } from "@/services/send-email.js";
|
||||
import { createNotification } from "@/services/create-notification.js";
|
||||
|
||||
export const meta = {
|
||||
tags: ["users"],
|
||||
|
||||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
|
||||
description: "Send a moderation notice.",
|
||||
|
||||
errors: {
|
||||
noSuchUser: {
|
||||
message: "No such user.",
|
||||
code: "NO_SUCH_USER",
|
||||
id: "1acefcb5-0959-43fd-9685-b48305736cb5",
|
||||
},
|
||||
noEmail: {
|
||||
message: "No email for user.",
|
||||
code: "NO_EMAIL",
|
||||
id: "ac9d2d22-ef73-11ed-a05b-0242ac120003",
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: "object",
|
||||
properties: {
|
||||
userId: { type: "string", format: "misskey:id" },
|
||||
comment: { type: "string", minLength: 1, maxLength: 2048 },
|
||||
},
|
||||
required: ["userId", "comment"],
|
||||
} as const;
|
||||
|
||||
export default define(meta, paramDef, async (ps) => {
|
||||
const [user, profile] = await Promise.all([
|
||||
Users.findOneBy({ id: ps.userId }),
|
||||
UserProfiles.findOneBy({ userId: ps.userId }),
|
||||
]);
|
||||
|
||||
if (user == null || profile == null) {
|
||||
throw new ApiError(meta.errors.noSuchUser);
|
||||
}
|
||||
|
||||
createNotification(user.id, "app", {
|
||||
customBody: ps.comment,
|
||||
customHeader: "Moderation Notice",
|
||||
customIcon: "/static-assets/badges/info.png",
|
||||
});
|
||||
|
||||
setImmediate(async () => {
|
||||
const email = profile.email;
|
||||
if (email == null) {
|
||||
throw new ApiError(meta.errors.noEmail);
|
||||
}
|
||||
|
||||
sendEmail(
|
||||
email,
|
||||
"Moderation notice",
|
||||
sanitizeHtml(ps.comment),
|
||||
sanitizeHtml(ps.comment),
|
||||
);
|
||||
});
|
||||
});
|
|
@ -59,6 +59,7 @@ export default define(meta, paramDef, async (ps, me) => {
|
|||
emailVerified: profile.emailVerified,
|
||||
autoAcceptFollowed: profile.autoAcceptFollowed,
|
||||
noCrawle: profile.noCrawle,
|
||||
preventAiLearning: profile.preventAiLearning,
|
||||
alwaysMarkNsfw: profile.alwaysMarkNsfw,
|
||||
autoSensitive: profile.autoSensitive,
|
||||
carefulBot: profile.carefulBot,
|
||||
|
|
|
@ -102,6 +102,7 @@ export const paramDef = {
|
|||
carefulBot: { type: "boolean" },
|
||||
autoAcceptFollowed: { type: "boolean" },
|
||||
noCrawle: { type: "boolean" },
|
||||
preventAiLearning: { type: "boolean" },
|
||||
isBot: { type: "boolean" },
|
||||
isCat: { type: "boolean" },
|
||||
speakAsCat: { type: "boolean" },
|
||||
|
@ -191,6 +192,8 @@ export default define(meta, paramDef, async (ps, _user, token) => {
|
|||
if (typeof ps.autoAcceptFollowed === "boolean")
|
||||
profileUpdates.autoAcceptFollowed = ps.autoAcceptFollowed;
|
||||
if (typeof ps.noCrawle === "boolean") profileUpdates.noCrawle = ps.noCrawle;
|
||||
if (typeof ps.preventAiLearning === "boolean")
|
||||
profileUpdates.preventAiLearning = ps.preventAiLearning;
|
||||
if (typeof ps.isCat === "boolean") updates.isCat = ps.isCat;
|
||||
if (typeof ps.speakAsCat === "boolean") updates.speakAsCat = ps.speakAsCat;
|
||||
if (typeof ps.injectFeaturedNote === "boolean")
|
||||
|
|
|
@ -28,7 +28,7 @@ export const meta = {
|
|||
},
|
||||
userId: {
|
||||
type: "string",
|
||||
optional: false,
|
||||
optional: true,
|
||||
nullable: false,
|
||||
},
|
||||
endpoint: {
|
||||
|
|
|
@ -53,7 +53,7 @@ const nodeinfo2 = async () => {
|
|||
name: "calckey",
|
||||
version: config.version,
|
||||
repository: meta.repositoryUrl,
|
||||
homepage: "https://calckey.cloud",
|
||||
homepage: "https://calckey.org/",
|
||||
},
|
||||
protocols: ["activitypub"],
|
||||
services: {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
html, body {
|
||||
html {
|
||||
background-color: var(--bg);
|
||||
color: var(--fg);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,9 @@ block meta
|
|||
unless privateMode
|
||||
if profile.noCrawle
|
||||
meta(name='robots' content='noindex')
|
||||
if profile.preventAiLearning
|
||||
meta(name='robots' content='noai')
|
||||
meta(name='robots' content='noimageai')
|
||||
|
||||
meta(name='misskey:user-username' content=user.username)
|
||||
meta(name='misskey:user-id' content=user.id)
|
||||
|
|
|
@ -24,6 +24,9 @@ block meta
|
|||
unless privateMode
|
||||
if user.host || profile.noCrawle
|
||||
meta(name='robots' content='noindex')
|
||||
if profile.preventAiLearning
|
||||
meta(name='robots' content='noai')
|
||||
meta(name='robots' content='noimageai')
|
||||
|
||||
meta(name='misskey:user-username' content=user.username)
|
||||
meta(name='misskey:user-id' content=user.id)
|
||||
|
|
|
@ -36,6 +36,9 @@ block meta
|
|||
unless privateMode
|
||||
if user.host || isRenote || profile.noCrawle
|
||||
meta(name='robots' content='noindex')
|
||||
if profile.preventAiLearning
|
||||
meta(name='robots' content='noai')
|
||||
meta(name='robots' content='noimageai')
|
||||
|
||||
meta(name='misskey:user-username' content=user.username)
|
||||
meta(name='misskey:user-id' content=user.id)
|
||||
|
|
|
@ -24,6 +24,9 @@ block meta
|
|||
unless privateMode
|
||||
if profile.noCrawle
|
||||
meta(name='robots' content='noindex')
|
||||
if profile.preventAiLearning
|
||||
meta(name='robots' content='noai')
|
||||
meta(name='robots' content='noimageai')
|
||||
|
||||
meta(name='misskey:user-username' content=user.username)
|
||||
meta(name='misskey:user-id' content=user.id)
|
||||
|
|
|
@ -23,6 +23,9 @@ block meta
|
|||
unless privateMode
|
||||
if user.host || profile.noCrawle
|
||||
meta(name='robots' content='noindex')
|
||||
if profile.preventAiLearning
|
||||
meta(name='robots' content='noai')
|
||||
meta(name='robots' content='noimageai')
|
||||
|
||||
meta(name='misskey:user-username' content=user.username)
|
||||
meta(name='misskey:user-id' content=user.id)
|
||||
|
|
|
@ -80,6 +80,9 @@ export async function createNotification(
|
|||
setTimeout(async () => {
|
||||
const fresh = await Notifications.findOneBy({ id: notification.id });
|
||||
if (fresh == null) return; // 既に削除されているかもしれない
|
||||
// We execute this before, because the server side "read" check doesnt work well with push notifications, the app and service worker will decide themself
|
||||
// when it is best to show push notifications
|
||||
pushNotification(notifieeId, "notification", packed);
|
||||
if (fresh.isRead) return;
|
||||
|
||||
//#region ただしミュートしているユーザーからの通知なら無視
|
||||
|
@ -95,7 +98,6 @@ export async function createNotification(
|
|||
//#endregion
|
||||
|
||||
publishMainStream(notifieeId, "unreadNotification", packed);
|
||||
pushNotification(notifieeId, "notification", packed);
|
||||
|
||||
if (type === "follow")
|
||||
sendEmailNotification.follow(
|
||||
|
|
|
@ -170,6 +170,9 @@ export default async (
|
|||
) =>
|
||||
// rome-ignore lint/suspicious/noAsyncPromiseExecutor: FIXME
|
||||
new Promise<Note>(async (res, rej) => {
|
||||
const dontFederateInitially =
|
||||
data.localOnly || data.visibility === "hidden";
|
||||
|
||||
// If you reply outside the channel, match the scope of the target.
|
||||
// TODO (I think it's a process that could be done on the client side, but it's server side for now.)
|
||||
if (
|
||||
|
@ -196,6 +199,7 @@ export default async (
|
|||
if (data.channel != null) data.visibility = "public";
|
||||
if (data.channel != null) data.visibleUsers = [];
|
||||
if (data.channel != null) data.localOnly = true;
|
||||
if (data.visibility === "hidden") data.visibility = "public";
|
||||
|
||||
// enforce silent clients on server
|
||||
if (
|
||||
|
@ -447,7 +451,9 @@ export default async (
|
|||
}
|
||||
}
|
||||
|
||||
publishNotesStream(note);
|
||||
if (!dontFederateInitially) {
|
||||
publishNotesStream(note);
|
||||
}
|
||||
if (note.replyId != null) {
|
||||
// Only provide the reply note id here as the recipient may not be authorized to see the note.
|
||||
publishNoteStream(note.replyId, "replied", {
|
||||
|
@ -546,7 +552,7 @@ export default async (
|
|||
});
|
||||
|
||||
//#region AP deliver
|
||||
if (Users.isLocalUser(user)) {
|
||||
if (Users.isLocalUser(user) && !dontFederateInitially) {
|
||||
(async () => {
|
||||
const noteActivity = await renderNoteOrRenoteActivity(data, note);
|
||||
const dm = new DeliverManager(user, noteActivity);
|
||||
|
@ -606,7 +612,7 @@ export default async (
|
|||
});
|
||||
|
||||
async function renderNoteOrRenoteActivity(data: Option, note: Note) {
|
||||
if (data.localOnly || note.visibility !== "hidden") return null;
|
||||
if (data.localOnly) return null;
|
||||
|
||||
const content =
|
||||
data.renote &&
|
||||
|
|
|
@ -144,7 +144,11 @@ export default async (
|
|||
});
|
||||
|
||||
//#region deliver
|
||||
if (Users.isLocalUser(user) && !note.localOnly) {
|
||||
if (
|
||||
Users.isLocalUser(user) &&
|
||||
!note.localOnly &&
|
||||
note.visibility !== "hidden"
|
||||
) {
|
||||
const content = renderActivity(await renderLike(record, note));
|
||||
const dm = new DeliverManager(user, content);
|
||||
if (note.userHost !== null) {
|
||||
|
|
|
@ -45,21 +45,21 @@ export async function sendEmail(
|
|||
<title>${subject}</title>
|
||||
</head>
|
||||
<body style="background: #191724; padding: 16px; margin: 0; font-family: sans-serif; font-size: 14px;">
|
||||
<main style="max-width: 500px; margin: 0 auto; background: #1f1d2e; color: #e0def4;">
|
||||
<header style="padding: 32px; background: #31748f; display: flex;">
|
||||
<main style="max-width: 500px; margin: 0 auto; background: #1f1d2e; color: #e0def4; border-radius: 20px;">
|
||||
<header style="padding: 32px; background: #31748f; color: #e0def4; display: flex; border-radius: 20px;">
|
||||
<img src="${meta.logoImageUrl || meta.iconUrl || iconUrl}" style="max-width: 128px; max-height: 72px; vertical-align: bottom; margin-right: 16px;"/>
|
||||
<h1 style="margin: 0 0 1em 0;">${meta.name}</h1>
|
||||
</header>
|
||||
<article style="padding: 32px;">
|
||||
<h1>${subject}</h1>
|
||||
<div>${html}</div>
|
||||
<h1 style="color: #ebbcba !important;">${subject}</h1>
|
||||
<div style="color: #e0def4;">${html}</div>
|
||||
</article>
|
||||
<footer style="padding: 32px; border-top: solid 1px #26233a;">
|
||||
<a href="${emailSettingUrl}" style="color: #31748f !important;">${"Email setting"}</a>
|
||||
<a href="${emailSettingUrl}" style="color: #9ccfd8 !important;">${"Email Settings"}</a>
|
||||
</footer>
|
||||
</main>
|
||||
<nav style="box-sizing: border-box; max-width: 500px; margin: 16px auto 0 auto; padding: 0 32px;">
|
||||
<a href="${config.url}" style="color: #6e6a86 !important;">${config.host}</a>
|
||||
<a href="${config.url}" style="color: #9ccfd8 !important;">${config.host}</a>
|
||||
</nav>
|
||||
</body>
|
||||
</html>`,
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -55,33 +55,33 @@ describe("fromHtml", () => {
|
|||
|
||||
it("link with different text", () => {
|
||||
assert.deepStrictEqual(
|
||||
fromHtml('<p>a <a href="https://example.com/b">c</a> d</p>'),
|
||||
"a [c](https://example.com/b) d",
|
||||
fromHtml('<p>a <a href="https://calckey.org/b">c</a> d</p>'),
|
||||
"a [c](https://calckey.org/b) d",
|
||||
);
|
||||
});
|
||||
|
||||
it("link with different text, but not encoded", () => {
|
||||
assert.deepStrictEqual(
|
||||
fromHtml('<p>a <a href="https://example.com/ä">c</a> d</p>'),
|
||||
"a [c](<https://example.com/ä>) d",
|
||||
fromHtml('<p>a <a href="https://calckey.org/ä">c</a> d</p>'),
|
||||
"a [c](<https://calckey.org/ä>) d",
|
||||
);
|
||||
});
|
||||
|
||||
it("link with same text", () => {
|
||||
assert.deepStrictEqual(
|
||||
fromHtml(
|
||||
'<p>a <a href="https://example.com/b">https://example.com/b</a> d</p>',
|
||||
'<p>a <a href="https://calckey.org/b">https://calckey.org/b</a> d</p>',
|
||||
),
|
||||
"a https://example.com/b d",
|
||||
"a https://calckey.org/b d",
|
||||
);
|
||||
});
|
||||
|
||||
it("link with same text, but not encoded", () => {
|
||||
assert.deepStrictEqual(
|
||||
fromHtml(
|
||||
'<p>a <a href="https://example.com/ä">https://example.com/ä</a> d</p>',
|
||||
'<p>a <a href="https://calckey.org/ä">https://calckey.org/ä</a> d</p>',
|
||||
),
|
||||
"a <https://example.com/ä> d",
|
||||
"a <https://calckey.org/ä> d",
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -98,8 +98,8 @@ describe("fromHtml", () => {
|
|||
|
||||
it("link without text", () => {
|
||||
assert.deepStrictEqual(
|
||||
fromHtml('<p>a <a href="https://example.com/b"></a> d</p>'),
|
||||
"a https://example.com/b d",
|
||||
fromHtml('<p>a <a href="https://calckey.org/b"></a> d</p>'),
|
||||
"a https://calckey.org/b d",
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -110,15 +110,15 @@ describe("fromHtml", () => {
|
|||
it("mention", () => {
|
||||
assert.deepStrictEqual(
|
||||
fromHtml(
|
||||
'<p>a <a href="https://example.com/@user" class="u-url mention">@user</a> d</p>',
|
||||
'<p>a <a href="https://calckey.org/@user" class="u-url mention">@user</a> d</p>',
|
||||
),
|
||||
"a @user@example.com d",
|
||||
"a @user@calckey.org d",
|
||||
);
|
||||
});
|
||||
|
||||
it("hashtag", () => {
|
||||
assert.deepStrictEqual(
|
||||
fromHtml('<p>a <a href="https://example.com/tags/a">#a</a> d</p>', [
|
||||
fromHtml('<p>a <a href="https://calckey.org/tags/a">#a</a> d</p>', [
|
||||
"#a",
|
||||
]),
|
||||
"a #a d",
|
||||
|
|
|
@ -707,6 +707,7 @@ export type Endpoints = {
|
|||
carefulBot?: boolean;
|
||||
autoAcceptFollowed?: boolean;
|
||||
noCrawle?: boolean;
|
||||
preventAiLearning?: boolean;
|
||||
isBot?: boolean;
|
||||
isCat?: boolean;
|
||||
injectFeaturedNote?: boolean;
|
||||
|
|
|
@ -104,6 +104,7 @@ export type MeDetailed = UserDetailed & {
|
|||
mutedWords: string[][];
|
||||
mutingNotificationTypes: string[];
|
||||
noCrawle: boolean;
|
||||
preventAiLearning: boolean;
|
||||
receiveAnnouncementEmail: boolean;
|
||||
usePasswordLessLogin: boolean;
|
||||
[other: string]: any;
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@discordapp/twemoji": "14.0.2",
|
||||
"@khmyznikov/pwa-install": "^0.2.0",
|
||||
"@phosphor-icons/web": "^2.0.3",
|
||||
"@rollup/plugin-alias": "3.1.9",
|
||||
"@rollup/plugin-json": "4.1.0",
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<template #empty>
|
||||
<div class="_fullinfo">
|
||||
<img
|
||||
src="/static-assets/badges/info.png"
|
||||
src="/static-assets/badges/not-found.png"
|
||||
class="_ghost"
|
||||
:alt="i18n.ts.notFound"
|
||||
/>
|
||||
|
|
|
@ -144,6 +144,20 @@ export default defineComponent({
|
|||
padding: var(--x-padding);
|
||||
-webkit-backdrop-filter: var(--blur, blur(8px));
|
||||
backdrop-filter: var(--blur, blur(20px));
|
||||
margin-inline: -12px;
|
||||
padding-inline: 12px;
|
||||
mask: linear-gradient(
|
||||
to right,
|
||||
transparent,
|
||||
black 12px calc(100% - 12px),
|
||||
transparent
|
||||
);
|
||||
-webkit-mask: linear-gradient(
|
||||
to right,
|
||||
transparent,
|
||||
black 12px calc(100% - 12px),
|
||||
transparent
|
||||
);
|
||||
|
||||
> .title {
|
||||
margin: 0;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="mk-google">
|
||||
<div class="mk-google" @click.stop>
|
||||
<input v-model="query" type="search" :placeholder="q" />
|
||||
<button @click="search">
|
||||
<i class="ph-magnifying-glass ph-bold ph-lg"></i>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div v-if="hide" class="qjewsnkg" @click="hide = false">
|
||||
<button v-if="hide" class="qjewsnkg" @click="hide = false">
|
||||
<ImgWithBlurhash
|
||||
class="bg"
|
||||
:hash="image.blurhash"
|
||||
|
@ -15,7 +15,7 @@
|
|||
<span style="display: block">{{ i18n.ts.clickToShow }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
<div v-else class="gqnyydlz">
|
||||
<a :href="image.url" :title="image.name">
|
||||
<ImgWithBlurhash
|
||||
|
@ -79,6 +79,7 @@ watch(
|
|||
|
||||
<style lang="scss" scoped>
|
||||
.qjewsnkg {
|
||||
all: unset;
|
||||
position: relative;
|
||||
|
||||
> .bg {
|
||||
|
@ -103,6 +104,10 @@ watch(
|
|||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
border: 2px solid var(--accent);
|
||||
}
|
||||
}
|
||||
|
||||
.gqnyydlz {
|
||||
|
|
|
@ -188,6 +188,7 @@ const previewable = (file: misskey.entities.DriveFile): boolean => {
|
|||
margin-top: 4px;
|
||||
border-radius: var(--radius);
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
|
||||
&:before {
|
||||
content: "";
|
||||
|
@ -207,6 +208,7 @@ const previewable = (file: misskey.entities.DriveFile): boolean => {
|
|||
> * {
|
||||
overflow: hidden;
|
||||
border-radius: 6px;
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
&[data-count="1"] {
|
||||
|
|
|
@ -13,12 +13,6 @@
|
|||
>
|
||||
<template v-for="(item, i) in items2">
|
||||
<div v-if="item === null" class="divider"></div>
|
||||
<template
|
||||
v-else-if="
|
||||
item.hidden ||
|
||||
(item.visible !== undefined && !item.visible)
|
||||
"
|
||||
/>
|
||||
<span v-else-if="item.type === 'label'" class="label item">
|
||||
<span :style="item.textStyle || ''">{{
|
||||
item.text
|
||||
|
@ -27,7 +21,6 @@
|
|||
<span
|
||||
v-else-if="item.type === 'pending'"
|
||||
class="pending item"
|
||||
:class="classMap(item.classes)"
|
||||
>
|
||||
<span><MkEllipsis /></span>
|
||||
</span>
|
||||
|
@ -35,7 +28,6 @@
|
|||
v-else-if="item.type === 'link'"
|
||||
:to="item.to"
|
||||
class="_button item"
|
||||
:class="classMap(item.classes)"
|
||||
@click.passive="close(true)"
|
||||
@mouseenter.passive="onItemMouseEnter(item)"
|
||||
@mouseleave.passive="onItemMouseLeave(item)"
|
||||
|
@ -64,7 +56,6 @@
|
|||
:target="item.target"
|
||||
:download="item.download"
|
||||
class="_button item"
|
||||
:class="classMap(item.classes)"
|
||||
@click="close(true)"
|
||||
@mouseenter.passive="onItemMouseEnter(item)"
|
||||
@mouseleave.passive="onItemMouseLeave(item)"
|
||||
|
@ -82,12 +73,9 @@
|
|||
></span>
|
||||
</a>
|
||||
<button
|
||||
v-else-if="item.type === 'user'"
|
||||
v-else-if="item.type === 'user' && !items.hidden"
|
||||
class="_button item"
|
||||
:class="{
|
||||
active: item.active,
|
||||
...classMap(item.classes),
|
||||
}"
|
||||
:class="{ active: item.active }"
|
||||
:disabled="item.active"
|
||||
@click="clicked(item.action, $event)"
|
||||
@mouseenter.passive="onItemMouseEnter(item)"
|
||||
|
@ -105,7 +93,6 @@
|
|||
<span
|
||||
v-else-if="item.type === 'switch'"
|
||||
class="item"
|
||||
:class="classMap(item.classes)"
|
||||
@mouseenter.passive="onItemMouseEnter(item)"
|
||||
@mouseleave.passive="onItemMouseLeave(item)"
|
||||
>
|
||||
|
@ -117,29 +104,10 @@
|
|||
>{{ item.text }}</FormSwitch
|
||||
>
|
||||
</span>
|
||||
<span
|
||||
v-else-if="item.type === 'input'"
|
||||
:tabindex="i"
|
||||
class="item"
|
||||
:class="classMap(item.classes)"
|
||||
@mouseenter.passive="onItemMouseEnter(item)"
|
||||
@mouseleave.passive="onItemMouseLeave(item)"
|
||||
>
|
||||
<FormInput
|
||||
v-model="item.ref"
|
||||
:disabled="item.disabled"
|
||||
class="form-input"
|
||||
:required="item.required"
|
||||
:placeholder="item.placeholder"
|
||||
/>
|
||||
</span>
|
||||
<button
|
||||
v-else-if="item.type === 'parent'"
|
||||
class="_button item parent"
|
||||
:class="{
|
||||
childShowing: childShowingItem === item,
|
||||
...classMap(item.classes),
|
||||
}"
|
||||
:class="{ childShowing: childShowingItem === item }"
|
||||
@mouseenter="showChildren(item, $event)"
|
||||
@click="showChildren(item, $event)"
|
||||
>
|
||||
|
@ -158,13 +126,9 @@
|
|||
></span>
|
||||
</button>
|
||||
<button
|
||||
v-else
|
||||
v-else-if="!item.hidden"
|
||||
class="_button item"
|
||||
:class="{
|
||||
danger: item.danger,
|
||||
active: item.active,
|
||||
...classMap(item.classes),
|
||||
}"
|
||||
:class="{ danger: item.danger, active: item.active }"
|
||||
:disabled="item.active"
|
||||
@click="clicked(item.action, $event)"
|
||||
@mouseenter.passive="onItemMouseEnter(item)"
|
||||
|
@ -222,14 +186,7 @@ import {
|
|||
} from "vue";
|
||||
import { focusPrev, focusNext } from "@/scripts/focus";
|
||||
import FormSwitch from "@/components/form/switch.vue";
|
||||
import FormInput from "@/components/form/input.vue";
|
||||
import {
|
||||
MenuItem,
|
||||
InnerMenuItem,
|
||||
MenuPending,
|
||||
MenuAction,
|
||||
MenuClasses,
|
||||
} from "@/types/menu";
|
||||
import { MenuItem, InnerMenuItem, MenuPending, MenuAction } from "@/types/menu";
|
||||
import * as os from "@/os";
|
||||
import { i18n } from "@/i18n";
|
||||
import { FocusTrap } from "focus-trap-vue";
|
||||
|
@ -287,18 +244,6 @@ watch(
|
|||
let childMenu = $ref<MenuItem[] | null>();
|
||||
let childTarget = $ref<HTMLElement | null>();
|
||||
|
||||
function classMap(classes?: MenuClasses) {
|
||||
if (!classes) return {};
|
||||
|
||||
return (Array.isArray(classes) ? classes : classes.value).reduce(
|
||||
(acc, cls) => {
|
||||
acc[cls] = true;
|
||||
return acc;
|
||||
},
|
||||
{}
|
||||
);
|
||||
}
|
||||
|
||||
function closeChild() {
|
||||
childMenu = null;
|
||||
childShowingItem = null;
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
<div class="body">
|
||||
<MkSubNoteContent
|
||||
class="text"
|
||||
:note="note"
|
||||
:note="appearNote"
|
||||
:detailed="true"
|
||||
:detailedView="detailedView"
|
||||
:parentId="appearNote.parentId"
|
||||
|
@ -139,7 +139,6 @@
|
|||
class="button"
|
||||
:note="appearNote"
|
||||
:count="appearNote.renoteCount"
|
||||
:renoteCw="note.cw"
|
||||
/>
|
||||
<XStarButtonNoEmoji
|
||||
v-if="!enableEmojiReactions"
|
||||
|
@ -198,7 +197,7 @@
|
|||
</div>
|
||||
</article>
|
||||
</div>
|
||||
<div v-else class="muted" @click="muted.muted = false">
|
||||
<button v-else class="muted _button" @click="muted.muted = false">
|
||||
<I18n :src="softMuteReasonI18nSrc(muted.what)" tag="small">
|
||||
<template #name>
|
||||
<MkA
|
||||
|
@ -213,7 +212,7 @@
|
|||
<b class="_blur_text">{{ muted.matched.join(", ") }}</b>
|
||||
</template>
|
||||
</I18n>
|
||||
</div>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@ -748,5 +747,6 @@ function readPromo() {
|
|||
padding: 8px;
|
||||
text-align: center;
|
||||
opacity: 0.7;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<MkNoteSub
|
||||
v-for="note in conversation"
|
||||
:key="note.id"
|
||||
class="reply-to-more"
|
||||
class="reply-to"
|
||||
:note="note"
|
||||
/>
|
||||
<MkNoteSub
|
||||
|
@ -345,7 +345,7 @@ async function onNoteUpdated(noteData: NoteUpdatedEvent): Promise<void> {
|
|||
|
||||
replies.value.splice(found, 0, replyNote);
|
||||
if (found === 0) {
|
||||
directReplies.value.unshift(replyNote);
|
||||
directReplies.value.push(replyNote);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -414,15 +414,7 @@ onUnmounted(() => {
|
|||
}
|
||||
> .reply-to {
|
||||
margin-bottom: -16px;
|
||||
}
|
||||
|
||||
> .reply-to-more {
|
||||
// opacity: 0.7;
|
||||
cursor: pointer;
|
||||
|
||||
@media (pointer: coarse) {
|
||||
cursor: default;
|
||||
}
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
|
||||
> .renote {
|
||||
|
@ -478,16 +470,17 @@ onUnmounted(() => {
|
|||
|
||||
> .article {
|
||||
padding-block: 28px 6px;
|
||||
&:last-child {
|
||||
padding-bottom: 24px;
|
||||
}
|
||||
font-size: 1.1em;
|
||||
padding-top: 12px;
|
||||
font-size: 1.1rem;
|
||||
overflow: clip;
|
||||
outline: none;
|
||||
scroll-margin-top: calc(var(--stickyTop) + 20vh);
|
||||
:deep(.article) {
|
||||
cursor: unset;
|
||||
}
|
||||
&:first-of-type {
|
||||
padding-top: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
> .reply {
|
||||
|
@ -503,7 +496,6 @@ onUnmounted(() => {
|
|||
// Hover
|
||||
.reply :deep(.main),
|
||||
.reply-to,
|
||||
.reply-to-more,
|
||||
:deep(.more) {
|
||||
position: relative;
|
||||
&::before {
|
||||
|
@ -517,14 +509,19 @@ onUnmounted(() => {
|
|||
transition: opacity 0.2s;
|
||||
z-index: -1;
|
||||
}
|
||||
&.reply-to,
|
||||
&.reply-to-more {
|
||||
&.reply-to {
|
||||
&::before {
|
||||
inset: 0px 8px;
|
||||
}
|
||||
&:not(.max-width_450px)::before {
|
||||
bottom: 12px;
|
||||
}
|
||||
&:first-of-type::before {
|
||||
top: 12px;
|
||||
}
|
||||
&.reply.max-width_500px:first-of-type::before {
|
||||
top: 4px;
|
||||
}
|
||||
}
|
||||
// &::after {
|
||||
// content: "";
|
||||
|
@ -557,8 +554,11 @@ onUnmounted(() => {
|
|||
// }
|
||||
}
|
||||
|
||||
&.max-width_500px {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
&.max-width_450px {
|
||||
> .reply-to-more:first-child {
|
||||
> .reply-to:first-child {
|
||||
padding-top: 14px;
|
||||
}
|
||||
> .renote {
|
||||
|
|
|
@ -69,7 +69,6 @@
|
|||
class="button"
|
||||
:note="appearNote"
|
||||
:count="appearNote.renoteCount"
|
||||
:renoteCw="note.cw"
|
||||
/>
|
||||
<XStarButtonNoEmoji
|
||||
v-if="!enableEmojiReactions"
|
||||
|
@ -362,6 +361,7 @@ function noteClick(e) {
|
|||
|
||||
> .main {
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
|
||||
> .avatar-container {
|
||||
margin-right: 8px;
|
||||
|
@ -377,7 +377,6 @@ function noteClick(e) {
|
|||
> .body {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
cursor: pointer;
|
||||
margin: 0 -200px;
|
||||
padding: 0 200px;
|
||||
overflow: clip;
|
||||
|
|
|
@ -58,13 +58,12 @@ defineExpose({
|
|||
.giivymft {
|
||||
&.noGap {
|
||||
> .notes {
|
||||
background: var(--panel);
|
||||
background: var(--panel) !important;
|
||||
border-radius: var(--radius);
|
||||
}
|
||||
}
|
||||
&:not(.noGap) {
|
||||
> .notes {
|
||||
background: var(--bg);
|
||||
.qtqtichx {
|
||||
background: var(--panel);
|
||||
border-radius: var(--radius);
|
||||
|
|
|
@ -17,19 +17,17 @@
|
|||
:max-height="maxHeight"
|
||||
:as-drawer="type === 'drawer'"
|
||||
class="sfhdhdhq"
|
||||
:class="{
|
||||
drawer: type === 'drawer',
|
||||
...classMap(classes),
|
||||
}"
|
||||
:class="{ drawer: type === 'drawer' }"
|
||||
@close="modal.close()"
|
||||
/>
|
||||
</MkModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {} from "vue";
|
||||
import MkModal from "./MkModal.vue";
|
||||
import MkMenu from "./MkMenu.vue";
|
||||
import { MenuClasses, MenuItem } from "@/types/menu";
|
||||
import { MenuItem } from "@/types/menu";
|
||||
|
||||
defineProps<{
|
||||
items: MenuItem[];
|
||||
|
@ -37,7 +35,6 @@ defineProps<{
|
|||
width?: number;
|
||||
viaKeyboard?: boolean;
|
||||
src?: any;
|
||||
classes?: MenuClasses;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
|
@ -45,18 +42,6 @@ const emit = defineEmits<{
|
|||
}>();
|
||||
|
||||
let modal = $ref<InstanceType<typeof MkModal>>();
|
||||
|
||||
function classMap(classes?: MenuClasses) {
|
||||
if (!classes) return {};
|
||||
|
||||
return (Array.isArray(classes) ? classes : classes.value).reduce(
|
||||
(acc, cls) => {
|
||||
acc[cls] = true;
|
||||
return acc;
|
||||
},
|
||||
{}
|
||||
);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
<template>
|
||||
<div
|
||||
<section
|
||||
v-size="{ max: [310, 500] }"
|
||||
class="gafaadew"
|
||||
:class="{ modal, _popup: modal }"
|
||||
:aria-label="i18n.ts._pages.blocks.post"
|
||||
@dragover.stop="onDragover"
|
||||
@dragenter="onDragenter"
|
||||
@dragleave="onDragleave"
|
||||
|
@ -82,7 +83,7 @@
|
|||
<div v-if="quoteId" class="with-quote">
|
||||
<i class="ph-quotes ph-bold ph-lg"></i>
|
||||
{{ i18n.ts.quoteAttached
|
||||
}}<button @click="quoteId = null">
|
||||
}}<button class="_button" @click="quoteId = null">
|
||||
<i class="ph-x ph-bold ph-lg"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -218,7 +219,7 @@
|
|||
/>
|
||||
</datalist>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@ -1120,11 +1121,16 @@ onMounted(() => {
|
|||
}
|
||||
|
||||
> .with-quote {
|
||||
margin: 0 0 8px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.4em;
|
||||
margin-inline: 24px;
|
||||
margin-bottom: 12px;
|
||||
color: var(--accent);
|
||||
|
||||
> button {
|
||||
padding: 4px 8px;
|
||||
display: flex;
|
||||
padding: 0;
|
||||
color: var(--accentAlpha04);
|
||||
|
||||
&:hover {
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
ref="buttonRef"
|
||||
v-tooltip.noDelay.bottom="i18n.ts.renote"
|
||||
class="eddddedb _button canRenote"
|
||||
:class="{ addCw }"
|
||||
@click="renote(false, $event)"
|
||||
>
|
||||
<i class="ph-repeat ph-bold ph-lg"></i>
|
||||
|
@ -27,29 +26,20 @@ import { useTooltip } from "@/scripts/use-tooltip";
|
|||
import { i18n } from "@/i18n";
|
||||
import { defaultStore } from "@/store";
|
||||
import { MenuItem } from "@/types/menu";
|
||||
import { add } from "date-fns";
|
||||
|
||||
const props = defineProps<{
|
||||
note: misskey.entities.Note;
|
||||
count: number;
|
||||
renoteCw?: string | null;
|
||||
}>();
|
||||
|
||||
const buttonRef = ref<HTMLElement>();
|
||||
const addCw = ref<boolean>(!!props.renoteCw);
|
||||
const cwInput = ref<string>(props.renoteCw ?? "");
|
||||
|
||||
const canRenote = computed(
|
||||
() =>
|
||||
["public", "home", "hidden"].includes(props.note.visibility) ||
|
||||
["public", "home"].includes(props.note.visibility) ||
|
||||
props.note.userId === $i.id
|
||||
);
|
||||
|
||||
const getCw = () =>
|
||||
addCw.value && cwInput.value !== ""
|
||||
? cwInput.value
|
||||
: props.note.cw ?? undefined;
|
||||
|
||||
useTooltip(buttonRef, async (showing) => {
|
||||
const renotes = await os.api("notes/renotes", {
|
||||
noteId: props.note.id,
|
||||
|
@ -86,10 +76,7 @@ const renote = async (viaKeyboard = false, ev?: MouseEvent) => {
|
|||
|
||||
let buttonActions: Array<MenuItem> = [];
|
||||
|
||||
if (
|
||||
props.note.visibility === "public" ||
|
||||
props.note.visibility === "hidden"
|
||||
) {
|
||||
if (props.note.visibility === "public") {
|
||||
buttonActions.push({
|
||||
text: i18n.ts.renote,
|
||||
textStyle: "font-weight: bold",
|
||||
|
@ -99,7 +86,6 @@ const renote = async (viaKeyboard = false, ev?: MouseEvent) => {
|
|||
os.api("notes/create", {
|
||||
renoteId: props.note.id,
|
||||
visibility: "public",
|
||||
cw: getCw(),
|
||||
});
|
||||
const el =
|
||||
ev &&
|
||||
|
@ -117,7 +103,7 @@ const renote = async (viaKeyboard = false, ev?: MouseEvent) => {
|
|||
});
|
||||
}
|
||||
|
||||
if (["public", "home", "hidden"].includes(props.note.visibility)) {
|
||||
if (["public", "home"].includes(props.note.visibility)) {
|
||||
buttonActions.push({
|
||||
text: `${i18n.ts.renote} (${i18n.ts._visibility.home})`,
|
||||
icon: "ph-house ph-bold ph-lg",
|
||||
|
@ -126,7 +112,6 @@ const renote = async (viaKeyboard = false, ev?: MouseEvent) => {
|
|||
os.api("notes/create", {
|
||||
renoteId: props.note.id,
|
||||
visibility: "home",
|
||||
cw: getCw(),
|
||||
});
|
||||
const el =
|
||||
ev &&
|
||||
|
@ -154,7 +139,6 @@ const renote = async (viaKeyboard = false, ev?: MouseEvent) => {
|
|||
renoteId: props.note.id,
|
||||
visibility: "specified",
|
||||
visibleUserIds: props.note.visibleUserIds,
|
||||
cw: getCw(),
|
||||
});
|
||||
const el =
|
||||
ev &&
|
||||
|
@ -179,7 +163,6 @@ const renote = async (viaKeyboard = false, ev?: MouseEvent) => {
|
|||
os.api("notes/create", {
|
||||
renoteId: props.note.id,
|
||||
visibility: "followers",
|
||||
cw: getCw(),
|
||||
});
|
||||
const el =
|
||||
ev &&
|
||||
|
@ -197,30 +180,44 @@ const renote = async (viaKeyboard = false, ev?: MouseEvent) => {
|
|||
});
|
||||
}
|
||||
|
||||
const showQuote = !defaultStore.state.seperateRenoteQuote;
|
||||
|
||||
if (!props.note.cw || props.note.cw === "") {
|
||||
if (canRenote) {
|
||||
buttonActions.push({
|
||||
type: "switch",
|
||||
ref: addCw,
|
||||
text: "Add content warning",
|
||||
hidden: addCw,
|
||||
text: `${i18n.ts.renote} (${i18n.ts.local})`,
|
||||
icon: "ph-hand-fist ph-bold ph-lg",
|
||||
danger: false,
|
||||
action: () => {
|
||||
os.api(
|
||||
"notes/create",
|
||||
props.note.visibility === "specified"
|
||||
? {
|
||||
renoteId: props.note.id,
|
||||
visibility: props.note.visibility,
|
||||
visibleUserIds: props.note.visibleUserIds,
|
||||
localOnly: true,
|
||||
}
|
||||
: {
|
||||
renoteId: props.note.id,
|
||||
visibility: props.note.visibility,
|
||||
localOnly: true,
|
||||
}
|
||||
);
|
||||
const el =
|
||||
ev &&
|
||||
((ev.currentTarget ?? ev.target) as
|
||||
| HTMLElement
|
||||
| null
|
||||
| undefined);
|
||||
if (el) {
|
||||
const rect = el.getBoundingClientRect();
|
||||
const x = rect.left + el.offsetWidth / 2;
|
||||
const y = rect.top + el.offsetHeight / 2;
|
||||
os.popup(Ripple, { x, y }, {}, "end");
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
buttonActions.push({
|
||||
type: "input",
|
||||
ref: cwInput,
|
||||
placeholder: "Content warning",
|
||||
required: true,
|
||||
visible: addCw,
|
||||
});
|
||||
|
||||
if (showQuote || hasRenotedBefore) {
|
||||
buttonActions.push(null);
|
||||
}
|
||||
}
|
||||
|
||||
if (showQuote) {
|
||||
if (!defaultStore.state.seperateRenoteQuote) {
|
||||
buttonActions.push({
|
||||
text: i18n.ts.quote,
|
||||
icon: "ph-quotes ph-bold ph-lg",
|
||||
|
@ -245,10 +242,7 @@ const renote = async (viaKeyboard = false, ev?: MouseEvent) => {
|
|||
},
|
||||
});
|
||||
}
|
||||
|
||||
os.popupMenu(buttonActions, buttonRef.value, {
|
||||
viaKeyboard,
|
||||
});
|
||||
os.popupMenu(buttonActions, buttonRef.value, { viaKeyboard });
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ export default defineComponent({
|
|||
this.$i ? this.$i.username : "guest"
|
||||
}.\nAlso, here is ${config.url} and [example link](${
|
||||
config.url
|
||||
}). for more details, see https://example.com.\nAs you know #misskey is open-source software.`,
|
||||
}). for more details, see https://calckey.org.\nAs you know #misskey is open-source software.`,
|
||||
};
|
||||
},
|
||||
|
||||
|
|
|
@ -1,137 +1,142 @@
|
|||
<template>
|
||||
<div
|
||||
:class="{
|
||||
hasCw: !!cw,
|
||||
cwHighlight,
|
||||
}"
|
||||
>
|
||||
<p v-if="cw != null" class="cw">
|
||||
<MkA
|
||||
v-if="!detailed && appearNote.replyId"
|
||||
:to="`/notes/${appearNote.replyId}`"
|
||||
class="reply-icon"
|
||||
@click.stop
|
||||
>
|
||||
<i class="ph-arrow-bend-left-up ph-bold ph-lg"></i>
|
||||
</MkA>
|
||||
<MkA
|
||||
v-if="
|
||||
conversation &&
|
||||
appearNote.renoteId &&
|
||||
appearNote.renoteId != parentId &&
|
||||
!appearNote.replyId
|
||||
"
|
||||
:to="`/notes/${appearNote.renoteId}`"
|
||||
class="reply-icon"
|
||||
@click.stop
|
||||
>
|
||||
<i class="ph-quotes ph-bold ph-lg"></i>
|
||||
</MkA>
|
||||
<Mfm
|
||||
v-if="cw != ''"
|
||||
class="text"
|
||||
:text="cw"
|
||||
:author="appearNote.user"
|
||||
:i="$i"
|
||||
:custom-emojis="appearNote.emojis"
|
||||
<p v-if="note.cw != null" class="cw">
|
||||
<MkA
|
||||
v-if="!detailed && note.replyId"
|
||||
:to="`/notes/${note.replyId}`"
|
||||
class="reply-icon"
|
||||
@click.stop
|
||||
>
|
||||
<i class="ph-arrow-bend-left-up ph-bold ph-lg"></i>
|
||||
</MkA>
|
||||
<MkA
|
||||
v-if="
|
||||
conversation &&
|
||||
note.renoteId &&
|
||||
note.renoteId != parentId &&
|
||||
!note.replyId
|
||||
"
|
||||
:to="`/notes/${note.renoteId}`"
|
||||
class="reply-icon"
|
||||
@click.stop
|
||||
>
|
||||
<i class="ph-quotes ph-bold ph-lg"></i>
|
||||
</MkA>
|
||||
<Mfm
|
||||
v-if="note.cw != ''"
|
||||
class="text"
|
||||
:text="note.cw"
|
||||
:author="note.user"
|
||||
:i="$i"
|
||||
:custom-emojis="note.emojis"
|
||||
/>
|
||||
</p>
|
||||
<div class="wrmlmaau">
|
||||
<div
|
||||
class="content"
|
||||
:class="{
|
||||
collapsed,
|
||||
isLong,
|
||||
showContent: note.cw && !showContent,
|
||||
disableAnim: disableMfm,
|
||||
}"
|
||||
>
|
||||
<XCwButton
|
||||
ref="cwButton"
|
||||
v-if="note.cw && !showContent"
|
||||
v-model="showContent"
|
||||
:note="note"
|
||||
v-on:keydown="focusFooter"
|
||||
/>
|
||||
</p>
|
||||
<div class="wrmlmaau">
|
||||
<div
|
||||
class="content"
|
||||
:class="{ collapsed, isLong, showContent: cw && !showContent }"
|
||||
class="body"
|
||||
v-bind="{
|
||||
'aria-label': !showContent ? '' : null,
|
||||
tabindex: !showContent ? '-1' : null,
|
||||
}"
|
||||
>
|
||||
<XCwButton
|
||||
ref="cwButton"
|
||||
v-if="cw && !showContent"
|
||||
v-model="showContent"
|
||||
:note="appearNote"
|
||||
v-on:keydown="focusFooter"
|
||||
/>
|
||||
<div
|
||||
class="body"
|
||||
v-bind="{
|
||||
'aria-label': !showContent ? '' : null,
|
||||
tabindex: !showContent ? '-1' : null,
|
||||
}"
|
||||
<span v-if="note.deletedAt" style="opacity: 0.5"
|
||||
>({{ i18n.ts.deleted }})</span
|
||||
>
|
||||
<span v-if="appearNote.deletedAt" style="opacity: 0.5"
|
||||
>({{ i18n.ts.deleted }})</span
|
||||
>
|
||||
<template v-if="!cw">
|
||||
<MkA
|
||||
v-if="!detailed && appearNote.replyId"
|
||||
:to="`/notes/${appearNote.replyId}`"
|
||||
class="reply-icon"
|
||||
@click.stop
|
||||
>
|
||||
<i class="ph-arrow-bend-left-up ph-bold ph-lg"></i>
|
||||
</MkA>
|
||||
<MkA
|
||||
v-if="
|
||||
conversation &&
|
||||
appearNote.renoteId &&
|
||||
appearNote.renoteId != parentId &&
|
||||
!appearNote.replyId
|
||||
"
|
||||
:to="`/notes/${appearNote.renoteId}`"
|
||||
class="reply-icon"
|
||||
@click.stop
|
||||
>
|
||||
<i class="ph-quotes ph-bold ph-lg"></i>
|
||||
</MkA>
|
||||
</template>
|
||||
<Mfm
|
||||
v-if="appearNote.text"
|
||||
:text="appearNote.text"
|
||||
:author="appearNote.user"
|
||||
:i="$i"
|
||||
:custom-emojis="appearNote.emojis"
|
||||
/>
|
||||
<template v-if="!note.cw">
|
||||
<MkA
|
||||
v-if="!detailed && appearNote.renoteId"
|
||||
class="rp"
|
||||
:to="`/notes/${appearNote.renoteId}`"
|
||||
>{{ i18n.ts.quoteAttached }}: ...</MkA
|
||||
v-if="!detailed && note.replyId"
|
||||
:to="`/notes/${note.replyId}`"
|
||||
class="reply-icon"
|
||||
@click.stop
|
||||
>
|
||||
<div v-if="appearNote.files.length > 0" class="files">
|
||||
<XMediaList :media-list="appearNote.files" />
|
||||
</div>
|
||||
<XPoll
|
||||
v-if="appearNote.poll"
|
||||
:note="appearNote"
|
||||
class="poll"
|
||||
/>
|
||||
<template v-if="detailed">
|
||||
<MkUrlPreview
|
||||
v-for="url in urls"
|
||||
:key="url"
|
||||
:url="url"
|
||||
:compact="true"
|
||||
:detail="false"
|
||||
class="url-preview"
|
||||
/>
|
||||
<div
|
||||
v-if="appearNote.renote"
|
||||
class="renote"
|
||||
@click.stop="emit('push', appearNote.renote)"
|
||||
>
|
||||
<XNoteSimple :note="appearNote.renote" />
|
||||
</div>
|
||||
</template>
|
||||
<div
|
||||
v-if="cw && !showContent"
|
||||
tabindex="0"
|
||||
v-on:focus="cwButton?.focus()"
|
||||
></div>
|
||||
<i class="ph-arrow-bend-left-up ph-bold ph-lg"></i>
|
||||
</MkA>
|
||||
<MkA
|
||||
v-if="
|
||||
conversation &&
|
||||
note.renoteId &&
|
||||
note.renoteId != parentId &&
|
||||
!note.replyId
|
||||
"
|
||||
:to="`/notes/${note.renoteId}`"
|
||||
class="reply-icon"
|
||||
@click.stop
|
||||
>
|
||||
<i class="ph-quotes ph-bold ph-lg"></i>
|
||||
</MkA>
|
||||
</template>
|
||||
<Mfm
|
||||
v-if="note.text"
|
||||
:text="note.text"
|
||||
:author="note.user"
|
||||
:i="$i"
|
||||
:custom-emojis="note.emojis"
|
||||
/>
|
||||
<MkA
|
||||
v-if="!detailed && note.renoteId"
|
||||
class="rp"
|
||||
:to="`/notes/${note.renoteId}`"
|
||||
>{{ i18n.ts.quoteAttached }}: ...</MkA
|
||||
>
|
||||
<div v-if="note.files.length > 0" class="files">
|
||||
<XMediaList :media-list="note.files" />
|
||||
</div>
|
||||
<XShowMoreButton
|
||||
v-if="isLong"
|
||||
v-model="collapsed"
|
||||
></XShowMoreButton>
|
||||
<XCwButton v-if="cw" v-model="showContent" :note="appearNote" />
|
||||
<XPoll v-if="note.poll" :note="note" class="poll" />
|
||||
<template v-if="detailed">
|
||||
<MkUrlPreview
|
||||
v-for="url in urls"
|
||||
:key="url"
|
||||
:url="url"
|
||||
:compact="true"
|
||||
:detail="false"
|
||||
class="url-preview"
|
||||
/>
|
||||
<div
|
||||
v-if="note.renote"
|
||||
class="renote"
|
||||
@click.stop="emit('push', note.renote)"
|
||||
>
|
||||
<XNoteSimple :note="note.renote" />
|
||||
</div>
|
||||
</template>
|
||||
<div
|
||||
v-if="note.cw && !showContent"
|
||||
tabindex="0"
|
||||
v-on:focus="cwButton?.focus()"
|
||||
></div>
|
||||
</div>
|
||||
<XShowMoreButton
|
||||
v-if="isLong"
|
||||
v-model="collapsed"
|
||||
></XShowMoreButton>
|
||||
<XCwButton v-if="note.cw" v-model="showContent" :note="note" />
|
||||
</div>
|
||||
<MkButton
|
||||
v-if="hasMfm && defaultStore.state.animatedMfm"
|
||||
@click.stop="toggleMfm"
|
||||
>
|
||||
<template v-if="disableMfm">
|
||||
<i class="ph-play ph-bold"></i> {{ i18n.ts._mfm.play }}
|
||||
</template>
|
||||
<template v-else>
|
||||
<i class="ph-stop ph-bold"></i> {{ i18n.ts._mfm.stop }}
|
||||
</template>
|
||||
</MkButton>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -139,13 +144,16 @@
|
|||
import { ref } from "vue";
|
||||
import * as misskey from "calckey-js";
|
||||
import * as mfm from "mfm-js";
|
||||
import * as os from "@/os";
|
||||
import XNoteSimple from "@/components/MkNoteSimple.vue";
|
||||
import XMediaList from "@/components/MkMediaList.vue";
|
||||
import XPoll from "@/components/MkPoll.vue";
|
||||
import MkUrlPreview from "@/components/MkUrlPreview.vue";
|
||||
import XShowMoreButton from "@/components/MkShowMoreButton.vue";
|
||||
import XCwButton from "@/components/MkCwButton.vue";
|
||||
import MkButton from "@/components/MkButton.vue";
|
||||
import { extractUrlFromMfm } from "@/scripts/extract-url-from-mfm";
|
||||
import { extractMfmWithAnimation } from "@/scripts/extract-mfm";
|
||||
import { i18n } from "@/i18n";
|
||||
import { defaultStore } from "@/store";
|
||||
|
||||
|
@ -162,34 +170,46 @@ const emit = defineEmits<{
|
|||
(ev: "focusfooter"): void;
|
||||
}>();
|
||||
|
||||
const note = props.note;
|
||||
|
||||
const isRenote =
|
||||
note.renote != null &&
|
||||
note.text == null &&
|
||||
note.fileIds.length === 0 &&
|
||||
note.poll == null;
|
||||
|
||||
let appearNote = $computed(() =>
|
||||
isRenote ? (note.renote as misskey.entities.Note) : note
|
||||
);
|
||||
let cw = $computed(() => appearNote.cw || note.cw);
|
||||
const cwHighlight = defaultStore.state.highlightCw;
|
||||
|
||||
const cwButton = ref<HTMLElement>();
|
||||
const isLong =
|
||||
!props.detailedView &&
|
||||
!cw &&
|
||||
appearNote.text != null &&
|
||||
(appearNote.text.split("\n").length > 9 || appearNote.text.length > 500);
|
||||
const collapsed = $ref(!cw && isLong);
|
||||
props.note.cw == null &&
|
||||
props.note.text != null &&
|
||||
(props.note.text.split("\n").length > 9 || props.note.text.length > 500);
|
||||
const collapsed = $ref(props.note.cw == null && isLong);
|
||||
|
||||
const urls = appearNote.text
|
||||
? extractUrlFromMfm(mfm.parse(appearNote.text)).slice(0, 5)
|
||||
const urls = props.note.text
|
||||
? extractUrlFromMfm(mfm.parse(props.note.text)).slice(0, 5)
|
||||
: null;
|
||||
|
||||
let showContent = $ref(false);
|
||||
|
||||
const mfms = props.note.text
|
||||
? extractMfmWithAnimation(mfm.parse(props.note.text))
|
||||
: null;
|
||||
|
||||
const hasMfm = $ref(mfms.length > 0);
|
||||
|
||||
let disableMfm = $ref(hasMfm && defaultStore.state.animatedMfm);
|
||||
|
||||
async function toggleMfm() {
|
||||
if (disableMfm) {
|
||||
if (!defaultStore.state.animatedMfmWarnShown) {
|
||||
const { canceled } = await os.confirm({
|
||||
type: "warning",
|
||||
text: i18n.ts._mfm.warn,
|
||||
});
|
||||
if (canceled) return;
|
||||
|
||||
defaultStore.set("animatedMfmWarnShown", true);
|
||||
}
|
||||
|
||||
disableMfm = false;
|
||||
} else {
|
||||
disableMfm = true;
|
||||
}
|
||||
}
|
||||
|
||||
function focusFooter(ev) {
|
||||
if (ev.key == "Tab" && !ev.getModifierState("Shift")) {
|
||||
emit("focusfooter");
|
||||
|
@ -219,25 +239,9 @@ function focusFooter(ev) {
|
|||
overflow-wrap: break-word;
|
||||
> .text {
|
||||
margin-right: 8px;
|
||||
padding-inline-start: 0.25em;
|
||||
}
|
||||
}
|
||||
.cwHighlight.hasCw {
|
||||
outline: 1px dotted var(--cwFg);
|
||||
border-radius: 5px;
|
||||
> .wrmlmaau {
|
||||
padding-inline-start: 0.25em;
|
||||
}
|
||||
> .cw {
|
||||
background-color: var(--cwFg);
|
||||
color: var(--cwBg);
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
> .reply-icon {
|
||||
color: var(--cwBg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wrmlmaau {
|
||||
.content {
|
||||
overflow-wrap: break-word;
|
||||
|
@ -267,9 +271,11 @@ function focusFooter(ev) {
|
|||
> .url-preview {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
> .poll {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
> .renote {
|
||||
padding-top: 8px;
|
||||
> * {
|
||||
|
@ -284,6 +290,7 @@ function focusFooter(ev) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.collapsed,
|
||||
&.showContent {
|
||||
position: relative;
|
||||
|
@ -326,6 +333,13 @@ function focusFooter(ev) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.disableAnim :deep(span) {
|
||||
animation: none !important;
|
||||
}
|
||||
}
|
||||
> :deep(button) {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="rrevdjwu" :class="{ grid }">
|
||||
<div v-for="group in def" class="group">
|
||||
<nav class="rrevdjwu" :class="{ grid }">
|
||||
<section v-for="group in def" class="group">
|
||||
<div v-if="group.title" class="title">{{ group.title }}</div>
|
||||
|
||||
<div class="items">
|
||||
|
@ -48,8 +48,8 @@
|
|||
</MkA>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
|
|
|
@ -41,16 +41,27 @@
|
|||
{{ i18n.ts.next }}</MkButton
|
||||
>
|
||||
</div>
|
||||
<h2 class="_title title">
|
||||
<i class="ph-info ph-bold ph-lg"></i>
|
||||
{{ i18n.ts._tutorial.title }}
|
||||
</h2>
|
||||
<Transition name="fade">
|
||||
<div v-if="tutorial === 0" key="1" class="_content">
|
||||
<section v-if="tutorial === 0" key="1" class="_content">
|
||||
<h2 class="_title title">
|
||||
<i class="ph-info ph-bold ph-lg"></i>
|
||||
{{ i18n.ts._tutorial.title }}
|
||||
</h2>
|
||||
<h3>{{ i18n.ts._tutorial.step1_1 }}</h3>
|
||||
<div>{{ i18n.ts._tutorial.step1_2 }}</div>
|
||||
</div>
|
||||
<div
|
||||
<!-- TODO: move to own slide -->
|
||||
<!-- <FormSwitch v-model="autoplayMfm" class="_formBlock">
|
||||
{{ i18n.ts._mfm.alwaysPlay }}
|
||||
<template #caption>
|
||||
<i class="ph-warning ph-bold ph-lg" style="color: var(--warn)"></i>
|
||||
{{ i18n.ts._mfm.warn }}
|
||||
</template>
|
||||
</FormSwitch> -->
|
||||
<FormSwitch v-model="reduceAnimation" class="_formBlock">
|
||||
{{ i18n.ts.reduceUiAnimation }}
|
||||
</FormSwitch>
|
||||
</section>
|
||||
<section
|
||||
v-else-if="tutorial === 1"
|
||||
key="2"
|
||||
class="_content"
|
||||
|
@ -60,8 +71,8 @@
|
|||
<br />
|
||||
<XSettings :save-button="true" />
|
||||
<br />
|
||||
</div>
|
||||
<div
|
||||
</section>
|
||||
<section
|
||||
v-else-if="tutorial === 2"
|
||||
key="3"
|
||||
class="_content"
|
||||
|
@ -74,8 +85,8 @@
|
|||
><i class="ph-check ph-bold ph-lg"></i>
|
||||
{{ i18n.ts.next }}</MkButton
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
</section>
|
||||
<section
|
||||
v-else-if="tutorial === 3"
|
||||
key="4"
|
||||
class="_content"
|
||||
|
@ -90,8 +101,8 @@
|
|||
</I18n>
|
||||
<br />
|
||||
<XPostForm class="post-form _block" />
|
||||
</div>
|
||||
<div
|
||||
</section>
|
||||
<section
|
||||
v-else-if="tutorial === 4"
|
||||
key="5"
|
||||
class="_content"
|
||||
|
@ -160,8 +171,8 @@
|
|||
</I18n>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div
|
||||
</section>
|
||||
<section
|
||||
v-else-if="tutorial === 5"
|
||||
key="6"
|
||||
class="_content"
|
||||
|
@ -180,7 +191,7 @@
|
|||
primary
|
||||
show-only-to-register
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
</Transition>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -189,7 +200,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from "vue";
|
||||
import { reactive, computed } from "vue";
|
||||
import XSettings from "@/pages/settings/profile.vue";
|
||||
import XModalWindow from "@/components/MkModalWindow.vue";
|
||||
import MkButton from "@/components/MkButton.vue";
|
||||
|
@ -197,6 +208,7 @@ import XFeaturedUsers from "@/pages/explore.users.vue";
|
|||
import XPostForm from "@/components/MkPostForm.vue";
|
||||
import MkSparkle from "@/components/MkSparkle.vue";
|
||||
import MkPushNotificationAllowButton from "@/components/MkPushNotificationAllowButton.vue";
|
||||
import FormSwitch from "@/components/form/switch.vue";
|
||||
import { defaultStore } from "@/store";
|
||||
import { i18n } from "@/i18n";
|
||||
import { $i } from "@/account";
|
||||
|
@ -243,6 +255,21 @@ const tutorial = computed({
|
|||
},
|
||||
});
|
||||
|
||||
const autoplayMfm = computed(
|
||||
defaultStore.makeGetterSetter(
|
||||
"animatedMfm",
|
||||
(v) => !v,
|
||||
(v) => !v
|
||||
)
|
||||
);
|
||||
const reduceAnimation = computed(
|
||||
defaultStore.makeGetterSetter(
|
||||
"animation",
|
||||
(v) => !v,
|
||||
(v) => !v
|
||||
)
|
||||
);
|
||||
|
||||
function close(res) {
|
||||
tutorial.value = -1;
|
||||
dialog.close();
|
||||
|
|
|
@ -57,7 +57,8 @@ export default defineComponent({
|
|||
MkRadio,
|
||||
{
|
||||
key: option.key,
|
||||
value: option.props.value,
|
||||
value: option.props?.value,
|
||||
disabled: option.props?.disabled,
|
||||
modelValue: this.value,
|
||||
"onUpdate:modelValue": (value) =>
|
||||
(this.value = value),
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<template>
|
||||
<div class="vrtktovh _formBlock">
|
||||
<div class="label"><slot name="label"></slot></div>
|
||||
<section class="vrtktovh _formBlock">
|
||||
<h3 class="label"><slot name="label"></slot></h3>
|
||||
<div class="main _formRoot">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup></script>
|
||||
|
@ -29,6 +29,7 @@
|
|||
> .label {
|
||||
font-weight: bold;
|
||||
margin: 1.5em 0 16px 0;
|
||||
font-size: 1em;
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div
|
||||
<header
|
||||
v-if="show"
|
||||
ref="el"
|
||||
class="fdidabkb"
|
||||
|
@ -7,12 +7,15 @@
|
|||
:style="{ background: bg }"
|
||||
@click="onClick"
|
||||
>
|
||||
<i
|
||||
@click="goBack()"
|
||||
<button
|
||||
v-if="props.displayBackButton"
|
||||
class="_button button icon backButton"
|
||||
@click.stop="goBack()"
|
||||
@touchstart="preventDrag"
|
||||
v-tooltip.noDelay="i18n.ts.goBack"
|
||||
class="icon backButton ph-caret-left ph-bold ph-lg"
|
||||
></i>
|
||||
>
|
||||
<i class="ph-caret-left ph-bold ph-lg"></i>
|
||||
</button>
|
||||
<div v-if="narrow" class="buttons left" @click="openAccountMenu">
|
||||
<MkAvatar
|
||||
v-if="props.displayMyAvatar && $i"
|
||||
|
@ -63,7 +66,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ref="tabsEl" v-if="hasTabs" class="tabs">
|
||||
<nav ref="tabsEl" v-if="hasTabs" class="tabs">
|
||||
<button
|
||||
v-for="tab in tabs"
|
||||
:ref="(el) => (tabRefs[tab.key] = el)"
|
||||
|
@ -79,7 +82,7 @@
|
|||
<span class="title">{{ tab.title }}</span>
|
||||
</button>
|
||||
<div ref="tabHighlightEl" class="highlight"></div>
|
||||
</div>
|
||||
</nav>
|
||||
</template>
|
||||
<div class="buttons right">
|
||||
<template v-for="action in actions">
|
||||
|
@ -94,7 +97,7 @@
|
|||
</button>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@ -377,7 +380,8 @@ onUnmounted(() => {
|
|||
display: none;
|
||||
}
|
||||
|
||||
> .button {
|
||||
> .button/*, @at-root .backButton*/ {
|
||||
/* I don't know how to get this to work */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
|
|
@ -102,35 +102,22 @@ export default defineComponent({
|
|||
switch (token.props.name) {
|
||||
case "tada": {
|
||||
const speed = validTime(token.props.args.speed) || "1s";
|
||||
style = `font-size: 150%;${
|
||||
defaultStore.state.animatedMfm
|
||||
? `animation: tada ${speed} linear infinite both;`
|
||||
: ""
|
||||
}`;
|
||||
style = `font-size: 150%; animation: tada ${speed} linear infinite both;`;
|
||||
break;
|
||||
}
|
||||
case "jelly": {
|
||||
const speed = validTime(token.props.args.speed) || "1s";
|
||||
style =
|
||||
defaultStore.state.animatedMfm && !reducedMotion()
|
||||
? `animation: mfm-rubberBand ${speed} linear infinite both;`
|
||||
: "";
|
||||
style = `animation: mfm-rubberBand ${speed} linear infinite both;`;
|
||||
break;
|
||||
}
|
||||
case "twitch": {
|
||||
const speed = validTime(token.props.args.speed) || "0.5s";
|
||||
style =
|
||||
defaultStore.state.animatedMfm && !reducedMotion()
|
||||
? `animation: mfm-twitch ${speed} ease infinite;`
|
||||
: "";
|
||||
style = `animation: mfm-twitch ${speed} ease infinite;`;
|
||||
break;
|
||||
}
|
||||
case "shake": {
|
||||
const speed = validTime(token.props.args.speed) || "0.5s";
|
||||
style =
|
||||
defaultStore.state.animatedMfm && !reducedMotion()
|
||||
? `animation: mfm-shake ${speed} ease infinite;`
|
||||
: "";
|
||||
style = `animation: mfm-shake ${speed} ease infinite;`;
|
||||
break;
|
||||
}
|
||||
case "spin": {
|
||||
|
@ -145,38 +132,26 @@ export default defineComponent({
|
|||
? "mfm-spinY"
|
||||
: "mfm-spin";
|
||||
const speed = validTime(token.props.args.speed) || "1.5s";
|
||||
style =
|
||||
defaultStore.state.animatedMfm && !reducedMotion()
|
||||
? `animation: ${anime} ${speed} linear infinite; animation-direction: ${direction};`
|
||||
: "";
|
||||
style = `animation: ${anime} ${speed} linear infinite; animation-direction: ${direction};`;
|
||||
break;
|
||||
}
|
||||
case "jump": {
|
||||
const speed = validTime(token.props.args.speed) || "0.75s";
|
||||
style =
|
||||
defaultStore.state.animatedMfm && !reducedMotion()
|
||||
? `animation: mfm-jump ${speed} linear infinite;`
|
||||
: "";
|
||||
style = `animation: mfm-jump ${speed} linear infinite;`;
|
||||
break;
|
||||
}
|
||||
case "bounce": {
|
||||
const speed = validTime(token.props.args.speed) || "0.75s";
|
||||
style =
|
||||
defaultStore.state.animatedMfm && !reducedMotion()
|
||||
? `animation: mfm-bounce ${speed} linear infinite; transform-origin: center bottom;`
|
||||
: "";
|
||||
style = `animation: mfm-bounce ${speed} linear infinite; transform-origin: center bottom;`;
|
||||
break;
|
||||
}
|
||||
case "rainbow": {
|
||||
const speed = validTime(token.props.args.speed) || "1s";
|
||||
style =
|
||||
defaultStore.state.animatedMfm && !reducedMotion()
|
||||
? `animation: mfm-rainbow ${speed} linear infinite;`
|
||||
: "";
|
||||
style = `animation: mfm-rainbow ${speed} linear infinite;`;
|
||||
break;
|
||||
}
|
||||
case "sparkle": {
|
||||
if (!(defaultStore.state.animatedMfm || reducedMotion())) {
|
||||
if (reducedMotion()) {
|
||||
return genEl(token.children);
|
||||
}
|
||||
return h(MkSparkle, {}, genEl(token.children));
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue