Compare commits
29 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
393c6aa79a | ||
![]() |
fc05540404 | ||
![]() |
1c589c7c18 | ||
![]() |
284df27435 | ||
![]() |
cd80e02ebf | ||
![]() |
dffcefb81f | ||
![]() |
7e1cad3e12 | ||
![]() |
fd3f4c37a0 | ||
![]() |
3acd2e0f0c | ||
![]() |
b1b5a795c8 | ||
![]() |
197e2c8377 | ||
![]() |
fb8b0c291d | ||
![]() |
706d47ec32 | ||
![]() |
4eab2b3654 | ||
![]() |
0a78f560e0 | ||
![]() |
f6f79fb388 | ||
![]() |
34235d4d44 | ||
![]() |
21842ec190 | ||
![]() |
026e1cc7e7 | ||
![]() |
c65f4eebaf | ||
![]() |
17baf8770a | ||
![]() |
01f60edb17 | ||
![]() |
15b11e59f4 | ||
![]() |
a2db4db963 | ||
![]() |
e87b9cc019 | ||
![]() |
54cb94db1d | ||
![]() |
1de8e1eeb1 | ||
![]() |
1d8fb65959 | ||
![]() |
28482627f7 |
@@ -1,9 +1,10 @@
|
||||
ChangeLog
|
||||
=========
|
||||
|
||||
破壊的変更のみ記載。
|
||||
|
||||
This document describes breaking changes only.
|
||||
10.62.2
|
||||
-------
|
||||
* バグ修正
|
||||
* ユーザビリティの向上
|
||||
|
||||
10.0.0
|
||||
------
|
||||
|
@@ -990,6 +990,12 @@ desktop/views/components/sub-note-content.vue:
|
||||
media-count: "{}つのメディア"
|
||||
poll: "アンケート"
|
||||
|
||||
desktop/views/components/settings.tags.vue:
|
||||
title: "タグ"
|
||||
query: "クエリ (省略可)"
|
||||
add: "追加"
|
||||
save: "保存"
|
||||
|
||||
desktop/views/components/taskmanager.vue:
|
||||
title: "タスクマネージャ"
|
||||
|
||||
|
@@ -297,8 +297,8 @@ common/views/components/theme.vue:
|
||||
common/views/components/cw-button.vue:
|
||||
hide: "숨기기"
|
||||
show: "더 보기"
|
||||
chars: "{count}文字"
|
||||
files: "{count}ファイル"
|
||||
chars: "{count}문자"
|
||||
files: "{count}파일"
|
||||
common/views/components/messaging.vue:
|
||||
search-user: "사용자 찾기"
|
||||
you: "당신"
|
||||
@@ -875,7 +875,7 @@ common/views/components/password-settings.vue:
|
||||
enter-new-password-again: "다시 한 번 새 비밀번호를 입력하여 주십시오"
|
||||
not-match: "새 비밀번호가 일치하지 않습니다"
|
||||
changed: "비밀번호를 변경하였습니다"
|
||||
failed: "パスワード変更に失敗しました"
|
||||
failed: "비밀번호 변경을 실패하였습니다."
|
||||
desktop/views/components/sub-note-content.vue:
|
||||
private: "이 글은 비공개입니다"
|
||||
deleted: "이 글은 삭제되었습니다"
|
||||
|
@@ -116,20 +116,20 @@ common:
|
||||
disable-animated-mfm: "Wyłącz animowany tekst we wpisach"
|
||||
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
||||
always-show-nsfw: "常に閲覧注意のメディアを表示する"
|
||||
always-mark-nsfw: "Zawsze oznaczaj posty z multimediom jako NSFW"
|
||||
always-mark-nsfw: "Zawsze oznaczaj posty z multimediami jako NSFW"
|
||||
show-full-acct: "ユーザー名のホストを省略しない"
|
||||
show-via: "viaを表示する"
|
||||
reduce-motion: "UIの動きを減らす"
|
||||
this-setting-is-this-device-only: "このデバイスのみ"
|
||||
use-os-default-emojis: "OS標準の絵文字を使用"
|
||||
use-os-default-emojis: "Użyj domyślnych Emoji systemowych"
|
||||
do-not-use-in-production: 'これは開発ビルドです。本番環境で使用しないでください。'
|
||||
is-remote-user: "Informacje o użytkowniku są kopiowane."
|
||||
is-remote-post: "この投稿情報はコピーです。"
|
||||
view-on-remote: "正確な情報を見る"
|
||||
renoted-by: "{user}がRenote"
|
||||
error:
|
||||
title: '問題が発生しました'
|
||||
retry: 'やり直す'
|
||||
title: 'Coś poszło nie tak'
|
||||
retry: 'Ponów próbę'
|
||||
reversi:
|
||||
drawn: "Remis"
|
||||
my-turn: "Twoja kolej"
|
||||
@@ -263,20 +263,20 @@ common/views/components/theme.vue:
|
||||
light-theme: "非ダークモード時に使用するテーマ"
|
||||
dark-theme: "ダークモード時に使用するテーマ"
|
||||
light-themes: "明るいテーマ"
|
||||
dark-themes: "暗いテーマ"
|
||||
dark-themes: "Ciemny motyw"
|
||||
install-a-theme: "Zainstaluj motyw"
|
||||
theme-code: "テーマコード"
|
||||
install: "インストール"
|
||||
installed: "「{}」をインストールしました"
|
||||
theme-code: "Kod motywu"
|
||||
install: "Zainstaluj"
|
||||
installed: "\"{}\" został zainstalowany"
|
||||
create-a-theme: "Stwórz motyw"
|
||||
save-created-theme: "テーマを保存"
|
||||
save-created-theme: "Zapisz motyw"
|
||||
primary-color: "Kolor podstawowy"
|
||||
secondary-color: "Kolor dodatkowy"
|
||||
text-color: "Kolor tekstu"
|
||||
base-theme: "Podstawowy motyw"
|
||||
base-theme-light: "Light"
|
||||
base-theme-dark: "Dark"
|
||||
theme-name: "テーマ名"
|
||||
base-theme-light: "Jasny"
|
||||
base-theme-dark: "Ciemny"
|
||||
theme-name: "Nazwa motywu"
|
||||
preview-created-theme: "プレビュー"
|
||||
invalid-theme: "テーマが正しくありません。"
|
||||
already-installed: "既にそのテーマはインストールされています。"
|
||||
@@ -288,8 +288,8 @@ common/views/components/theme.vue:
|
||||
select-theme: "テーマを選択してください"
|
||||
uninstall: "アンインストール"
|
||||
uninstalled: "「{}」をアンインストールしました"
|
||||
author: "作者"
|
||||
desc: "説明"
|
||||
author: "Author"
|
||||
desc: "Opis"
|
||||
export: "エクスポート"
|
||||
import: "インポート"
|
||||
import-by-code: "lub wklej kod"
|
||||
@@ -328,12 +328,12 @@ common/views/components/nav.vue:
|
||||
develop: "Autorzy"
|
||||
feedback: "Podziel się opinią"
|
||||
common/views/components/note-menu.vue:
|
||||
detail: "詳細"
|
||||
copy-link: "リンクをコピー"
|
||||
detail: "Szczegóły"
|
||||
copy-link: "Skopiuj adres"
|
||||
favorite: "Dodaj do ulubionych"
|
||||
unfavorite: "お気に入り解除"
|
||||
unfavorite: "Usuń z ulubionych"
|
||||
pin: "Przypnij do profilu"
|
||||
unpin: "ピン留め解除"
|
||||
unpin: "Odepnij"
|
||||
delete: "Usuń"
|
||||
delete-confirm: "Czy na pewno chcesz usunąć ten wpis?"
|
||||
remote: "Pokaż oryginał"
|
||||
@@ -453,13 +453,13 @@ common/views/components/profile-editor.vue:
|
||||
account: "Konto"
|
||||
location: "Lokalizacja"
|
||||
description: "O mnie"
|
||||
language: "言語"
|
||||
birthday: "誕生日"
|
||||
language: "Język"
|
||||
birthday: "Data urodzenia"
|
||||
avatar: "Awatar"
|
||||
banner: "バナー"
|
||||
banner: "Baner"
|
||||
is-cat: "To konto jest prowadzone przez kota"
|
||||
is-bot: "To konto jest prowadzone przez bota"
|
||||
is-locked: "フォローを承認制にする"
|
||||
is-locked: "Żądanania śledzenia wymagają zatwierdzenia"
|
||||
careful-bot: "Botからのフォローだけ承認制にする"
|
||||
advanced: "Inne"
|
||||
privacy: "Prywatność"
|
||||
@@ -740,7 +740,7 @@ desktop/views/components/settings.vue:
|
||||
fetch-on-scroll: "Automatycznie ładuj po przeciągnięciu w dół"
|
||||
fetch-on-scroll-desc: "Po przewinięciu na dół strony automatycznie zostaną załadowane nowe treści."
|
||||
note-visibility: "Widoczność wpisów"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
default-note-visibility: "Domyślna widoczność"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
web-search-engine: "ウェブ検索エンジン"
|
||||
web-search-engine-desc: "例: https://www.google.com/?#q={{query}}"
|
||||
@@ -774,7 +774,7 @@ desktop/views/components/settings.vue:
|
||||
deck-column-align: "デッキのカラムの配置"
|
||||
deck-column-align-center: "中央"
|
||||
deck-column-align-left: "左"
|
||||
deck-column-align-flexible: "フレキシブル"
|
||||
deck-column-align-flexible: "Elastyczne"
|
||||
deck-column-width: "デッキのカラムの幅"
|
||||
deck-column-width-narrow: "狭"
|
||||
deck-column-width-narrower: "やや狭"
|
||||
@@ -843,13 +843,13 @@ common/views/components/api-settings.vue:
|
||||
regeneration-of-token: "万が一このトークンが漏れたりその可能性がある場合はトークンを再生成できます。"
|
||||
regenerate-token: "トークンを再生成"
|
||||
token: "Token:"
|
||||
enter-password: "パスワードを入力してください"
|
||||
enter-password: "Wprowadź hasło"
|
||||
console:
|
||||
title: 'Konsola API'
|
||||
endpoint: 'エンドポイント'
|
||||
parameter: 'パラメータ'
|
||||
parameter: 'Parametry'
|
||||
credential-info: "「i」パラメータは自動で付与されます。"
|
||||
send: '送信'
|
||||
send: 'Wyślij'
|
||||
sending: '応答待ち'
|
||||
response: '結果'
|
||||
desktop/views/components/settings.apps.vue:
|
||||
@@ -860,11 +860,11 @@ common/views/components/drive-settings.vue:
|
||||
stats: "Statystyki"
|
||||
common/views/components/mute-and-block.vue:
|
||||
mute-and-block: "Wyczisz / Zablokuj"
|
||||
mute: "ミュート"
|
||||
mute: "Wycisz"
|
||||
block: "ブロック"
|
||||
no-muted-users: "Brak wyciszonych użytkowników"
|
||||
no-blocked-users: "Brak zablokowanych użytkowników"
|
||||
word-mute: "ワードミュート"
|
||||
word-mute: "Wyciszenie słowa"
|
||||
muted-words: "ミュートされたキーワード"
|
||||
muted-words-description: "スペースで区切るとAND指定になり、改行で区切るとOR指定になります"
|
||||
save: "Zapisz"
|
||||
@@ -904,7 +904,7 @@ desktop/views/components/ui.header.account.vue:
|
||||
lists: "Listy"
|
||||
follow-requests: "Prośby o śledzenie"
|
||||
customize: "Dostosuj stronę główną"
|
||||
admin: "管理"
|
||||
admin: "Admin"
|
||||
settings: "Ustawienia"
|
||||
signout: "Wyloguj się"
|
||||
dark: "Sprowadź ciemność"
|
||||
@@ -940,10 +940,10 @@ desktop/views/components/window.vue:
|
||||
popout: "Pop-out"
|
||||
close: "Zamknij"
|
||||
admin/views/index.vue:
|
||||
dashboard: "ダッシュボード"
|
||||
instance: "インスタンス"
|
||||
emoji: "カスタム絵文字"
|
||||
moderators: "モデレーター"
|
||||
dashboard: "Kokpit"
|
||||
instance: "Instancja"
|
||||
emoji: "Emoji"
|
||||
moderators: "Moderatorzy"
|
||||
users: "ユーザー"
|
||||
federation: "連合"
|
||||
announcements: "Ogłoszenia"
|
||||
@@ -1002,12 +1002,12 @@ admin/views/instance.vue:
|
||||
max-note-text-length: "投稿の最大文字数"
|
||||
disable-registration: "ユーザー登録の受付を停止する"
|
||||
disable-local-timeline: "ローカルタイムラインを無効にする"
|
||||
invite: "招待"
|
||||
invite: "Zaproś"
|
||||
save: "Zapisz"
|
||||
saved: "Zapisano"
|
||||
user-recommendation-config: "おすすめユーザー"
|
||||
user-recommendation-config: "Polecani użytkownicy"
|
||||
enable-external-user-recommendation: "外部ユーザーレコメンデーションを有効にする"
|
||||
external-user-recommendation-engine: "エンジン"
|
||||
external-user-recommendation-engine: "Silnik"
|
||||
external-user-recommendation-engine-desc: "例: https://vinayaka.distsn.org/cgi-bin/vinayaka-user-match-misskey-api.cgi?{{host}}+{{user}}+{{limit}}+{{offset}}"
|
||||
external-user-recommendation-timeout: "タイムアウト"
|
||||
external-user-recommendation-timeout-desc: "ミリ秒単位 (例: 300000)"
|
||||
@@ -1026,10 +1026,10 @@ admin/views/charts.vue:
|
||||
per-day: "1日ごと"
|
||||
per-hour: "1時間ごと"
|
||||
federation: "フェデレーション"
|
||||
notes: "投稿"
|
||||
users: "ユーザー"
|
||||
drive: "ドライブ"
|
||||
network: "ネットワーク"
|
||||
notes: "Wpisy"
|
||||
users: "Użytkownicy"
|
||||
drive: "Dysk"
|
||||
network: "Sieć"
|
||||
charts:
|
||||
federation-instances: "インスタンスの増減"
|
||||
federation-instances-total: "インスタンスの積算"
|
||||
@@ -1043,8 +1043,8 @@ admin/views/charts.vue:
|
||||
drive-total: "ドライブ使用量の積算"
|
||||
drive-files: "ドライブのファイル数の増減"
|
||||
drive-files-total: "ドライブのファイル数の積算"
|
||||
network-requests: "リクエスト"
|
||||
network-time: "応答時間"
|
||||
network-requests: "Żądania"
|
||||
network-time: "Czas reakcji"
|
||||
network-usage: "通信量"
|
||||
admin/views/users.vue:
|
||||
operation: "操作"
|
||||
@@ -1062,19 +1062,19 @@ admin/views/users.vue:
|
||||
unverify: "公式アカウントを解除する"
|
||||
unverified: "公式アカウントを解除しました"
|
||||
users:
|
||||
title: "ユーザー"
|
||||
title: "Użytkownicy"
|
||||
sort:
|
||||
title: "ソート"
|
||||
title: "Sortuj"
|
||||
createdAtAsc: "登録日時が古い順"
|
||||
createdAtDesc: "登録日時が新しい順"
|
||||
updatedAtAsc: "更新日時が古い順"
|
||||
updatedAtDesc: "更新日時が新しい順"
|
||||
origin:
|
||||
title: "オリジン"
|
||||
title: "Źródło"
|
||||
combined: "ローカル+リモート"
|
||||
local: "ローカル"
|
||||
remote: "リモート"
|
||||
createdAt: "登録日時"
|
||||
local: "Lokalny"
|
||||
remote: "Zdalny"
|
||||
createdAt: "Utworzono"
|
||||
updatedAt: "更新日時"
|
||||
admin/views/moderators.vue:
|
||||
add-moderator:
|
||||
@@ -1094,23 +1094,23 @@ admin/views/emoji.vue:
|
||||
added: "絵文字を登録しました"
|
||||
emojis:
|
||||
title: "絵文字一覧"
|
||||
update: "更新"
|
||||
remove: "削除"
|
||||
updated: "更新しました"
|
||||
update: "Aktualizuj"
|
||||
remove: "Usuń"
|
||||
updated: "Zaktualizowano"
|
||||
remove-emoji:
|
||||
are-you-sure: "「$1」を削除しますか?"
|
||||
removed: "削除しました"
|
||||
are-you-sure: "Usunąć \"$1\"?"
|
||||
removed: "Usunięto"
|
||||
admin/views/announcements.vue:
|
||||
announcements: "Ogłoszenia"
|
||||
save: "Zapisz"
|
||||
remove: "削除"
|
||||
add: "追加"
|
||||
title: "タイトル"
|
||||
remove: "Usuń"
|
||||
add: "Dodaj"
|
||||
title: "Tytuł"
|
||||
text: "内容"
|
||||
saved: "Zapisano"
|
||||
_remove:
|
||||
are-you-sure: "「$1」を削除しますか?"
|
||||
removed: "削除しました"
|
||||
are-you-sure: "Usunąć \"$1\"?"
|
||||
removed: "Usunięto"
|
||||
admin/views/hashtags.vue:
|
||||
hided-tags: "Hidden Tags"
|
||||
desktop/views/pages/welcome.vue:
|
||||
@@ -1179,9 +1179,9 @@ desktop/views/pages/user/user.header.vue:
|
||||
followers: "Śledzący"
|
||||
is-bot: "To konto jest botem"
|
||||
years-old: "{age} lat"
|
||||
year: "年"
|
||||
month: "月"
|
||||
day: "日"
|
||||
year: "/"
|
||||
month: "/"
|
||||
day: "-"
|
||||
desktop/views/pages/user/user.timeline.vue:
|
||||
default: "Wpisy"
|
||||
with-replies: "Wpisy i odpowiedzi"
|
||||
@@ -1309,7 +1309,7 @@ mobile/views/components/ui.nav.vue:
|
||||
game: "Gry"
|
||||
darkmode: "Tryb ciemny"
|
||||
settings: "Ustawienia"
|
||||
admin: "管理"
|
||||
admin: "Admin"
|
||||
about: "O Misskey"
|
||||
mobile/views/components/user-timeline.vue:
|
||||
no-notes: "Wygląda na to, że ten użytkownik nie opublikował jeszcze niczego"
|
||||
@@ -1382,13 +1382,13 @@ mobile/views/pages/settings.vue:
|
||||
post-style-standard: "Standardowy"
|
||||
post-style-smart: "Inteligentny"
|
||||
notification-position: "通知の表示"
|
||||
notification-position-bottom: "下"
|
||||
notification-position-top: "上"
|
||||
notification-position-bottom: "Dół"
|
||||
notification-position-top: "Góra"
|
||||
theme: "Motyw"
|
||||
behavior: "Zachowanie"
|
||||
fetch-on-scroll: "Automatycznie ładuj po przeciągnięciu w dół"
|
||||
note-visibility: "Widoczność wpisów"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
default-note-visibility: "Domyślna widoczność"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
web-search-engine: "ウェブ検索エンジン"
|
||||
web-search-engine-desc: "例: https://www.google.com/?#q={{query}}"
|
||||
@@ -1419,10 +1419,10 @@ mobile/views/pages/user.vue:
|
||||
timeline: "Oś czasu"
|
||||
media: "Multimedia"
|
||||
is-suspended: "To konto zostało zablokowane"
|
||||
mute: "ミュート"
|
||||
mute: "Wycisz"
|
||||
unmute: "ミュート解除"
|
||||
block: "ブロック"
|
||||
unblock: "ブロック解除"
|
||||
block: "Zablokuj"
|
||||
unblock: "Odblokuj"
|
||||
years-old: "{age} lat"
|
||||
push-to-list: "リストに追加"
|
||||
select-list: "Wybierz listę"
|
||||
@@ -1462,21 +1462,21 @@ deck:
|
||||
remove: "カラムを削除"
|
||||
add-column: "カラムを追加"
|
||||
rename: "Zmień nazwę"
|
||||
stack-left: "左に重ねる"
|
||||
stack-left: "Przypnij do lewej"
|
||||
pop-right: "右に出す"
|
||||
deck/deck.tl-column.vue:
|
||||
is-media-only: "メディア投稿のみ"
|
||||
is-media-view: "メディアビュー"
|
||||
edit: "オプション"
|
||||
is-media-only: "Tylko wpisy z zawartością multimedialną"
|
||||
is-media-view: "Widok multimediów"
|
||||
edit: "Opcje"
|
||||
deck/deck.user-column.vue:
|
||||
posts: "投稿"
|
||||
posts: "Wpisy"
|
||||
following: "フォロー"
|
||||
followers: "フォロワー"
|
||||
images: "画像"
|
||||
activity: "アクティビティ"
|
||||
timeline: "タイムライン"
|
||||
pinned-notes: "ピン留めされた投稿"
|
||||
push-to-a-list: "リストに追加"
|
||||
images: "Zdjęcia"
|
||||
activity: "Aktywność"
|
||||
timeline: "Oś czasu"
|
||||
pinned-notes: "Przypięte posty"
|
||||
push-to-a-list: "Dodaj do listy"
|
||||
docs:
|
||||
edit-this-page-on-github: "Znalazłeś błąd lub chcesz pomóc w tworzeniu dokumentacji?"
|
||||
edit-this-page-on-github-link: "Edytuj stronę na GitHubie!"
|
||||
@@ -1502,12 +1502,12 @@ docs:
|
||||
dev/views/index.vue:
|
||||
manage-apps: "Zarządzaj aplikacjami"
|
||||
dev/views/apps.vue:
|
||||
manage-apps: "アプリを管理"
|
||||
manage-apps: "Zarządzaj aplikacjami"
|
||||
create-app: "アプリ作成"
|
||||
app-missing: "アプリなし"
|
||||
app-missing: "Brak aplikacji"
|
||||
dev/views/new-app.vue:
|
||||
create-app: "アプリケーションの作成"
|
||||
app-name: "アプリケーション名"
|
||||
app-name: "Nazwa Aplikacji"
|
||||
app-name-desc: "あなたのアプリの名称。"
|
||||
app-name-ex: "ex) Misskey for iOS"
|
||||
app-overview: "アプリの概要"
|
||||
@@ -1515,7 +1515,7 @@ dev/views/new-app.vue:
|
||||
app-desc-ex: "ex) Misskey iOSクライアント。"
|
||||
callback-url: "コールバックURL (オプション)"
|
||||
callback-url-desc: "ユーザーが認証フォームで認証した際にリダイレクトするURLを設定できます。"
|
||||
authority: "権限"
|
||||
authority: "Uprawnienia"
|
||||
authority-desc: "ここで要求した機能だけがAPIからアクセスできます。"
|
||||
authority-warning: "アプリ作成後も変更できますが、新たな権限を付与する場合、その時点で関連付けられているユーザーキーはすべて無効になります。"
|
||||
account-read: "アカウントの情報を見る。"
|
||||
|
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "misskey",
|
||||
"author": "syuilo <i@syuilo.com>",
|
||||
"version": "10.62.1",
|
||||
"clientVersion": "2.0.12580",
|
||||
"version": "10.62.2",
|
||||
"clientVersion": "2.0.12609",
|
||||
"codename": "nighthike",
|
||||
"main": "./built/index.js",
|
||||
"private": true,
|
||||
|
@@ -61,11 +61,13 @@ export default abstract class Chart<T> {
|
||||
|
||||
constructor(name: string, grouped = false) {
|
||||
this.collection = db.get<Log<T>>(`chart.${name}`);
|
||||
if (grouped) {
|
||||
this.collection.createIndex({ span: -1, date: -1, group: -1 }, { unique: true });
|
||||
} else {
|
||||
this.collection.createIndex({ span: -1, date: -1 }, { unique: true });
|
||||
}
|
||||
const keys = {
|
||||
span: -1,
|
||||
date: -1
|
||||
};
|
||||
if (grouped)
|
||||
keys.group = -1;
|
||||
this.collection.createIndex(keys, { unique: true });
|
||||
}
|
||||
|
||||
@autobind
|
||||
|
@@ -77,11 +77,7 @@ export default {
|
||||
const matched = match(e, action.patterns);
|
||||
|
||||
if (matched) {
|
||||
if (el._hotkey_global) {
|
||||
if (match(e, targetReservedKeys)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (el._hotkey_global && match(e, targetReservedKeys)) return;
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
@@ -75,12 +75,10 @@ export default class Stream extends EventEmitter {
|
||||
|
||||
// チャンネル再接続
|
||||
if (isReconnect) {
|
||||
this.sharedConnectionPools.forEach(p => {
|
||||
for (const p of this.sharedConnectionPools)
|
||||
p.connect();
|
||||
});
|
||||
this.nonSharedConnections.forEach(c => {
|
||||
for (const c of this.nonSharedConnections)
|
||||
c.connect();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -10,7 +10,8 @@
|
||||
<misskey-flavored-markdown class="text" v-if="message.text" ref="text" :text="message.text" :i="$store.state.i"/>
|
||||
<div class="file" v-if="message.file">
|
||||
<a :href="message.file.url" target="_blank" :title="message.file.name">
|
||||
<img v-if="message.file.type.split('/')[0] == 'image'" :src="message.file.url" :alt="message.file.name"/>
|
||||
<img v-if="message.file.type.split('/')[0] == 'image'" :src="message.file.url" :alt="message.file.name"
|
||||
:style="{ backgroundColor: message.file.properties.avgColor && message.file.properties.avgColor.length == 3 ? `rgb(${message.file.properties.avgColor.join(',')})` : 'transparent' }"/>
|
||||
<p v-else>{{ message.file.name }}</p>
|
||||
</a>
|
||||
</div>
|
||||
@@ -150,7 +151,6 @@ export default Vue.extend({
|
||||
> a
|
||||
display block
|
||||
max-width 100%
|
||||
max-height 512px
|
||||
border-radius 16px
|
||||
overflow hidden
|
||||
text-decoration none
|
||||
@@ -165,7 +165,8 @@ export default Vue.extend({
|
||||
display block
|
||||
margin 0
|
||||
width 100%
|
||||
height 100%
|
||||
max-height 512px
|
||||
object-fit contain
|
||||
|
||||
> p
|
||||
padding 30px
|
||||
|
@@ -3,36 +3,21 @@ import { length } from 'stringz';
|
||||
import { Node } from '../../../../../mfm/parser';
|
||||
import parse from '../../../../../mfm/parse';
|
||||
import MkUrl from './url.vue';
|
||||
import { concat } from '../../../../../prelude/array';
|
||||
import { concat, sum } from '../../../../../prelude/array';
|
||||
import MkFormula from './formula.vue';
|
||||
import MkGoogle from './google.vue';
|
||||
import { toUnicode } from 'punycode';
|
||||
import syntaxHighlight from '../../../../../mfm/syntax-highlight';
|
||||
|
||||
function getTextCount(tokens: Node[]): number {
|
||||
let count = 0;
|
||||
const extract = (tokens: Node[]) => {
|
||||
tokens.filter(x => x.name === 'text').forEach(x => {
|
||||
count += length(x.props.text);
|
||||
});
|
||||
tokens.filter(x => x.children).forEach(x => {
|
||||
extract(x.children);
|
||||
});
|
||||
};
|
||||
extract(tokens);
|
||||
return count;
|
||||
const rootCount = sum(tokens.filter(x => x.name === 'text').map(x => length(x.props.text)));
|
||||
const childrenCount = sum(tokens.filter(x => x.children).map(x => getTextCount(x.children)));
|
||||
return rootCount + childrenCount;
|
||||
}
|
||||
|
||||
function getChildrenCount(tokens: Node[]): number {
|
||||
let count = 0;
|
||||
const extract = (tokens: Node[]) => {
|
||||
tokens.filter(x => x.children).forEach(x => {
|
||||
count++;
|
||||
extract(x.children);
|
||||
});
|
||||
};
|
||||
extract(tokens);
|
||||
return count;
|
||||
const countTree = tokens.filter(x => x.children).map(x => getChildrenCount(x.children));
|
||||
return countTree.length + sum(countTree);
|
||||
}
|
||||
|
||||
export default Vue.component('misskey-flavored-markdown', {
|
||||
@@ -69,14 +54,9 @@ export default Vue.component('misskey-flavored-markdown', {
|
||||
render(createElement) {
|
||||
if (this.text == null || this.text == '') return;
|
||||
|
||||
let ast: Node[];
|
||||
|
||||
if (this.ast == null) {
|
||||
// Parse text to ast
|
||||
ast = parse(this.text, this.plainText);
|
||||
} else {
|
||||
ast = this.ast as Node[];
|
||||
}
|
||||
const ast = this.ast == null ?
|
||||
parse(this.text, this.plainText) : // Parse text to ast
|
||||
this.ast as Node[];
|
||||
|
||||
let bigCount = 0;
|
||||
let motionCount = 0;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="ui-textarea" :class="{ focused, filled, tall }">
|
||||
<div class="ui-textarea" :class="{ focused, filled, tall, pre }">
|
||||
<div class="input">
|
||||
<span class="label" ref="label"><slot></slot></span>
|
||||
<textarea ref="input"
|
||||
@@ -46,6 +46,11 @@ export default Vue.extend({
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
pre: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -175,6 +180,11 @@ root(fill)
|
||||
> textarea
|
||||
min-height 200px
|
||||
|
||||
&.pre
|
||||
> .input
|
||||
> textarea
|
||||
white-space pre
|
||||
|
||||
.ui-textarea.fill
|
||||
root(true)
|
||||
|
||||
|
@@ -1,6 +1,3 @@
|
||||
import Vue from 'vue';
|
||||
|
||||
Vue.filter('number', (n) => {
|
||||
if (n == null) return 'N/A';
|
||||
return n.toLocaleString();
|
||||
});
|
||||
Vue.filter('number', n => n == null ? 'N/A' : n.toLocaleString());
|
||||
|
@@ -1,15 +1,15 @@
|
||||
<template>
|
||||
<div class="vfcitkilproprqtbnpoertpsziierwzi">
|
||||
<div v-for="timeline in timelines" class="timeline">
|
||||
<div v-for="timeline in timelines" class="timeline" :key="timeline.id">
|
||||
<ui-input v-model="timeline.title" @change="save">
|
||||
<span>{{ $t('title') }}</span>
|
||||
</ui-input>
|
||||
<ui-textarea :value="timeline.query ? timeline.query.map(tags => tags.join(' ')).join('\n') : ''" @input="onQueryChange(timeline, $event)">
|
||||
<ui-textarea :value="timeline.query ? timeline.query.map(tags => tags.join(' ')).join('\n') : ''" :pre="true" @input="onQueryChange(timeline, $event)">
|
||||
<span>{{ $t('query') }}</span>
|
||||
</ui-textarea>
|
||||
<ui-button class="save" @click="save">{{ $t('save') }}</ui-button>
|
||||
</div>
|
||||
<ui-button class="add" @click="add">{{ $t('add') }}</ui-button>
|
||||
<ui-button class="save" @click="save">{{ $t('save') }}</ui-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -33,12 +33,19 @@ export default Vue.extend({
|
||||
title: '',
|
||||
query: ''
|
||||
});
|
||||
|
||||
this.save();
|
||||
},
|
||||
|
||||
save() {
|
||||
this.$store.dispatch('settings/set', { key: 'tagTimelines', value: this.timelines });
|
||||
const timelines = this.timelines
|
||||
.filter(timeline => timeline.title)
|
||||
.map(timeline => {
|
||||
if (!(timeline.query && timeline.query[0] && timeline.query[0][0])) {
|
||||
timeline.query = timeline.title.split('\n').map(tags => tags.split(' '));
|
||||
}
|
||||
return timeline;
|
||||
});
|
||||
|
||||
this.$store.dispatch('settings/set', { key: 'tagTimelines', value: timelines });
|
||||
},
|
||||
|
||||
onQueryChange(timeline, value) {
|
||||
|
@@ -61,7 +61,7 @@ export default Vue.extend({
|
||||
this.connection = this.$root.stream.useSharedConnection('main');
|
||||
|
||||
this.connection.on('reversiInvited', this.onReversiInvited);
|
||||
this.connection.on('reversi_no_invites', this.onReversiNoInvites);
|
||||
this.connection.on('reversiNoInvites', this.onReversiNoInvites);
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
|
@@ -111,7 +111,7 @@ export default Vue.extend({
|
||||
this.connection = this.$root.stream.useSharedConnection('main');
|
||||
|
||||
this.connection.on('reversiInvited', this.onReversiInvited);
|
||||
this.connection.on('reversi_no_invites', this.onReversiNoInvites);
|
||||
this.connection.on('reversiNoInvites', this.onReversiNoInvites);
|
||||
}
|
||||
},
|
||||
|
||||
|
@@ -1,28 +0,0 @@
|
||||
<template>
|
||||
<a class="lkafjvabenanajk17kwqpsatoushincb" :href="`https://discordapp.com/users/${user.discord.id}`" target="_blank">
|
||||
<div>
|
||||
<span><fa :icon="['fab', 'discord']"/>@{{ user.discord.username }}#{{ user.discord.discriminator }}</span>
|
||||
</div>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
props: ['user']
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.lkafjvabenanajk17kwqpsatoushincb
|
||||
margin-left 8px
|
||||
color #fff
|
||||
|
||||
div
|
||||
padding 32px
|
||||
background #7289da
|
||||
border-radius 6px
|
||||
color #fff
|
||||
|
||||
</style>
|
@@ -1,28 +0,0 @@
|
||||
<template>
|
||||
<a class="aqooishiizumijmihokohinatamihoaz" :href="`https://github.com/${user.github.login}`" target="_blank">
|
||||
<div>
|
||||
<span><fa :icon="['fab', 'github']"/>@{{ user.github.login }}</span>
|
||||
</div>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
props: ['user']
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.aqooishiizumijmihokohinatamihoaz
|
||||
margin-left 8px
|
||||
color #fff
|
||||
|
||||
div
|
||||
padding 32px
|
||||
background #171515
|
||||
border-radius 6px
|
||||
color #fff
|
||||
|
||||
</style>
|
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<a :href="url" :class="service" target="_blank">
|
||||
<fa :icon="icon" size="lg" fixed-width />
|
||||
<div>{{ text }}</div>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
props: ['url', 'text', 'icon', 'service']
|
||||
});
|
||||
</script>
|
@@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<div class="usertwitxxxgithxxdiscxxxintegrat" :v-if="user.twitter || user.github || user.discord">
|
||||
<x-integration v-if="user.twitter" service="twitter" :url="`https://twitter.com/${user.twitter.screenName}`" :text="user.twitter.screenName" :icon="['fab', 'twitter']"/>
|
||||
<x-integration v-if="user.github" service="github" :url="`https://github.com/${user.github.login}`" :text="user.github.login" :icon="['fab', 'github']"/>
|
||||
<x-integration v-if="user.discord" service="discord" :url="`https://discordapp.com/users/${user.discord.id}`" :text="`${user.discord.username}#${user.discord.discriminator}`" :icon="['fab', 'discord']"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import XIntegration from './user.integrations.integration.vue';
|
||||
|
||||
export default Vue.extend({
|
||||
components: {
|
||||
XIntegration
|
||||
},
|
||||
props: ['user']
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.usertwitxxxgithxxdiscxxxintegrat
|
||||
> a
|
||||
display flex
|
||||
align-items center
|
||||
padding 32px 38px
|
||||
box-shadow var(--shadow)
|
||||
border-radius var(--round)
|
||||
|
||||
&:not(:last-child)
|
||||
margin-bottom 16px
|
||||
|
||||
&:hover
|
||||
text-decoration none
|
||||
|
||||
> div
|
||||
padding-left .2em
|
||||
line-height 1.3em
|
||||
flex 1 0
|
||||
word-wrap anywhere
|
||||
|
||||
&.twitter
|
||||
color #fff
|
||||
background #1da1f3
|
||||
|
||||
&:hover
|
||||
background #0c87cf
|
||||
|
||||
&.github
|
||||
color #fff
|
||||
background #171515
|
||||
|
||||
&:hover
|
||||
background #000
|
||||
|
||||
&.discord
|
||||
color #fff
|
||||
background #7289da
|
||||
|
||||
&:hover
|
||||
background #4968ce
|
||||
|
||||
</style>
|
@@ -1,28 +0,0 @@
|
||||
<template>
|
||||
<a class="adsvaidqfznoartcbplullnejvxjphcn" :href="`https://twitter.com/${user.twitter.screenName}`" target="_blank">
|
||||
<div>
|
||||
<span><fa :icon="['fab', 'twitter']"/>@{{ user.twitter.screenName }}</span>
|
||||
</div>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
props: ['user']
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.adsvaidqfznoartcbplullnejvxjphcn
|
||||
margin-left 8px
|
||||
color #fff
|
||||
|
||||
div
|
||||
padding 32px
|
||||
background #1a94f2
|
||||
border-radius 6px
|
||||
color #fff
|
||||
|
||||
</style>
|
@@ -12,9 +12,7 @@
|
||||
<div class="side">
|
||||
<div class="instance" v-if="!$store.getters.isSignedIn"><mk-instance/></div>
|
||||
<x-profile :user="user"/>
|
||||
<x-twitter :user="user" v-if="!user.host && user.twitter"/>
|
||||
<x-github :user="user" v-if="!user.host && user.github"/>
|
||||
<x-discord :user="user" v-if="!user.host && user.discord"/>
|
||||
<x-integrations :user="user" v-if="!user.host"/>
|
||||
<mk-calendar @chosen="warp" :start="new Date(user.createdAt)"/>
|
||||
<mk-activity :user="user"/>
|
||||
<x-photos :user="user"/>
|
||||
@@ -38,9 +36,7 @@ import XProfile from './user.profile.vue';
|
||||
import XPhotos from './user.photos.vue';
|
||||
import XFollowersYouKnow from './user.followers-you-know.vue';
|
||||
import XFriends from './user.friends.vue';
|
||||
import XTwitter from './user.twitter.vue';
|
||||
import XGithub from './user.github.vue'; // ?MEM: Don't fix the intentional typo. (XGitHub -> `<x-git-hub>`)
|
||||
import XDiscord from './user.discord.vue';
|
||||
import XIntegrations from './user.integrations.vue';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n(),
|
||||
@@ -51,9 +47,7 @@ export default Vue.extend({
|
||||
XPhotos,
|
||||
XFollowersYouKnow,
|
||||
XFriends,
|
||||
XTwitter,
|
||||
XGithub, // ?MEM: Don't fix the intentional typo. (see L41)
|
||||
XDiscord
|
||||
XIntegrations
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -87,7 +81,8 @@ export default Vue.extend({
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.xygkxeaeontfaokvqmiblezmhvhostak
|
||||
width 980px
|
||||
max-width 980px
|
||||
min-width 720px
|
||||
padding 16px
|
||||
margin 0 auto
|
||||
|
||||
|
@@ -385,9 +385,11 @@ export default (callback: (launch: (router: VueRouter) => [Vue, MiOS]) => void,
|
||||
const shadow = '0 3px 8px rgba(0, 0, 0, 0.2)';
|
||||
const shadowRight = '4px 0 4px rgba(0, 0, 0, 0.1)';
|
||||
const shadowLeft = '-4px 0 4px rgba(0, 0, 0, 0.1)';
|
||||
if (os.store.state.settings.useShadow) document.documentElement.style.setProperty('--shadow', shadow);
|
||||
if (os.store.state.settings.useShadow) document.documentElement.style.setProperty('--shadowRight', shadowRight);
|
||||
if (os.store.state.settings.useShadow) document.documentElement.style.setProperty('--shadowLeft', shadowLeft);
|
||||
if (os.store.state.settings.useShadow) {
|
||||
document.documentElement.style.setProperty('--shadow', shadow);
|
||||
document.documentElement.style.setProperty('--shadowRight', shadowRight);
|
||||
document.documentElement.style.setProperty('--shadowLeft', shadowLeft);
|
||||
}
|
||||
os.store.watch(s => {
|
||||
return s.settings.useShadow;
|
||||
}, v => {
|
||||
@@ -409,15 +411,7 @@ export default (callback: (launch: (router: VueRouter) => [Vue, MiOS]) => void,
|
||||
|
||||
// Navigation hook
|
||||
router.beforeEach((to, from, next) => {
|
||||
if (os.store.state.navHook) {
|
||||
if (os.store.state.navHook(to)) {
|
||||
next(false);
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
next(os.store.state.navHook && os.store.state.navHook(to) ? false : undefined);
|
||||
});
|
||||
|
||||
document.addEventListener('visibilitychange', () => {
|
||||
|
@@ -45,13 +45,15 @@ export default Vue.extend({
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.$store.commit('setUiHeaderHeight', this.$refs.root.offsetHeight);
|
||||
this.$nextTick(() => {
|
||||
this.$store.commit('setUiHeaderHeight', this.$refs.root.offsetHeight);
|
||||
});
|
||||
|
||||
if (this.$store.getters.isSignedIn) {
|
||||
this.connection = this.$root.stream.useSharedConnection('main');
|
||||
|
||||
this.connection.on('reversiInvited', this.onReversiInvited);
|
||||
this.connection.on('reversi_no_invites', this.onReversiNoInvites);
|
||||
this.connection.on('reversiNoInvites', this.onReversiNoInvites);
|
||||
}
|
||||
},
|
||||
|
||||
|
@@ -83,7 +83,7 @@ export default Vue.extend({
|
||||
this.connection = this.$root.stream.useSharedConnection('main');
|
||||
|
||||
this.connection.on('reversiInvited', this.onReversiInvited);
|
||||
this.connection.on('reversi_no_invites', this.onReversiNoInvites);
|
||||
this.connection.on('reversiNoInvites', this.onReversiNoInvites);
|
||||
}
|
||||
},
|
||||
|
||||
|
@@ -10,7 +10,7 @@
|
||||
</header>
|
||||
<div class="body">
|
||||
<div class="description">
|
||||
<misskey-flavored-markdown v-if="u.description" :text="u.description" :author="u" :i="$store.state.i" :custom-emojis="u.emojis"/>
|
||||
<misskey-flavored-markdown v-if="user.description" :text="user.description" :author="user" :i="$store.state.i" :custom-emojis="user.emojis"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -14,44 +14,44 @@ export default (tokens: Node[], mentionedRemoteUsers: INote['mentionedRemoteUser
|
||||
|
||||
const doc = window.document;
|
||||
|
||||
function dive(nodes: Node[]): any[] {
|
||||
return nodes.map(n => handlers[n.name](n));
|
||||
function appendChildren(children: Node[], targetElement: any): void {
|
||||
for (const child of children.map(n => handlers[n.name](n))) targetElement.appendChild(child);
|
||||
}
|
||||
|
||||
const handlers: { [key: string]: (token: Node) => any } = {
|
||||
bold(token) {
|
||||
const el = doc.createElement('b');
|
||||
dive(token.children).forEach(child => el.appendChild(child));
|
||||
appendChildren(token.children, el);
|
||||
return el;
|
||||
},
|
||||
|
||||
big(token) {
|
||||
const el = doc.createElement('strong');
|
||||
dive(token.children).forEach(child => el.appendChild(child));
|
||||
appendChildren(token.children, el);
|
||||
return el;
|
||||
},
|
||||
|
||||
small(token) {
|
||||
const el = doc.createElement('small');
|
||||
dive(token.children).forEach(child => el.appendChild(child));
|
||||
appendChildren(token.children, el);
|
||||
return el;
|
||||
},
|
||||
|
||||
strike(token) {
|
||||
const el = doc.createElement('del');
|
||||
dive(token.children).forEach(child => el.appendChild(child));
|
||||
appendChildren(token.children, el);
|
||||
return el;
|
||||
},
|
||||
|
||||
italic(token) {
|
||||
const el = doc.createElement('i');
|
||||
dive(token.children).forEach(child => el.appendChild(child));
|
||||
appendChildren(token.children, el);
|
||||
return el;
|
||||
},
|
||||
|
||||
motion(token) {
|
||||
const el = doc.createElement('i');
|
||||
dive(token.children).forEach(child => el.appendChild(child));
|
||||
appendChildren(token.children, el);
|
||||
return el;
|
||||
},
|
||||
|
||||
@@ -65,7 +65,7 @@ export default (tokens: Node[], mentionedRemoteUsers: INote['mentionedRemoteUser
|
||||
|
||||
center(token) {
|
||||
const el = doc.createElement('div');
|
||||
dive(token.children).forEach(child => el.appendChild(child));
|
||||
appendChildren(token.children, el);
|
||||
return el;
|
||||
},
|
||||
|
||||
@@ -96,7 +96,7 @@ export default (tokens: Node[], mentionedRemoteUsers: INote['mentionedRemoteUser
|
||||
link(token) {
|
||||
const a = doc.createElement('a');
|
||||
a.href = token.props.url;
|
||||
dive(token.children).forEach(child => a.appendChild(child));
|
||||
appendChildren(token.children, a);
|
||||
return a;
|
||||
},
|
||||
|
||||
@@ -111,13 +111,13 @@ export default (tokens: Node[], mentionedRemoteUsers: INote['mentionedRemoteUser
|
||||
|
||||
quote(token) {
|
||||
const el = doc.createElement('blockquote');
|
||||
dive(token.children).forEach(child => el.appendChild(child));
|
||||
appendChildren(token.children, el);
|
||||
return el;
|
||||
},
|
||||
|
||||
title(token) {
|
||||
const el = doc.createElement('h1');
|
||||
dive(token.children).forEach(child => el.appendChild(child));
|
||||
appendChildren(token.children, el);
|
||||
return el;
|
||||
},
|
||||
|
||||
@@ -126,11 +126,7 @@ export default (tokens: Node[], mentionedRemoteUsers: INote['mentionedRemoteUser
|
||||
const nodes = (token.props.text as string).split('\n').map(x => doc.createTextNode(x));
|
||||
|
||||
for (const x of intersperse('br', nodes)) {
|
||||
if (x === 'br') {
|
||||
el.appendChild(doc.createElement('br'));
|
||||
} else {
|
||||
el.appendChild(x);
|
||||
}
|
||||
el.appendChild(x === 'br' ? doc.createElement('br') : x);
|
||||
}
|
||||
|
||||
return el;
|
||||
@@ -151,9 +147,7 @@ export default (tokens: Node[], mentionedRemoteUsers: INote['mentionedRemoteUser
|
||||
}
|
||||
};
|
||||
|
||||
dive(tokens).forEach(x => {
|
||||
doc.body.appendChild(x);
|
||||
});
|
||||
appendChildren(tokens, doc.body);
|
||||
|
||||
return `<p>${doc.body.innerHTML}</p>`;
|
||||
};
|
||||
|
@@ -5,6 +5,7 @@ import unfollow from '../../../../services/following/delete';
|
||||
import cancelRequest from '../../../../services/following/requests/cancel';
|
||||
import { IFollow } from '../../type';
|
||||
import FollowRequest from '../../../../models/follow-request';
|
||||
import Following from '../../../../models/following';
|
||||
|
||||
export default async (actor: IRemoteUser, activity: IFollow): Promise<void> => {
|
||||
const id = typeof activity.object == 'string' ? activity.object : activity.object.id;
|
||||
@@ -30,9 +31,16 @@ export default async (actor: IRemoteUser, activity: IFollow): Promise<void> => {
|
||||
followeeId: followee._id
|
||||
});
|
||||
|
||||
const following = await Following.findOne({
|
||||
followerId: actor._id,
|
||||
followeeId: followee._id
|
||||
});
|
||||
|
||||
if (req) {
|
||||
await cancelRequest(followee, actor);
|
||||
} else {
|
||||
}
|
||||
|
||||
if (following) {
|
||||
await unfollow(actor, followee);
|
||||
}
|
||||
};
|
||||
|
@@ -66,7 +66,7 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||
});
|
||||
|
||||
if (other == 0) {
|
||||
publishMainStream(user._id, 'reversi_no_invites');
|
||||
publishMainStream(user._id, 'reversiNoInvites');
|
||||
}
|
||||
} else {
|
||||
// Fetch child
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import User, { IUser, isRemoteUser, ILocalUser, pack as packUser } from '../../../models/user';
|
||||
import User, { IUser, isRemoteUser, ILocalUser, pack as packUser, isLocalUser } from '../../../models/user';
|
||||
import FollowRequest from '../../../models/follow-request';
|
||||
import pack from '../../../remote/activitypub/renderer';
|
||||
import renderFollow from '../../../remote/activitypub/renderer/follow';
|
||||
@@ -9,6 +9,8 @@ import { publishMainStream } from '../../../stream';
|
||||
import perUserFollowingChart from '../../../chart/per-user-following';
|
||||
|
||||
export default async function(followee: IUser, follower: IUser) {
|
||||
let incremented = 1;
|
||||
|
||||
await Following.insert({
|
||||
createdAt: new Date(),
|
||||
followerId: follower._id,
|
||||
@@ -25,6 +27,13 @@ export default async function(followee: IUser, follower: IUser) {
|
||||
inbox: isRemoteUser(followee) ? followee.inbox : undefined,
|
||||
sharedInbox: isRemoteUser(followee) ? followee.sharedInbox : undefined
|
||||
}
|
||||
}).catch(e => {
|
||||
if (e.code === 11000 && isRemoteUser(follower) && isLocalUser(followee)) {
|
||||
console.log(`Accept => Insert duplicated ignore. ${follower._id} => ${followee._id}`);
|
||||
incremented = 0;
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
if (isRemoteUser(follower)) {
|
||||
@@ -45,7 +54,7 @@ export default async function(followee: IUser, follower: IUser) {
|
||||
//#region Increment following count
|
||||
await User.update({ _id: follower._id }, {
|
||||
$inc: {
|
||||
followingCount: 1
|
||||
followingCount: incremented
|
||||
}
|
||||
});
|
||||
//#endregion
|
||||
@@ -53,7 +62,7 @@ export default async function(followee: IUser, follower: IUser) {
|
||||
//#region Increment followers count
|
||||
await User.update({ _id: followee._id }, {
|
||||
$inc: {
|
||||
followersCount: 1
|
||||
followersCount: incremented
|
||||
}
|
||||
});
|
||||
//#endregion
|
||||
|
Reference in New Issue
Block a user