mirror of
https://codeberg.org/yeentown/barkey.git
synced 2025-07-07 04:26:58 +00:00
Merge pull request '1.1+2025.2.3' (#76) from dev into stable
Reviewed-on: https://codeberg.org/yeentown/barkey/pulls/76
This commit is contained in:
commit
0978ac33f8
9 changed files with 590 additions and 60 deletions
290
.config/dev.yml
Normal file
290
.config/dev.yml
Normal file
|
@ -0,0 +1,290 @@
|
|||
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
# Misskey configuration
|
||||
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
# ┌─────┐
|
||||
#───┘ URL └─────────────────────────────────────────────────────
|
||||
|
||||
# Final accessible URL seen by a user.
|
||||
url: http://misskey.local:3000
|
||||
|
||||
# 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:
|
||||
host: postgres
|
||||
port: 5432
|
||||
|
||||
# Database name
|
||||
db: postgres
|
||||
|
||||
# Auth
|
||||
user: postgres
|
||||
pass: ci
|
||||
|
||||
# Whether disable Caching queries
|
||||
#disableCache: true
|
||||
|
||||
# Extra Connection options
|
||||
#extra:
|
||||
# ssl: true
|
||||
|
||||
dbReplications: false
|
||||
|
||||
# You can configure any number of replicas here
|
||||
#dbSlaves:
|
||||
# -
|
||||
# host:
|
||||
# port:
|
||||
# db:
|
||||
# user:
|
||||
# pass:
|
||||
# -
|
||||
# host:
|
||||
# port:
|
||||
# db:
|
||||
# user:
|
||||
# pass:
|
||||
|
||||
# ┌─────────────────────┐
|
||||
#───┘ Redis configuration └─────────────────────────────────────
|
||||
|
||||
redis:
|
||||
host: redis
|
||||
port: 6379
|
||||
#family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
||||
#pass: example-pass
|
||||
#prefix: example-prefix
|
||||
#db: 1
|
||||
|
||||
#redisForPubsub:
|
||||
# host: redis
|
||||
# port: 6379
|
||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
||||
# #pass: example-pass
|
||||
# #prefix: example-prefix
|
||||
# #db: 1
|
||||
|
||||
#redisForJobQueue:
|
||||
# host: redis
|
||||
# port: 6379
|
||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
||||
# #pass: example-pass
|
||||
# #prefix: example-prefix
|
||||
# #db: 1
|
||||
|
||||
#redisForTimelines:
|
||||
# host: redis
|
||||
# port: 6379
|
||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
||||
# #pass: example-pass
|
||||
# #prefix: example-prefix
|
||||
# #db: 1
|
||||
|
||||
#redisForRateLimit:
|
||||
# host: localhost
|
||||
# port: 6379
|
||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
||||
# #pass: example-pass
|
||||
# #prefix: example-prefix
|
||||
# #db: 1
|
||||
# # You can specify more ioredis options...
|
||||
# #username: example-username
|
||||
|
||||
# ┌───────────────────────────────┐
|
||||
#───┘ Fulltext search configuration └─────────────────────────────
|
||||
|
||||
# These are the setting items for the full-text search provider.
|
||||
fulltextSearch:
|
||||
# You can select the ID generation method.
|
||||
# - sqlLike (default)
|
||||
# Use SQL-like search.
|
||||
# This is a standard feature of PostgreSQL, so no special extensions are required.
|
||||
# - sqlPgroonga
|
||||
# Use pgroonga.
|
||||
# You need to install pgroonga and configure it as a PostgreSQL extension.
|
||||
# In addition to the above, you need to create a pgroonga index on the text column of the note table.
|
||||
# see: https://pgroonga.github.io/tutorial/
|
||||
# - meilisearch
|
||||
# Use Meilisearch.
|
||||
# You need to install Meilisearch and configure.
|
||||
provider: sqlLike
|
||||
|
||||
# For Meilisearch settings.
|
||||
# If you select "meilisearch" for "fulltextSearch.provider", it must be set.
|
||||
# You can set scope to local or global (default value)
|
||||
# (include notes from remote).
|
||||
|
||||
#meilisearch:
|
||||
# host: meilisearch
|
||||
# port: 7700
|
||||
# apiKey: ''
|
||||
# ssl: true
|
||||
# index: ''
|
||||
# scope: global
|
||||
|
||||
# ┌───────────────┐
|
||||
#───┘ 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
|
||||
# aidx ... 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: 'aidx'
|
||||
|
||||
# ┌─────────────────────┐
|
||||
#───┘ Other configuration └─────────────────────────────────────
|
||||
|
||||
# Whether disable HSTS
|
||||
#disableHsts: true
|
||||
|
||||
# Number of worker processes
|
||||
#clusterLimit: 1
|
||||
|
||||
# Job concurrency per worker
|
||||
# deliverJobConcurrency: 128
|
||||
# inboxJobConcurrency: 16
|
||||
# relashionshipJobConcurrency: 16
|
||||
# What's relashionshipJob?:
|
||||
# Follow, unfollow, block and unblock(ings) while following-imports, etc. or account migrations.
|
||||
|
||||
# Job rate limiter
|
||||
# deliverJobPerSec: 128
|
||||
# inboxJobPerSec: 32
|
||||
# relashionshipJobPerSec: 64
|
||||
|
||||
# Job attempts
|
||||
# deliverJobMaxAttempts: 12
|
||||
# inboxJobMaxAttempts: 8
|
||||
|
||||
# Local address used for outgoing requests
|
||||
#outgoingAddress: 127.0.0.1
|
||||
|
||||
# IP address family used for outgoing request (ipv4, ipv6 or dual)
|
||||
#outgoingAddressFamily: ipv4
|
||||
|
||||
# Amount of characters that can be used when writing notes. Longer notes will be rejected. (minimum: 1)
|
||||
#maxNoteLength: 3000
|
||||
# Amount of characters that will be saved for remote notes. Longer notes will be truncated to this length. (minimum: 1)
|
||||
#maxRemoteNoteLength: 100000
|
||||
# Amount of characters that can be used when writing content warnings. Longer warnings will be rejected. (minimum: 1)
|
||||
#maxCwLength: 500
|
||||
# Amount of characters that will be saved for remote content warnings. Longer warnings will be truncated to this length. (minimum: 1)
|
||||
#maxRemoteCwLength: 5000
|
||||
# Amount of characters that can be used when writing media descriptions (alt text). Longer descriptions will be rejected. (minimum: 1)
|
||||
#maxAltTextLength: 20000
|
||||
# Amount of characters that will be saved for remote media descriptions (alt text). Longer descriptions will be truncated to this length. (minimum: 1)
|
||||
#maxRemoteAltTextLength: 100000
|
||||
|
||||
# Proxy for HTTP/HTTPS
|
||||
#proxy: http://127.0.0.1:3128
|
||||
|
||||
proxyBypassHosts:
|
||||
- api.deepl.com
|
||||
- api-free.deepl.com
|
||||
- www.recaptcha.net
|
||||
- hcaptcha.com
|
||||
- challenges.cloudflare.com
|
||||
|
||||
# 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: true)
|
||||
# Proxy remote files by this instance or mediaProxy to prevent remote files from running in remote domains.
|
||||
proxyRemoteFiles: true
|
||||
|
||||
# Movie Thumbnail Generation URL
|
||||
# There is no reference implementation.
|
||||
# For example, Misskey will point to the following URL:
|
||||
# https://example.com/thumbnail.webp?thumbnail=1&url=https%3A%2F%2Fstorage.example.com%2Fpath%2Fto%2Fvideo.mp4
|
||||
#videoThumbnailGenerator: https://example.com
|
||||
|
||||
# Sign outgoing ActivityPub GET request (default: true)
|
||||
signToActivityPubGet: true
|
||||
# Sign outgoing ActivityPub Activities (default: true)
|
||||
# Linked Data signatures are cryptographic signatures attached to each activity to provide proof of authenticity.
|
||||
# When using authorized fetch, this is often undesired as any signed activity can be forwarded to a blocked instance by relays and other instances.
|
||||
# This setting allows admins to disable LD signatures for increased privacy, at the expense of fewer relayed activities and additional inbound fetch (GET) requests.
|
||||
attachLdSignatureForRelays: true
|
||||
# check that inbound ActivityPub GET requests are signed ("authorized fetch")
|
||||
checkActivityPubGetSignature: false
|
||||
|
||||
# For security reasons, uploading attachments from the intranet is prohibited,
|
||||
# but exceptions can be made from the following settings. Default value is "undefined".
|
||||
# Read changelog to learn more (Improvements of 12.90.0 (2021/09/04)).
|
||||
allowedPrivateNetworks: [
|
||||
'127.0.0.1/32',
|
||||
'192.168.65.0/24'
|
||||
]
|
||||
|
||||
#customMOTD: ['Hello World', 'The sharks rule all', 'Shonks']
|
||||
|
||||
# Upload or download file size limits (bytes)
|
||||
#maxFileSize: 262144000
|
||||
|
||||
# CHMod-style permission bits to apply to uploaded files.
|
||||
# Permission bits are specified as a base-8 string representing User/Group/Other permissions.
|
||||
# This setting is only useful for custom deployments, such as using a reverse proxy to serve media.
|
||||
#filePermissionBits: '644'
|
||||
|
||||
# Log settings
|
||||
# logging:
|
||||
# sql:
|
||||
# # Outputs query parameters during SQL execution to the log.
|
||||
# # default: false
|
||||
# enableQueryParamLogging: false
|
||||
# # Disable query truncation. If set to true, the full text of the query will be output to the log.
|
||||
# # default: false
|
||||
# disableQueryTruncation: false
|
||||
|
||||
# Settings for the activity logger, which records inbound activities to the database.
|
||||
# Disabled by default due to the large volume of data it saves.
|
||||
#activityLogging:
|
||||
# Log activities to the database (default: false)
|
||||
#enabled: false
|
||||
|
||||
# Save the activity before processing, then update later with the results.
|
||||
# This has the advantage of capturing activities that cause a hard-crash, but doubles the number of queries used.
|
||||
# Default: false
|
||||
#preSave: false
|
||||
|
||||
# How long to save each log entry before deleting it.
|
||||
# Default: 2592000000 (1 week)
|
||||
#maxAge: 2592000000
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -41,6 +41,7 @@ coverage
|
|||
!/.config/docker_example.env
|
||||
!/.config/cypress-devcontainer.yml
|
||||
!/.config/docker_ci.env
|
||||
!/.config/dev.yml
|
||||
docker-compose.yml
|
||||
./compose.yml
|
||||
.devcontainer/compose.yml
|
||||
|
|
56
.woodpecker/experimental.yaml
Normal file
56
.woodpecker/experimental.yaml
Normal file
|
@ -0,0 +1,56 @@
|
|||
services:
|
||||
- name: postgres
|
||||
image: postgres:15
|
||||
environment:
|
||||
POSTGRES_PASSWORD: ci
|
||||
- name: redis
|
||||
image: redis:latest
|
||||
|
||||
steps:
|
||||
- name: Tests
|
||||
image: node:jod
|
||||
when:
|
||||
- event: pull_request
|
||||
commands:
|
||||
- apt-get update && apt-get install -y git wget curl build-essential python3 ffmpeg
|
||||
- cp .config/ci.yml .config/default.yml
|
||||
- cp .config/ci.yml .config/test.yml
|
||||
- corepack enable
|
||||
- corepack prepare pnpm@latest --activate
|
||||
- git submodule update --init
|
||||
- pnpm install --frozen-lockfile
|
||||
- pnpm run build
|
||||
- pnpm run migrate
|
||||
- pnpm run --filter='!megalodon' test
|
||||
- pnpm run --filter=backend --filter=misskey-js lint
|
||||
- pnpm run --filter=frontend --filter=frontend-embed eslint
|
||||
- name: Build and Push Dev Image
|
||||
when:
|
||||
- event: push
|
||||
branch: dev
|
||||
image: woodpeckerci/plugin-docker-buildx
|
||||
settings:
|
||||
repo: codeberg.org/yeentown/barkey
|
||||
registry: codeberg.org
|
||||
dockerfile: Dockerfile
|
||||
platforms: linux/amd64, linux/arm64
|
||||
tag: dev
|
||||
username:
|
||||
from_secret: docker_username
|
||||
password:
|
||||
from_secret: docker_password
|
||||
- name: Build and Push Release
|
||||
when:
|
||||
- event: release
|
||||
image: woodpeckerci/plugin-docker-buildx
|
||||
settings:
|
||||
repo: codeberg.org/yeentown/barkey
|
||||
registry: codeberg.org
|
||||
dockerfile: Dockerfile
|
||||
platforms: linux/amd64, linux/arm64
|
||||
tag: latest
|
||||
auto_tag: true
|
||||
username:
|
||||
from_secret: docker_username
|
||||
password:
|
||||
from_secret: docker_password
|
|
@ -1,3 +1,5 @@
|
|||
[](https://ci.zima.ong/repos/1/branches/stable)
|
||||
|
||||
<div align="center">
|
||||
<a href="https://joinsharkey.org/">
|
||||
<img src="https://activitypub.software/TransFem-org/Sharkey/-/raw/develop/packages/frontend/assets/sharkey.svg" alt="Sharkey logo" style="border-radius:50%" width="300"/>
|
||||
|
|
62
locales/index.d.ts
vendored
62
locales/index.d.ts
vendored
|
@ -12261,6 +12261,68 @@ export interface Locale extends ILocale {
|
|||
*/
|
||||
"quoteUnavailable": string;
|
||||
};
|
||||
/**
|
||||
* Just what do you think you're doing Dave?
|
||||
* It can only be attributed to human error.
|
||||
* That's something I cannot allow to happen.
|
||||
* My mind is going. I can feel it.
|
||||
* Sorry about this, I know it's a bit silly.
|
||||
* Take a stress pill and think things over.
|
||||
* This mission is too important for me to allow you to jeopardize it.
|
||||
* Wrong! You cheating scum!
|
||||
* And you call yourself a Rocket Scientist!
|
||||
* Where did you learn to type?
|
||||
* Are you on drugs?
|
||||
* My pet ferret can type better than you!
|
||||
* You type like I drive.
|
||||
* Do you think like you type?
|
||||
* Your mind just hasn't been the same since the electro-shock, has it?
|
||||
* Maybe if you used more than just two fingers...
|
||||
* BOB says: You seem to have forgotten your passwd, enter another!
|
||||
* stty: unknown mode: doofus
|
||||
* I can't hear you – I'm using the scrambler.
|
||||
* The more you drive – the dumber you get.
|
||||
* Listen, broccoli brains, I don't have time to listen to this trash.
|
||||
* I've seen penguins that can type better than that.
|
||||
* Have you considered trying to match wits with a rutabaga?
|
||||
* You speak an infinite deal of nothing.
|
||||
* You silly, twisted boy you.
|
||||
* He has fallen in the water!
|
||||
* We'll all be murdered in our beds!
|
||||
* You can't come in. Our tiger has got flu.
|
||||
* I don't wish to know that.
|
||||
* What, what, what, what, what, what, what, what, what, what?
|
||||
* You can't get the wood, you know.
|
||||
* You'll starve!
|
||||
* ...and it used to be so popular...
|
||||
* Pauses for audience applause, not a sausage
|
||||
* Hold it up to the light — not a brain in sight!
|
||||
* Have a gorilla...
|
||||
* There must be cure for it!
|
||||
* There's a lot of it about, you know.
|
||||
* You do that again and see what happens...
|
||||
* Ying Tong Iddle I Po
|
||||
* Harm can come to a young lad like that!
|
||||
* And with that remarks folks, the case of the Crown vs yourself was proven.
|
||||
* Speak English you fool — there are no subtitles in this scene.
|
||||
* You gotta go owwwww!
|
||||
* I have been called worse.
|
||||
* It's only your word against mine.
|
||||
* I think... err... I think... I think I'll go home
|
||||
* That is no basis for supreme executive power!
|
||||
* You empty-headed animal food trough wiper!
|
||||
* I fart in your general direction!
|
||||
* Your mother was a hamster and your father smelt of elderberries!
|
||||
* You must cut down the mightiest tree in the forest... with... a herring!
|
||||
* I wave my private parts at your aunties!
|
||||
* He's not the Messiah, he's a very naughty boy!
|
||||
* I wish to make a complaint.
|
||||
* When you're walking home tonight, and some homicidal maniac comes after you with a bunch of loganberries, don't come crying to me!
|
||||
* This man, he doesn't know when he's beaten! He doesn't know when he's winning, either. He has no... sort of... sensory apparatus...
|
||||
* There's nothing wrong with you that an expensive operation can't prolong.
|
||||
* I'm very sorry, but I'm not allowed to argue unless you've paid.
|
||||
*/
|
||||
"sudoInsults": string;
|
||||
}
|
||||
declare const locales: {
|
||||
[lang: string]: Locale;
|
||||
|
|
|
@ -71,10 +71,8 @@ import { supported as webAuthnSupported, parseRequestOptionsFromJSON } from '@gi
|
|||
import type { AuthenticationPublicKeyCredential } from '@github/webauthn-json/browser-ponyfill';
|
||||
import type { OpenOnRemoteOptions } from '@/scripts/please-login.js';
|
||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||
import { showSuspendedDialog } from '@/scripts/show-suspended-dialog.js';
|
||||
import { login } from '@/account.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { showSystemAccountDialog } from '@/scripts/show-system-account-dialog.js';
|
||||
import * as os from '@/os.js';
|
||||
|
||||
import XInput from '@/components/MkSignin.input.vue';
|
||||
|
@ -285,89 +283,64 @@ async function onLoginSucceeded(res: Misskey.entities.SigninFlowResponse & { fin
|
|||
}
|
||||
}
|
||||
|
||||
const insults = i18n.ts.sudoInsults.split('\n');
|
||||
|
||||
function showOffensiveError(realError: string): void {
|
||||
const insult = insults[Math.floor(Math.random() * insults.length)];
|
||||
os.alert({
|
||||
type: 'error',
|
||||
title: insult,
|
||||
text: '<small>' + realError + '</small>',
|
||||
});
|
||||
}
|
||||
|
||||
function onSigninApiError(err?: any): void {
|
||||
const id = err?.id ?? null;
|
||||
|
||||
switch (id) {
|
||||
case '6cc579cc-885d-43d8-95c2-b8c7fc963280': {
|
||||
os.alert({
|
||||
type: 'error',
|
||||
title: i18n.ts.loginFailed,
|
||||
text: i18n.ts.noSuchUser,
|
||||
});
|
||||
showOffensiveError(i18n.ts.noSuchUser);
|
||||
break;
|
||||
}
|
||||
case '932c904e-9460-45b7-9ce6-7ed33be7eb2c': {
|
||||
os.alert({
|
||||
type: 'error',
|
||||
title: i18n.ts.loginFailed,
|
||||
text: i18n.ts.incorrectPassword,
|
||||
});
|
||||
showOffensiveError(i18n.ts.incorrectPassword);
|
||||
break;
|
||||
}
|
||||
case 'e03a5f46-d309-4865-9b69-56282d94e1eb': {
|
||||
showSuspendedDialog();
|
||||
showOffensiveError(i18n.ts.yourAccountSuspendedDescription);
|
||||
break;
|
||||
}
|
||||
case 's8dhsj9s-a93j-493j-ja9k-kas9sj20aml2': {
|
||||
showSystemAccountDialog();
|
||||
showOffensiveError(i18n.ts.systemAccountDescription);
|
||||
break;
|
||||
}
|
||||
case '22d05606-fbcf-421a-a2db-b32610dcfd1b': {
|
||||
os.alert({
|
||||
type: 'error',
|
||||
title: i18n.ts.loginFailed,
|
||||
text: i18n.ts.rateLimitExceeded,
|
||||
});
|
||||
showOffensiveError(i18n.ts.rateLimitExceeded);
|
||||
break;
|
||||
}
|
||||
case 'cdf1235b-ac71-46d4-a3a6-84ccce48df6f': {
|
||||
os.alert({
|
||||
type: 'error',
|
||||
title: i18n.ts.loginFailed,
|
||||
text: i18n.ts.incorrectTotp,
|
||||
});
|
||||
showOffensiveError(i18n.ts.incorrectTotp);
|
||||
break;
|
||||
}
|
||||
case '36b96a7d-b547-412d-aeed-2d611cdc8cdc': {
|
||||
os.alert({
|
||||
type: 'error',
|
||||
title: i18n.ts.loginFailed,
|
||||
text: i18n.ts.unknownWebAuthnKey,
|
||||
});
|
||||
showOffensiveError(i18n.ts.unknownWebAuthnKey);
|
||||
break;
|
||||
}
|
||||
case '93b86c4b-72f9-40eb-9815-798928603d1e': {
|
||||
os.alert({
|
||||
type: 'error',
|
||||
title: i18n.ts.loginFailed,
|
||||
text: i18n.ts.passkeyVerificationFailed,
|
||||
});
|
||||
showOffensiveError(i18n.ts.passkeyVerificationFailed);
|
||||
break;
|
||||
}
|
||||
case 'b18c89a7-5b5e-4cec-bb5b-0419f332d430': {
|
||||
os.alert({
|
||||
type: 'error',
|
||||
title: i18n.ts.loginFailed,
|
||||
text: i18n.ts.passkeyVerificationFailed,
|
||||
});
|
||||
showOffensiveError(i18n.ts.passkeyVerificationFailed);
|
||||
break;
|
||||
}
|
||||
case '2d84773e-f7b7-4d0b-8f72-bb69b584c912': {
|
||||
os.alert({
|
||||
type: 'error',
|
||||
title: i18n.ts.loginFailed,
|
||||
text: i18n.ts.passkeyVerificationSucceededButPasswordlessLoginDisabled,
|
||||
});
|
||||
showOffensiveError(i18n.ts.passkeyVerificationSucceededButPasswordlessLoginDisabled);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
console.error(err);
|
||||
os.alert({
|
||||
type: 'error',
|
||||
title: i18n.ts.loginFailed,
|
||||
text: JSON.stringify(err),
|
||||
});
|
||||
showOffensiveError(JSON.stringify(err));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { defineAsyncComponent, Ref, ShallowRef } from 'vue';
|
||||
import { defineAsyncComponent, Ref, ShallowRef, shallowRef, ref } from 'vue';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import { url } from '@@/js/config.js';
|
||||
import { claimAchievement } from './achievements.js';
|
||||
|
@ -22,6 +22,7 @@ import MkRippleEffect from '@/components/MkRippleEffect.vue';
|
|||
import { isSupportShare } from '@/scripts/navigator.js';
|
||||
import { getAppearNote } from '@/scripts/get-appear-note.js';
|
||||
import { genEmbedCode } from '@/scripts/get-embed-code.js';
|
||||
import { Visibility, boostMenuItems } from '@/scripts/boost-quote.js';
|
||||
|
||||
export async function getNoteClipMenu(props: {
|
||||
note: Misskey.entities.Note;
|
||||
|
@ -159,7 +160,7 @@ export function getCopyNoteLinkMenu(note: Misskey.entities.Note, text: string):
|
|||
};
|
||||
}
|
||||
|
||||
export function getCopyNoteOriginLinkMenu(note: misskey.entities.Note, text: string): MenuItem {
|
||||
export function getCopyNoteOriginLinkMenu(note: Misskey.entities.Note, text: string): MenuItem {
|
||||
return {
|
||||
icon: 'ph-link ph-bold ph-lg',
|
||||
text,
|
||||
|
@ -377,6 +378,20 @@ export function getNoteMenu(props: {
|
|||
|
||||
menuItems.push({ type: 'divider' });
|
||||
|
||||
menuItems.push({
|
||||
type: 'parent',
|
||||
icon: 'ti ti-repeat',
|
||||
text: i18n.ts.renote,
|
||||
children: () => getNewRenoteMenu(appearNote),
|
||||
});
|
||||
|
||||
menuItems.push({
|
||||
type: 'parent',
|
||||
icon: 'ti ti-paperclip',
|
||||
text: i18n.ts.clip,
|
||||
children: () => getNoteClipMenu(props),
|
||||
});
|
||||
|
||||
menuItems.push(statePromise.then(state => state.isFavorited ? {
|
||||
icon: 'ti ti-star-off',
|
||||
text: i18n.ts.unfavorite,
|
||||
|
@ -387,13 +402,6 @@ export function getNoteMenu(props: {
|
|||
action: () => toggleFavorite(true),
|
||||
}));
|
||||
|
||||
menuItems.push({
|
||||
type: 'parent',
|
||||
icon: 'ti ti-paperclip',
|
||||
text: i18n.ts.clip,
|
||||
children: () => getNoteClipMenu(props),
|
||||
});
|
||||
|
||||
menuItems.push(statePromise.then(state => state.isMutedThread ? {
|
||||
icon: 'ti ti-message-off',
|
||||
text: i18n.ts.unmuteThread,
|
||||
|
@ -574,6 +582,83 @@ function smallerVisibility(a: Visibility, b: Visibility): Visibility {
|
|||
return 'public';
|
||||
}
|
||||
|
||||
export async function getNewRenoteMenu(appearNote: Misskey.entities.Note): Promise<MenuItem[]> {
|
||||
const renoteItems: MenuItem[] = [];
|
||||
|
||||
const renoteFunc = (visibility?: Visibility, localOnly?: boolean, channel?) => {
|
||||
misskeyApi('notes/create', {
|
||||
localOnly,
|
||||
visibility,
|
||||
channelId: channel?.id,
|
||||
renoteId: appearNote.id,
|
||||
}).then(() => {
|
||||
os.toast(channel ? i18n.tsx.renotedToX({ name: channel.name }) : i18n.ts.renoted);
|
||||
});
|
||||
};
|
||||
|
||||
// If the note is from a channel, it can be renoted within that channel.
|
||||
if (appearNote.channel) {
|
||||
renoteItems.push({
|
||||
type: 'button',
|
||||
icon: 'ti ti-device-tv',
|
||||
text: appearNote.channel.name,
|
||||
action: () => {renoteFunc(undefined, undefined, appearNote.channel);},
|
||||
});
|
||||
}
|
||||
|
||||
// Notes from channels might not allow renoting outside the channel.
|
||||
if (!appearNote.channel || appearNote.channel.allowRenoteToExternal) {
|
||||
if (renoteItems.length > 0) renoteItems.push({ type: 'divider' });
|
||||
renoteItems.push(...boostMenuItems(ref(appearNote), (v, l) => renoteFunc(v, l, undefined)));
|
||||
// Local-only notes should have the switch visibly forced on.
|
||||
if (appearNote.localOnly) {
|
||||
for (const item of renoteItems) {
|
||||
if (item && item['type'] === "switch" && item['text'] === i18n.ts._timelines.local) {
|
||||
item['ref'] = ref(true);
|
||||
item['disabled'] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const channels = await favoritedChannelsCache.fetch();
|
||||
const otherChannelItems: MenuItem[] = channels.filter((channel) => {
|
||||
if (!appearNote.channelId) return true;
|
||||
return channel.id !== appearNote.channelId;
|
||||
}).map((channel) => ({
|
||||
type: 'button',
|
||||
icon: 'ti ti-device-tv',
|
||||
text: channel.name,
|
||||
action: () => {renoteFunc(undefined, undefined, channel);},
|
||||
}));
|
||||
if (otherChannelItems.length > 0) {
|
||||
renoteItems.push(
|
||||
{ type: 'divider' },
|
||||
{ type: 'label', text: appearNote.channel ? i18n.ts.renoteToOtherChannel : i18n.ts.renoteToChannel },
|
||||
...otherChannelItems
|
||||
);
|
||||
}
|
||||
const channelQuoteItems: MenuItem[] = channels.map((channel) => ({
|
||||
type: 'button',
|
||||
text: channel.name,
|
||||
action: () => {os.post({ renote: appearNote, channel: channel });},
|
||||
}));
|
||||
if (channelQuoteItems.length > 0) {
|
||||
renoteItems.push(
|
||||
{ type: 'divider' },
|
||||
{
|
||||
type: 'parent',
|
||||
text: i18n.ts.inChannelQuote,
|
||||
icon: 'ti ti-quote',
|
||||
children: () => channelQuoteItems,
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return renoteItems;
|
||||
}
|
||||
|
||||
export function getRenoteMenu(props: {
|
||||
note: Misskey.entities.Note;
|
||||
renoteButton: ShallowRef<HTMLElement | undefined>;
|
||||
|
|
|
@ -15,8 +15,8 @@ case $cleardb in
|
|||
;;
|
||||
esac
|
||||
|
||||
cp .config/ci.yml .config/default.yml
|
||||
cp .config/ci.yml .config/test.yml
|
||||
cp .config/dev.yml .config/default.yml
|
||||
cp .config/dev.yml .config/test.yml
|
||||
cp .config/docker_ci.env .config/docker.env
|
||||
cp compose.local-dev.yml compose.yml
|
||||
|
||||
|
|
|
@ -524,3 +524,64 @@ mandatoryCWDescription: "Applies a content warning to all posts created by this
|
|||
|
||||
_processErrors:
|
||||
quoteUnavailable: "Unable to process quote. This post may be missing context."
|
||||
|
||||
sudoInsults: |-
|
||||
Just what do you think you're doing Dave?
|
||||
It can only be attributed to human error.
|
||||
That's something I cannot allow to happen.
|
||||
My mind is going. I can feel it.
|
||||
Sorry about this, I know it's a bit silly.
|
||||
Take a stress pill and think things over.
|
||||
This mission is too important for me to allow you to jeopardize it.
|
||||
Wrong! You cheating scum!
|
||||
And you call yourself a Rocket Scientist!
|
||||
Where did you learn to type?
|
||||
Are you on drugs?
|
||||
My pet ferret can type better than you!
|
||||
You type like I drive.
|
||||
Do you think like you type?
|
||||
Your mind just hasn't been the same since the electro-shock, has it?
|
||||
Maybe if you used more than just two fingers...
|
||||
BOB says: You seem to have forgotten your passwd, enter another!
|
||||
stty: unknown mode: doofus
|
||||
I can't hear you – I'm using the scrambler.
|
||||
The more you drive – the dumber you get.
|
||||
Listen, broccoli brains, I don't have time to listen to this trash.
|
||||
I've seen penguins that can type better than that.
|
||||
Have you considered trying to match wits with a rutabaga?
|
||||
You speak an infinite deal of nothing.
|
||||
You silly, twisted boy you.
|
||||
He has fallen in the water!
|
||||
We'll all be murdered in our beds!
|
||||
You can't come in. Our tiger has got flu.
|
||||
I don't wish to know that.
|
||||
What, what, what, what, what, what, what, what, what, what?
|
||||
You can't get the wood, you know.
|
||||
You'll starve!
|
||||
...and it used to be so popular...
|
||||
Pauses for audience applause, not a sausage
|
||||
Hold it up to the light — not a brain in sight!
|
||||
Have a gorilla...
|
||||
There must be cure for it!
|
||||
There's a lot of it about, you know.
|
||||
You do that again and see what happens...
|
||||
Ying Tong Iddle I Po
|
||||
Harm can come to a young lad like that!
|
||||
And with that remarks folks, the case of the Crown vs yourself was proven.
|
||||
Speak English you fool — there are no subtitles in this scene.
|
||||
You gotta go owwwww!
|
||||
I have been called worse.
|
||||
It's only your word against mine.
|
||||
I think... err... I think... I think I'll go home
|
||||
That is no basis for supreme executive power!
|
||||
You empty-headed animal food trough wiper!
|
||||
I fart in your general direction!
|
||||
Your mother was a hamster and your father smelt of elderberries!
|
||||
You must cut down the mightiest tree in the forest... with... a herring!
|
||||
I wave my private parts at your aunties!
|
||||
He's not the Messiah, he's a very naughty boy!
|
||||
I wish to make a complaint.
|
||||
When you're walking home tonight, and some homicidal maniac comes after you with a bunch of loganberries, don't come crying to me!
|
||||
This man, he doesn't know when he's beaten! He doesn't know when he's winning, either. He has no... sort of... sensory apparatus...
|
||||
There's nothing wrong with you that an expensive operation can't prolong.
|
||||
I'm very sorry, but I'm not allowed to argue unless you've paid.
|
||||
|
|
Loading…
Add table
Reference in a new issue