Compare commits
16 Commits
Author | SHA1 | Date | |
---|---|---|---|
ade1e40395 | |||
c93b8677e4 | |||
62683d8878 | |||
3d1239c1b4 | |||
5268bade66 | |||
514eb39a14 | |||
18628b821e | |||
344fbe6bcd | |||
afb8cd2dc1 | |||
1a5f385eb5 | |||
8df7864064 | |||
9ca60bad7f | |||
bd828bb072 | |||
892cb44d84 | |||
517ea6a119 | |||
ba8ffda32a |
10
CHANGELOG.md
10
CHANGELOG.md
@ -1,6 +1,16 @@
|
|||||||
ChangeLog
|
ChangeLog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
12.6.0 (2020/02/10)
|
||||||
|
--------------------
|
||||||
|
### ✨Improvements
|
||||||
|
* リンクにホバーするとURLプレビューを表示するように
|
||||||
|
* ユーザーページからグループに招待できるように
|
||||||
|
* ウィジェットはブラウザごとに記憶するように
|
||||||
|
|
||||||
|
### 🐛Fixes
|
||||||
|
* 要素の幅を判定する処理が上手くいかないことがある問題を修正
|
||||||
|
|
||||||
12.5.0 (2020/02/09)
|
12.5.0 (2020/02/09)
|
||||||
--------------------
|
--------------------
|
||||||
### ✨Improvements
|
### ✨Improvements
|
||||||
|
@ -214,12 +214,10 @@ remove: "Delete"
|
|||||||
removed: "Successfully deleted"
|
removed: "Successfully deleted"
|
||||||
removeAreYouSure: "Are you sure that you want to delete \"{x}\"?"
|
removeAreYouSure: "Are you sure that you want to delete \"{x}\"?"
|
||||||
saved: "Saved"
|
saved: "Saved"
|
||||||
messaging: "Talk"
|
messaging: "Messaging"
|
||||||
upload: "Upload"
|
upload: "Upload"
|
||||||
fromDrive: "From Drive"
|
fromDrive: "From Drive"
|
||||||
fromUrl: "From URL"
|
fromUrl: "From URL"
|
||||||
editWidgets: "Edit widgets"
|
|
||||||
exitEdit: "Finish editing"
|
|
||||||
explore: "Explore"
|
explore: "Explore"
|
||||||
games: "Misskey Games"
|
games: "Misskey Games"
|
||||||
messageRead: "Read"
|
messageRead: "Read"
|
||||||
@ -348,6 +346,7 @@ post: "Notes"
|
|||||||
posted: "Posted!"
|
posted: "Posted!"
|
||||||
autoReloadWhenDisconnected: "Auto reload when disconnected with server"
|
autoReloadWhenDisconnected: "Auto reload when disconnected with server"
|
||||||
autoNoteWatch: "Watch note automatically"
|
autoNoteWatch: "Watch note automatically"
|
||||||
|
autoNoteWatchDescription: "Get notified about the notes which you reactioned or replied."
|
||||||
reduceUiAnimation: "Reduce animations of User Interface"
|
reduceUiAnimation: "Reduce animations of User Interface"
|
||||||
share: "Share"
|
share: "Share"
|
||||||
notFound: "Not found"
|
notFound: "Not found"
|
||||||
@ -356,7 +355,7 @@ uploadFolder: "Default Upload location"
|
|||||||
cacheClear: "Clear cache"
|
cacheClear: "Clear cache"
|
||||||
markAsReadAllNotifications: "Mark all notifications as read"
|
markAsReadAllNotifications: "Mark all notifications as read"
|
||||||
markAsReadAllUnreadNotes: "Mark all notes as read"
|
markAsReadAllUnreadNotes: "Mark all notes as read"
|
||||||
markAsReadAllTalkMessages: "Mark all conversations as read"
|
markAsReadAllTalkMessages: "Mark all messages as read"
|
||||||
help: "Help"
|
help: "Help"
|
||||||
inputMessageHere: "Enter message here"
|
inputMessageHere: "Enter message here"
|
||||||
close: "Close"
|
close: "Close"
|
||||||
@ -369,6 +368,36 @@ invites: "Invite"
|
|||||||
groupName: "Group name"
|
groupName: "Group name"
|
||||||
members: "Members"
|
members: "Members"
|
||||||
transfer: "Transfer"
|
transfer: "Transfer"
|
||||||
|
messagingWithUser: "Messaging with other user"
|
||||||
|
messagingWithGroup: "Messaging within group"
|
||||||
|
enable: "Enable"
|
||||||
|
next: "Next"
|
||||||
|
retype: "Enter again"
|
||||||
|
noteOf: "{user}'s notes"
|
||||||
|
inviteToGroup: "Invite to group"
|
||||||
|
_tutorial:
|
||||||
|
title: "How to use Misskey"
|
||||||
|
step1_1: "Welcome!"
|
||||||
|
step1_2: "This page is called \"timeline\". It shows chronologically ordered \"notes\" of people who you \"follow\"."
|
||||||
|
step1_3: "Your timeline is currently empty, since you have not posed any notes or followed anyone yet."
|
||||||
|
step2_1: "Let's finish setting up your profile before writing a note or following anyone."
|
||||||
|
step2_2: "Providing some information about who you are will make it easier for others to follow you back."
|
||||||
|
step3_1: "Finished setting up your profile?"
|
||||||
|
step3_2: "The next step is to post a note. You can do this by pressing a pencil icon on the screen."
|
||||||
|
step3_3: "Fill in the modal and press the button on the right top to post."
|
||||||
|
step3_4: "Have nothing to say? Try \"I just started Misskey!\""
|
||||||
|
step4_1: "Finished posting your first note?"
|
||||||
|
step4_2: "Hurray! Now your first note is displayed on your timeline."
|
||||||
|
step5_1: "Now, let's try making your timeline more lively by following other people."
|
||||||
|
step5_2: "{featured} will show you trending notes in this instance. {explore} will let you find trending users. Try following people you like!"
|
||||||
|
step5_3: "To follow other users, click on their icon and press \"follow\" button on their profile."
|
||||||
|
step5_4: "If the other user has a lock icon next to their name, that user will have to manually approve your follow request."
|
||||||
|
step6_1: "Now you will be able to see other users' notes on your timeline."
|
||||||
|
step6_2: "You can also put \"reactions\" on other people's notes to quickly respond."
|
||||||
|
step6_3: "To attach a \"reaction\", press \"+\" mark on other user's note and choose an emoji you'd like to react with."
|
||||||
|
step7_1: "Congratulations! You have now finished Misskey's basic tutorial."
|
||||||
|
step7_2: "If you would like to learn more about Misskey, try the {help} section."
|
||||||
|
step7_3: "Good luck and have fun! 🚀"
|
||||||
_2fa:
|
_2fa:
|
||||||
alreadyRegistered: "You have already registered 2-factor authentication device."
|
alreadyRegistered: "You have already registered 2-factor authentication device."
|
||||||
registerDevice: "Register a new device"
|
registerDevice: "Register a new device"
|
||||||
@ -389,11 +418,11 @@ _permissions:
|
|||||||
"write:favorites": "Edit your favorites list"
|
"write:favorites": "Edit your favorites list"
|
||||||
"read:following": "View your following information"
|
"read:following": "View your following information"
|
||||||
"write:following": "Follow or unfollow other accounts"
|
"write:following": "Follow or unfollow other accounts"
|
||||||
"read:messaging": "View your talks"
|
"read:messaging": "View your messages"
|
||||||
"write:messaging": "Start or delete your talks"
|
"write:messaging": "Compose or Delete messages"
|
||||||
"read:mutes": "View the list of people you muted"
|
"read:mutes": "View the list of people you muted"
|
||||||
"write:mutes": "Edit the list of people you muted"
|
"write:mutes": "Edit the list of people you muted"
|
||||||
"write:notes": "Compose and delete notes"
|
"write:notes": "Compose or Delete notes"
|
||||||
"read:notifications": "View notifications"
|
"read:notifications": "View notifications"
|
||||||
"write:notifications": "Work with notifications"
|
"write:notifications": "Work with notifications"
|
||||||
"read:reactions": "View reactions"
|
"read:reactions": "View reactions"
|
||||||
@ -466,6 +495,7 @@ _visibility:
|
|||||||
followersDescription: "Post to followers only"
|
followersDescription: "Post to followers only"
|
||||||
specified: "Direct"
|
specified: "Direct"
|
||||||
specifiedDescription: "Post to specified users only"
|
specifiedDescription: "Post to specified users only"
|
||||||
|
localOnly: "Local only"
|
||||||
_postForm:
|
_postForm:
|
||||||
replyPlaceholder: "Reply to this note..."
|
replyPlaceholder: "Reply to this note..."
|
||||||
quotePlaceholder: "Quote this note..."
|
quotePlaceholder: "Quote this note..."
|
||||||
|
@ -214,18 +214,16 @@ remove: "Borrar"
|
|||||||
removed: "Borrado"
|
removed: "Borrado"
|
||||||
removeAreYouSure: "¿Desea borrar \"{x}\"?"
|
removeAreYouSure: "¿Desea borrar \"{x}\"?"
|
||||||
saved: "Guardado"
|
saved: "Guardado"
|
||||||
messaging: "Conversación"
|
messaging: "Chat"
|
||||||
upload: "Subir"
|
upload: "Subir"
|
||||||
fromDrive: "Desde el drive"
|
fromDrive: "Desde el drive"
|
||||||
fromUrl: "Desde la URL"
|
fromUrl: "Desde la URL"
|
||||||
editWidgets: "Editar widgets"
|
|
||||||
exitEdit: "Terminar edición"
|
|
||||||
explore: "Explorar"
|
explore: "Explorar"
|
||||||
games: "Misskey Games"
|
games: "Misskey Games"
|
||||||
messageRead: "Ya leído"
|
messageRead: "Ya leído"
|
||||||
recentUsedEmojis: "Emojis usados recientemente"
|
recentUsedEmojis: "Emojis usados recientemente"
|
||||||
noMoreHistory: "El historial se ha acabado"
|
noMoreHistory: "El historial se ha acabado"
|
||||||
startMessaging: "Iniciar conversación"
|
startMessaging: "Iniciar chat"
|
||||||
nUsersRead: "Leído por {n} personas"
|
nUsersRead: "Leído por {n} personas"
|
||||||
agreeTo: "De acuerdo con {0}"
|
agreeTo: "De acuerdo con {0}"
|
||||||
tos: "Términos de uso"
|
tos: "Términos de uso"
|
||||||
@ -348,12 +346,39 @@ post: "Nota"
|
|||||||
posted: "Posteado"
|
posted: "Posteado"
|
||||||
autoReloadWhenDisconnected: "Recargar automáticamente cuando el servidor está desconectado"
|
autoReloadWhenDisconnected: "Recargar automáticamente cuando el servidor está desconectado"
|
||||||
autoNoteWatch: "Ver nota automáticamente"
|
autoNoteWatch: "Ver nota automáticamente"
|
||||||
|
autoNoteWatchDescription: "Recibe notificaciones sobre las notas de otros usuarios que a los que respondiste y reaccionaste"
|
||||||
reduceUiAnimation: "Reducir la animación de la UI"
|
reduceUiAnimation: "Reducir la animación de la UI"
|
||||||
share: "Compartir"
|
share: "Compartir"
|
||||||
notFound: "No se encuentra"
|
notFound: "No se encuentra"
|
||||||
notFoundDescription: "No se encontró la página correspondiente a la URL elegida"
|
notFoundDescription: "No se encontró la página correspondiente a la URL elegida"
|
||||||
|
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"
|
||||||
|
markAsReadAllTalkMessages: "Marcar todos los chats como leídos"
|
||||||
help: "Ayuda"
|
help: "Ayuda"
|
||||||
|
inputMessageHere: "Escribe el mensaje aquí"
|
||||||
|
close: "Cerrar"
|
||||||
|
group: "Grupo"
|
||||||
|
groups: "Grupos"
|
||||||
|
createGroup: "Crear grupo"
|
||||||
|
ownedGroups: "Tus"
|
||||||
|
joinedGroups: "Grupos a los que me uní"
|
||||||
invites: "Invitar"
|
invites: "Invitar"
|
||||||
|
groupName: "Nombre del grupo"
|
||||||
|
members: "Miembros"
|
||||||
|
transfer: "Transferir"
|
||||||
|
messagingWithUser: "Chatear con usuario"
|
||||||
|
messagingWithGroup: "Chatear en grupo"
|
||||||
|
enable: "Activar"
|
||||||
|
next: "Siguiente"
|
||||||
|
retype: "Intentar de nuevo"
|
||||||
|
_tutorial:
|
||||||
|
title: "Cómo usar Misskey"
|
||||||
|
step1_1: "Bienvenido"
|
||||||
|
step1_2: "Esta imagen se llama \"Linea de tiempo\" y muestra en orden cronológico las \"notas\" tuyas y de la gente que \"sigues\""
|
||||||
|
step1_3: "Si no estás escribiendo ninguna nota y no estás siguiendo a nadie, es esperable que no se muestre nada en la linea de tiempo"
|
||||||
|
step2_1: "Antes de crear notas y seguir a alguien, primero vamos a crear tu perfil"
|
||||||
_2fa:
|
_2fa:
|
||||||
registerDevice: "Registrar dispositivo"
|
registerDevice: "Registrar dispositivo"
|
||||||
step1: "Primero, instale en su dispositivo la aplicación de autenticación {a} o {b} u otra."
|
step1: "Primero, instale en su dispositivo la aplicación de autenticación {a} o {b} u otra."
|
||||||
@ -371,8 +396,6 @@ _permissions:
|
|||||||
"write:favorites": "Addministrar favoritos"
|
"write:favorites": "Addministrar favoritos"
|
||||||
"read:following": "Ver información de seguidor"
|
"read:following": "Ver información de seguidor"
|
||||||
"write:following": "Seguir o dejar de seguir"
|
"write:following": "Seguir o dejar de seguir"
|
||||||
"read:messaging": "Ver conversación"
|
|
||||||
"write:messaging": "Administrar coversación"
|
|
||||||
"read:mutes": "Ver usuarios silenciados"
|
"read:mutes": "Ver usuarios silenciados"
|
||||||
"write:mutes": "Administrar usuarios silenciados"
|
"write:mutes": "Administrar usuarios silenciados"
|
||||||
"write:notes": "Crear/borrar notas"
|
"write:notes": "Crear/borrar notas"
|
||||||
|
@ -219,8 +219,6 @@ messaging: "チャット"
|
|||||||
upload: "アップロード"
|
upload: "アップロード"
|
||||||
fromDrive: "ドライブから"
|
fromDrive: "ドライブから"
|
||||||
fromUrl: "URLから"
|
fromUrl: "URLから"
|
||||||
editWidgets: "ウィジェットを編集"
|
|
||||||
exitEdit: "編集を終了"
|
|
||||||
explore: "みつける"
|
explore: "みつける"
|
||||||
games: "Misskey Games"
|
games: "Misskey Games"
|
||||||
messageRead: "既読"
|
messageRead: "既読"
|
||||||
@ -376,6 +374,8 @@ messagingWithGroup: "グループでチャット"
|
|||||||
enable: "有効にする"
|
enable: "有効にする"
|
||||||
next: "次"
|
next: "次"
|
||||||
retype: "再入力"
|
retype: "再入力"
|
||||||
|
noteOf: "{user}のノート"
|
||||||
|
inviteToGroup: "グループに招待"
|
||||||
|
|
||||||
_tutorial:
|
_tutorial:
|
||||||
title: "Misskeyの使い方"
|
title: "Misskeyの使い方"
|
||||||
|
@ -1 +1,169 @@
|
|||||||
---
|
---
|
||||||
|
_ago:
|
||||||
|
unknown: "謎"
|
||||||
|
future: "未来"
|
||||||
|
justNow: "たった今"
|
||||||
|
secondsAgo: "{n}秒前"
|
||||||
|
minutesAgo: "{n}分前"
|
||||||
|
hoursAgo: "{n}時間前"
|
||||||
|
daysAgo: "{n}日前"
|
||||||
|
weeksAgo: "{n}週間前"
|
||||||
|
monthsAgo: "{n}ヶ月前"
|
||||||
|
yearsAgo: "{n}年前"
|
||||||
|
_time:
|
||||||
|
second: "秒"
|
||||||
|
minute: "分"
|
||||||
|
hour: "時間"
|
||||||
|
day: "日"
|
||||||
|
introMisskey: "ようこそ!Misskeyは、オープンソースの分散型マイクロブログサービスやねん。\n「ノート」を作成しぃ、いま起こっとることを共有したり、あんたについて皆に発信しよう📡\n「リアクション」機能で、皆のノートに素はよ反応を追加することもできます✌\n新しい世界を探検しよう🚀"
|
||||||
|
monthAndDay: "{month}月 {day}日"
|
||||||
|
search: "探す"
|
||||||
|
notifications: "通知"
|
||||||
|
username: "ユーザー名"
|
||||||
|
password: "パスワード"
|
||||||
|
fetchingAsApObject: "連合に照会中"
|
||||||
|
ok: "おっけー"
|
||||||
|
gotIt: "ほい"
|
||||||
|
cancel: "やめとくわ"
|
||||||
|
enterUsername: "ユーザー名を入れてや"
|
||||||
|
renotedBy: "{user}がRenote"
|
||||||
|
noNotes: "ノートはあらへん"
|
||||||
|
noNotifications: "通知はあらへん"
|
||||||
|
instance: "インスタンス"
|
||||||
|
settings: "設定"
|
||||||
|
profile: "プロフィール"
|
||||||
|
timeline: "タイムライン"
|
||||||
|
noAccountDescription: "自己紹介はあらへん"
|
||||||
|
login: "ログイン"
|
||||||
|
loggingIn: "ログインしとります"
|
||||||
|
logout: "ログアウト"
|
||||||
|
signup: "新規登録"
|
||||||
|
uploading: "アップロードしとります"
|
||||||
|
save: "保存"
|
||||||
|
users: "ユーザー"
|
||||||
|
addUser: "ユーザー増やす"
|
||||||
|
favorite: "お気に入り"
|
||||||
|
favorites: "お気に入り"
|
||||||
|
unfavorite: "お気に入りやめる"
|
||||||
|
pin: "ピン留め"
|
||||||
|
unpin: "ピン留めやめる"
|
||||||
|
copyContent: "内容をコピー"
|
||||||
|
copyLink: "リンクをコピー"
|
||||||
|
delete: "ほかす"
|
||||||
|
addToList: "リストに入れたる"
|
||||||
|
reply: "返す"
|
||||||
|
loadMore: "もっとあるやろ!"
|
||||||
|
mentions: "あんた宛て"
|
||||||
|
directNotes: "ダイレクト投稿"
|
||||||
|
import: "インポート"
|
||||||
|
export: "エクスポート"
|
||||||
|
files: "ファイル"
|
||||||
|
download: "ダウンロード"
|
||||||
|
lists: "リスト"
|
||||||
|
noLists: "リストはあらへん"
|
||||||
|
followsYou: "フォローされとるで"
|
||||||
|
error: "問題が発生してん"
|
||||||
|
enterListName: "リスト名を入れてや"
|
||||||
|
privacy: "プライバシーってなんや?オカンの年齢か?"
|
||||||
|
makeFollowManuallyApprove: "他人のフォローは許可してからや!"
|
||||||
|
defaultNoteVisibility: "もとからの公開範囲"
|
||||||
|
follow: "フォロー"
|
||||||
|
followRequest: "フォロー許してくれや!言うてみる"
|
||||||
|
followRequests: "フォロー許してくれや!"
|
||||||
|
followRequestPending: "フォロー許してくれるん待っとる"
|
||||||
|
enterEmoji: "絵文字を入れてや"
|
||||||
|
you: "あんた"
|
||||||
|
clickToShow: "押してみ、見せたるわ"
|
||||||
|
sensitive: "見たらあかんで"
|
||||||
|
add: "増やす"
|
||||||
|
reaction: "リアクション"
|
||||||
|
renameFile: "ファイル名をいらう"
|
||||||
|
attachCancel: "くっつけるのやめよか"
|
||||||
|
markAsSensitive: "ちょっと見せられへんわ"
|
||||||
|
unmarkAsSensitive: "別にええんじゃね?"
|
||||||
|
enterFileName: "ファイル名を入れてや"
|
||||||
|
mute: "ミュート"
|
||||||
|
unmute: "ミュートやめたる"
|
||||||
|
block: "ブロック"
|
||||||
|
unblock: "ブロックやめたる"
|
||||||
|
suspend: "凍結"
|
||||||
|
unsuspend: "溶かす"
|
||||||
|
customEmojis: "カスタム絵文字"
|
||||||
|
cacheRemoteFiles: "リモートのファイルをキャッシュする"
|
||||||
|
cacheRemoteFilesDescription: "この設定をチャラにすると、リモートファイルをキャッシュせず直リンクするようになります。サーバーのストレージを節約できますが、サムネイルが生成されへんので通信量が増加します。"
|
||||||
|
loginFailed: "ログインに失敗してん"
|
||||||
|
wallpaper: "壁紙"
|
||||||
|
removeWallpaper: "壁紙ほかす"
|
||||||
|
youHaveNoLists: "リストはあらへん"
|
||||||
|
proxyAccountDescription: "プロキシアカウントは、代わりにフォローしてくれるアカウントや。例えば、551に豚まんが無いときやったり、ユーザーがリモートユーザーをアカウントに入れたとき、リストに入れられたユーザーが誰からもフォローされてないと寂しいやん。寂しいし、アクティビティも配達されへんから、プロキシアカウントがフォローしてくれるで。ええやつやん…"
|
||||||
|
host: "ホスト"
|
||||||
|
federation: "連合"
|
||||||
|
instances: "インスタンス"
|
||||||
|
charts: "チャート"
|
||||||
|
perHour: "1時間ごと"
|
||||||
|
perDay: "1日ごと"
|
||||||
|
operations: "操作"
|
||||||
|
version: "バージョン"
|
||||||
|
network: "ネットワーク"
|
||||||
|
statistics: "統計"
|
||||||
|
clearQueueConfirmText: "未配達の投稿は配送されなくなるで。通常この操作を行う必要はあらへんや。"
|
||||||
|
muteAndBlock: "ミュートとブロック"
|
||||||
|
noUsers: "ユーザーはおらへん"
|
||||||
|
pinLimitExceeded: "これ以上ピン留めできひん"
|
||||||
|
intro: "Misskeyのインストールが完了してん!管理者アカウントを作ってや。"
|
||||||
|
noCustomEmojis: "絵文字はあらへん"
|
||||||
|
noJobs: "ジョブはあらへん"
|
||||||
|
all: "みな"
|
||||||
|
retypedNotMatch: "そやないねん。"
|
||||||
|
remove: "ほかす"
|
||||||
|
noMoreHistory: "これより過去の履歴はあらへんで"
|
||||||
|
nsfw: "見たらあかんで"
|
||||||
|
userList: "リスト"
|
||||||
|
about: "情報"
|
||||||
|
aboutMisskey: "Misskeyってなんや?"
|
||||||
|
notFoundDescription: "指定されたURLに該当するページはあらへんやった。"
|
||||||
|
close: "さいなら"
|
||||||
|
joinedGroups: "参加しとるグループ"
|
||||||
|
_2fa:
|
||||||
|
alreadyRegistered: "もう設定終わっとるわ"
|
||||||
|
_auth:
|
||||||
|
permissionAsk: "このアプリは次の権限を要求しとるで"
|
||||||
|
_antennaSources:
|
||||||
|
all: "みなのノート"
|
||||||
|
homeTimeline: "フォローしとるユーザーのノート"
|
||||||
|
_widgets:
|
||||||
|
notifications: "通知"
|
||||||
|
timeline: "タイムライン"
|
||||||
|
_cw:
|
||||||
|
show: "もっとあるやろ!"
|
||||||
|
_poll:
|
||||||
|
noMore: "これ以上追加でけへん"
|
||||||
|
deadlineTime: "時間"
|
||||||
|
_visibility:
|
||||||
|
publicDescription: "みなのユーザーに公開"
|
||||||
|
_profile:
|
||||||
|
username: "ユーザー名"
|
||||||
|
_exportOrImport:
|
||||||
|
allNotes: "全てのノート"
|
||||||
|
muteList: "ミュート"
|
||||||
|
blockingList: "ブロック"
|
||||||
|
userLists: "リスト"
|
||||||
|
_pages:
|
||||||
|
script:
|
||||||
|
categories:
|
||||||
|
list: "リスト"
|
||||||
|
blocks:
|
||||||
|
_join:
|
||||||
|
arg1: "リスト"
|
||||||
|
_randomPick:
|
||||||
|
arg1: "リスト"
|
||||||
|
_dailyRandomPick:
|
||||||
|
arg1: "リスト"
|
||||||
|
_seedRandomPick:
|
||||||
|
arg2: "リスト"
|
||||||
|
_pick:
|
||||||
|
arg1: "リスト"
|
||||||
|
_listLen:
|
||||||
|
arg1: "リスト"
|
||||||
|
types:
|
||||||
|
array: "リスト"
|
||||||
|
@ -218,14 +218,12 @@ messaging: "대화"
|
|||||||
upload: "업로드"
|
upload: "업로드"
|
||||||
fromDrive: "드라이브에서"
|
fromDrive: "드라이브에서"
|
||||||
fromUrl: "URL로부터"
|
fromUrl: "URL로부터"
|
||||||
editWidgets: "위젯 편집"
|
|
||||||
exitEdit: "편집 종료"
|
|
||||||
explore: "발견하기"
|
explore: "발견하기"
|
||||||
games: "Misskey Games"
|
games: "Misskey Games"
|
||||||
messageRead: "읽음"
|
messageRead: "읽음"
|
||||||
recentUsedEmojis: "최근에 사용한 이모지"
|
recentUsedEmojis: "최근에 사용한 이모지"
|
||||||
noMoreHistory: "이것보다 과거의 기록이 없습니다"
|
noMoreHistory: "이것보다 과거의 기록이 없습니다"
|
||||||
startMessaging: "대화 시작"
|
startMessaging: "대화 시작하기"
|
||||||
nUsersRead: "{n}명이 읽음"
|
nUsersRead: "{n}명이 읽음"
|
||||||
agreeTo: "{0}에 동의"
|
agreeTo: "{0}에 동의"
|
||||||
tos: "이용 약관"
|
tos: "이용 약관"
|
||||||
@ -348,6 +346,7 @@ post: "작성"
|
|||||||
posted: "게시하였습니다"
|
posted: "게시하였습니다"
|
||||||
autoReloadWhenDisconnected: "서버와의 연결이 끊기면 자동 새로고침"
|
autoReloadWhenDisconnected: "서버와의 연결이 끊기면 자동 새로고침"
|
||||||
autoNoteWatch: "노트를 자동으로 지켜보기"
|
autoNoteWatch: "노트를 자동으로 지켜보기"
|
||||||
|
autoNoteWatchDescription: "리액션하거나 답글을 남긴 다른 유저의 노트에 대한 알림을 받습니다."
|
||||||
reduceUiAnimation: "UI의 애니메이션을 줄이기"
|
reduceUiAnimation: "UI의 애니메이션을 줄이기"
|
||||||
share: "공유"
|
share: "공유"
|
||||||
notFound: "찾을 수 없습니다"
|
notFound: "찾을 수 없습니다"
|
||||||
@ -369,6 +368,36 @@ invites: "초대"
|
|||||||
groupName: "그룹명"
|
groupName: "그룹명"
|
||||||
members: "멤버"
|
members: "멤버"
|
||||||
transfer: "양도"
|
transfer: "양도"
|
||||||
|
messagingWithUser: "유저와 대화하기"
|
||||||
|
messagingWithGroup: "그룹끼리 대화하기"
|
||||||
|
enable: "사용"
|
||||||
|
next: "다음"
|
||||||
|
retype: "다시 입력"
|
||||||
|
noteOf: "{user}의 노트"
|
||||||
|
inviteToGroup: "그룹에 초대하기"
|
||||||
|
_tutorial:
|
||||||
|
title: "Misskey의 사용 방법"
|
||||||
|
step1_1: "환영합니다!"
|
||||||
|
step1_2: "이 페이지는 \"타임라인\"이라고 불립니다. 당신이 \"팔로우\"하고 있는 사람들의 \"노트\"가 시간순으로 나타납니다."
|
||||||
|
step1_3: "아직 아무 유저도 팔로우하고 있지 않기에 타임라인은 비어 있을 것입니다."
|
||||||
|
step2_1: "새 노트를 작성하거나 다른 사람을 팔로우하기 전에, 먼저 프로필을 완성해보도록 합시다."
|
||||||
|
step2_2: "당신이 어떤 사람인지를 알린다면, 다른 사람들이 당신을 팔로우할 확률이 올라갈 것입니다."
|
||||||
|
step3_1: "프로필 설정은 잘 끝내셨나요?"
|
||||||
|
step3_2: "그럼 시험삼아 노트를 작성해 보세요. 화면에 있는 연필 버튼을 누르면 작성 폼이 열립니다."
|
||||||
|
step3_3: "내용을 작성한 후, 폼 오른쪽 상단의 버튼을 눌러 노트를 올릴 수 있습니다."
|
||||||
|
step3_4: "쓸 말이 없나요? \"Misskey 시작했어요!\" 같은 건 어떨까요? :>"
|
||||||
|
step4_1: "노트 작성을 끝내셨나요?"
|
||||||
|
step4_2: "당신의 노트가 타임라인에 표시되어 있다면 성공입니다."
|
||||||
|
step5_1: "이제, 다른 사람을 팔로우하여 타임라인을 활기차게 만들어보도록 합시다."
|
||||||
|
step5_2: "{featured}에서 이 인스턴스의 인기 노트를 보실 수 있습니다. {explore}에서는 인기 사용자를 찾을 수 있구요. 마음에 드는 사람을 골라 팔로우해 보세요!"
|
||||||
|
step5_3: "다른 유저를 팔로우하려면 해당 유저의 아이콘을 클릭하여 프로필 페이지를 띄운 후, 팔로우 버튼을 눌러 주세요."
|
||||||
|
step5_4: "사용자에 따라 팔로우가 승인될 때까지 시간이 걸릴 수 있습니다."
|
||||||
|
step6_1: "타임라인에 다른 사용자의 노트가 나타난다면 성공입니다."
|
||||||
|
step6_2: "다른 유저의 노트에 \"리액션\"을 붙여 간단하게 당신의 반응을 전달할 수도 있습니다."
|
||||||
|
step6_3: "리액션을 붙이려면, 노트의 \"+\" 버튼을 클릭하고 원하는 이모지를 선택합니다."
|
||||||
|
step7_1: "이것으로 Misskey의 기본 튜토리얼을 마치겠습니다. 수고하셨습니다!"
|
||||||
|
step7_2: "Misskey에 대해 더 알고 싶으시다면 {help}를 참고해 주세요."
|
||||||
|
step7_3: "그럼 Misskey를 즐기세요! 🚀"
|
||||||
_2fa:
|
_2fa:
|
||||||
alreadyRegistered: "이미 설정이 완료되었습니다."
|
alreadyRegistered: "이미 설정이 완료되었습니다."
|
||||||
registerDevice: "디바이스 등록"
|
registerDevice: "디바이스 등록"
|
||||||
@ -379,32 +408,32 @@ _2fa:
|
|||||||
step4: "다음 로그인부터는 토큰을 입력해야 합니다."
|
step4: "다음 로그인부터는 토큰을 입력해야 합니다."
|
||||||
securityKeyInfo: "FIDO2를 지원하는 하드웨어 시큐리티 키 혹은 휴대전화의 지문인식이나 화면잠금 PIN을 이용해서 로그인하도록 설정할 수 있습니다."
|
securityKeyInfo: "FIDO2를 지원하는 하드웨어 시큐리티 키 혹은 휴대전화의 지문인식이나 화면잠금 PIN을 이용해서 로그인하도록 설정할 수 있습니다."
|
||||||
_permissions:
|
_permissions:
|
||||||
"read:account": "계정 정보 보기"
|
"read:account": "계정의 정보를 봅니다"
|
||||||
"write:account": "계정 정보 변경"
|
"write:account": "계정의 정보를 변경합니다"
|
||||||
"read:blocks": "차단 보기"
|
"read:blocks": "차단 여부를 확인합니다"
|
||||||
"write:blocks": "차단 수정"
|
"write:blocks": "차단을 하거나 해제합니다"
|
||||||
"read:drive": "드라이브 보기"
|
"read:drive": "드라이브를 조회합니다"
|
||||||
"write:drive": "드라이브 수정"
|
"write:drive": "드라이브에 파일을 올리거나, 이름을 변경하거나, 삭제합니다"
|
||||||
"read:favorites": "즐겨찾기 보기"
|
"read:favorites": "즐겨찾기를 조회합니다"
|
||||||
"write:favorites": "즐겨찾기 수정"
|
"write:favorites": "즐겨찾기에 추가하거나 삭제합니다"
|
||||||
"read:following": "팔로우 정보 보기"
|
"read:following": "팔로우 상태를 봅니다"
|
||||||
"write:following": "팔로잉 및 팔로우 수정"
|
"write:following": "팔로우하거나 팔로우를 해제합니다"
|
||||||
"read:messaging": "대화 보기"
|
"read:messaging": "대화를 읽습니다"
|
||||||
"write:messaging": "대화 수정"
|
"write:messaging": "대화를 시작하거나 메시지를 보냅니다"
|
||||||
"read:mutes": "뮤트 보기"
|
"read:mutes": "뮤트 여부를 확인합니다"
|
||||||
"write:mutes": "뮤트 수정"
|
"write:mutes": "뮤트를 하거나 해제합니다"
|
||||||
"write:notes": "노트를 작성하거나 삭제"
|
"write:notes": "노트를 작성하거나 삭제합니다"
|
||||||
"read:notifications": "알림 보기"
|
"read:notifications": "알림을 확인합니다"
|
||||||
"write:notifications": "알림 수정"
|
"write:notifications": "알림을 모두 읽음 처리합니다"
|
||||||
"read:reactions": "리액션 보기"
|
"read:reactions": "리액션을 확인합니다"
|
||||||
"write:reactions": "리액션 수정"
|
"write:reactions": "리액션을 추가하거나 취소합니다"
|
||||||
"write:votes": "투표하기"
|
"write:votes": "투표를 합니다"
|
||||||
"read:pages": "페이지 보기"
|
"read:pages": "페이지를 봅니다"
|
||||||
"write:pages": "페이지 수정"
|
"write:pages": "페이지를 수정합니다"
|
||||||
"read:page-likes": "페이지의 좋아요 보기"
|
"read:page-likes": "페이지의 좋아요를 확인합니다"
|
||||||
"write:page-likes": "페이지의 좋아요 수정"
|
"write:page-likes": "페이지의 좋아요를 추가하거나 삭제합니다"
|
||||||
"read:user-groups": "유저 그룹 조회"
|
"read:user-groups": "유저 그룹을 조회합니다"
|
||||||
"write:user-groups": "유저 그룹 변경"
|
"write:user-groups": "유저 그룹을 만들거나, 초대하거나, 이름을 변경하거나, 양도하거나, 삭제합니다"
|
||||||
_auth:
|
_auth:
|
||||||
shareAccess: "\"{name}\" 이 계정에 접근하는 것을 허용하시겠습니까?"
|
shareAccess: "\"{name}\" 이 계정에 접근하는 것을 허용하시겠습니까?"
|
||||||
permissionAsk: "이 앱은 다음의 권한을 요청합니다"
|
permissionAsk: "이 앱은 다음의 권한을 요청합니다"
|
||||||
@ -466,6 +495,7 @@ _visibility:
|
|||||||
followersDescription: "팔로워에게만 공개"
|
followersDescription: "팔로워에게만 공개"
|
||||||
specified: "다이렉트"
|
specified: "다이렉트"
|
||||||
specifiedDescription: "지정한 유저에게만 공개"
|
specifiedDescription: "지정한 유저에게만 공개"
|
||||||
|
localOnly: "로컬에만"
|
||||||
_postForm:
|
_postForm:
|
||||||
replyPlaceholder: "이 노트에 답글..."
|
replyPlaceholder: "이 노트에 답글..."
|
||||||
quotePlaceholder: "이 노트를 인용..."
|
quotePlaceholder: "이 노트를 인용..."
|
||||||
|
@ -15,7 +15,7 @@ _time:
|
|||||||
minute: "分"
|
minute: "分"
|
||||||
hour: "小时"
|
hour: "小时"
|
||||||
day: "日"
|
day: "日"
|
||||||
introMisskey: "欢迎!Misskey是一个开源的分散型SNS服务。\n通过「Note」来分享现在发生的事情吧!📡\n「反应」工能也可以让你快速的对大家的「Note」来表达感情👍\n一起来探索新的世界吧!🚀"
|
introMisskey: "欢迎!Misskey是一个开源的分散型SNS服务。\n通过「帖子」来分享现在发生的事情吧!📡\n「反应」功能,可以让你快速的对大家的「帖子」来表达感情👍\n一起来探索新的世界吧!🚀"
|
||||||
monthAndDay: "{month}月 {day}日"
|
monthAndDay: "{month}月 {day}日"
|
||||||
search: "搜索"
|
search: "搜索"
|
||||||
notifications: "通知"
|
notifications: "通知"
|
||||||
@ -27,6 +27,7 @@ gotIt: "我明白了"
|
|||||||
cancel: "取消"
|
cancel: "取消"
|
||||||
enterUsername: "输入用户名"
|
enterUsername: "输入用户名"
|
||||||
renotedBy: "由 {user} 转推"
|
renotedBy: "由 {user} 转推"
|
||||||
|
noNotes: "没有投稿"
|
||||||
noNotifications: "无通知"
|
noNotifications: "无通知"
|
||||||
instance: "实例"
|
instance: "实例"
|
||||||
settings: "设置"
|
settings: "设置"
|
||||||
@ -54,6 +55,11 @@ sendMessage: "发送"
|
|||||||
copyUsername: "复制用户名"
|
copyUsername: "复制用户名"
|
||||||
reply: "回复"
|
reply: "回复"
|
||||||
loadMore: "查看更多"
|
loadMore: "查看更多"
|
||||||
|
youGotNewFollower: "你有新的关注者"
|
||||||
|
receiveFollowRequest: "收到关注请求"
|
||||||
|
followRequestAccepted: "同意关注请求"
|
||||||
|
mentions: "提及"
|
||||||
|
directNotes: "指定用户可见"
|
||||||
importAndExport: "导入和导出"
|
importAndExport: "导入和导出"
|
||||||
import: "导入"
|
import: "导入"
|
||||||
export: "导出"
|
export: "导出"
|
||||||
@ -169,11 +175,8 @@ remove: "删除"
|
|||||||
removed: "已删除"
|
removed: "已删除"
|
||||||
removeAreYouSure: "要删掉「{x}」吗?"
|
removeAreYouSure: "要删掉「{x}」吗?"
|
||||||
saved: "已保存"
|
saved: "已保存"
|
||||||
messaging: "聊天"
|
|
||||||
upload: "上传"
|
upload: "上传"
|
||||||
fromUrl: "从 URL"
|
fromUrl: "从 URL"
|
||||||
editWidgets: "编辑部件"
|
|
||||||
exitEdit: "停止编辑"
|
|
||||||
explore: "发现"
|
explore: "发现"
|
||||||
games: "Misskey游戏"
|
games: "Misskey游戏"
|
||||||
messageRead: "已读"
|
messageRead: "已读"
|
||||||
@ -287,7 +290,6 @@ uploadFolder: "默认上传文件夹"
|
|||||||
cacheClear: "清空缓存"
|
cacheClear: "清空缓存"
|
||||||
markAsReadAllNotifications: "将所有通知标为已读"
|
markAsReadAllNotifications: "将所有通知标为已读"
|
||||||
markAsReadAllUnreadNotes: "将所有帖子标记为已读"
|
markAsReadAllUnreadNotes: "将所有帖子标记为已读"
|
||||||
markAsReadAllTalkMessages: "将所有对话标为已读"
|
|
||||||
help: "帮助"
|
help: "帮助"
|
||||||
inputMessageHere: "在此键入信息"
|
inputMessageHere: "在此键入信息"
|
||||||
close: "关闭"
|
close: "关闭"
|
||||||
@ -315,8 +317,6 @@ _permissions:
|
|||||||
"write:favorites": "编辑收藏夹"
|
"write:favorites": "编辑收藏夹"
|
||||||
"read:following": "查看关注信息"
|
"read:following": "查看关注信息"
|
||||||
"write:following": "关注/取消关注"
|
"write:following": "关注/取消关注"
|
||||||
"read:messaging": "查看对话"
|
|
||||||
"write:messaging": "对话操作"
|
|
||||||
"read:mutes": "查看屏蔽列表"
|
"read:mutes": "查看屏蔽列表"
|
||||||
"write:mutes": "编辑屏蔽列表"
|
"write:mutes": "编辑屏蔽列表"
|
||||||
"read:notifications": "查看通知"
|
"read:notifications": "查看通知"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"author": "syuilo <syuilotan@yahoo.co.jp>",
|
"author": "syuilo <syuilotan@yahoo.co.jp>",
|
||||||
"version": "12.5.0",
|
"version": "12.6.0",
|
||||||
"codename": "indigo",
|
"codename": "indigo",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@ -36,6 +36,7 @@
|
|||||||
"@fortawesome/free-regular-svg-icons": "5.12.0",
|
"@fortawesome/free-regular-svg-icons": "5.12.0",
|
||||||
"@fortawesome/free-solid-svg-icons": "5.12.0",
|
"@fortawesome/free-solid-svg-icons": "5.12.0",
|
||||||
"@fortawesome/vue-fontawesome": "0.1.9",
|
"@fortawesome/vue-fontawesome": "0.1.9",
|
||||||
|
"@juggle/resize-observer": "3.0.2",
|
||||||
"@koa/cors": "3.0.0",
|
"@koa/cors": "3.0.0",
|
||||||
"@koa/multer": "2.0.2",
|
"@koa/multer": "2.0.2",
|
||||||
"@koa/router": "8.0.6",
|
"@koa/router": "8.0.6",
|
||||||
|
@ -18,8 +18,12 @@
|
|||||||
</transition>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
<div class="sub">
|
<div class="sub">
|
||||||
|
<button v-if="widgetsEditMode" class="_button edit active" @click="widgetsEditMode = false"><fa :icon="faGripVertical"/></button>
|
||||||
|
<button v-else class="_button edit" @click="widgetsEditMode = true"><fa :icon="faGripVertical"/></button>
|
||||||
|
<div class="search">
|
||||||
<fa :icon="faSearch"/>
|
<fa :icon="faSearch"/>
|
||||||
<input type="search" class="search" :placeholder="$t('search')" v-model="searchQuery" v-autocomplete="{ model: 'searchQuery' }" :disabled="searchWait" @keypress="searchKeypress"/>
|
<input type="search" :placeholder="$t('search')" v-model="searchQuery" v-autocomplete="{ model: 'searchQuery' }" :disabled="searchWait" @keypress="searchKeypress"/>
|
||||||
|
</div>
|
||||||
<button v-if="$store.getters.isSignedIn" class="post _buttonPrimary" @click="post()"><fa :icon="faPencilAlt"/></button>
|
<button v-if="$store.getters.isSignedIn" class="post _buttonPrimary" @click="post()"><fa :icon="faPencilAlt"/></button>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
@ -86,7 +90,7 @@
|
|||||||
</nav>
|
</nav>
|
||||||
</transition>
|
</transition>
|
||||||
|
|
||||||
<div class="contents">
|
<div class="contents" ref="contents">
|
||||||
<main ref="main">
|
<main ref="main">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<transition :name="$store.state.device.animation ? 'page' : ''" mode="out-in" @enter="onTransition">
|
<transition :name="$store.state.device.animation ? 'page' : ''" mode="out-in" @enter="onTransition">
|
||||||
@ -126,8 +130,6 @@
|
|||||||
<template v-else>
|
<template v-else>
|
||||||
<component class="widget" v-for="widget in widgets" :is="`mkw-${widget.name}`" :key="widget.id" :ref="widget.id" :widget="widget"/>
|
<component class="widget" v-for="widget in widgets" :is="`mkw-${widget.name}`" :key="widget.id" :ref="widget.id" :widget="widget"/>
|
||||||
</template>
|
</template>
|
||||||
<button ref="widgetsEditButton" v-if="widgetsEditMode" class="_button edit" @click="widgetsEditMode = false">{{ $t('exitEdit') }}</button>
|
|
||||||
<button ref="widgetsEditButton" v-else class="_button edit" @click="widgetsEditMode = true">{{ $t('editWidgets') }}</button>
|
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -150,8 +152,9 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import { faChevronLeft, faHashtag, faBroadcastTower, faFireAlt, faEllipsisH, faPencilAlt, faBars, faTimes, faSearch, faUserCog, faCog, faUser, faHome, faStar, faCircle, faAt, faListUl, faPlus, faUserClock, faUsers, faTachometerAlt, faExchangeAlt, faGlobe, faChartBar, faCloud, faGamepad, faServer, faFileAlt, faSatellite, faInfoCircle, faQuestionCircle } from '@fortawesome/free-solid-svg-icons';
|
import { faGripVertical, faChevronLeft, faHashtag, faBroadcastTower, faFireAlt, faEllipsisH, faPencilAlt, faBars, faTimes, faSearch, faUserCog, faCog, faUser, faHome, faStar, faCircle, faAt, faListUl, faPlus, faUserClock, faUsers, faTachometerAlt, faExchangeAlt, faGlobe, faChartBar, faCloud, faGamepad, faServer, faFileAlt, faSatellite, faInfoCircle, faQuestionCircle } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { faBell, faEnvelope, faLaugh, faComments } from '@fortawesome/free-regular-svg-icons';
|
import { faBell, faEnvelope, faLaugh, faComments } from '@fortawesome/free-regular-svg-icons';
|
||||||
|
import { ResizeObserver } from '@juggle/resize-observer';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
import i18n from './i18n';
|
import i18n from './i18n';
|
||||||
import { host } from './config';
|
import { host } from './config';
|
||||||
@ -184,7 +187,7 @@ export default Vue.extend({
|
|||||||
enableWidgets: window.innerWidth >= 1100,
|
enableWidgets: window.innerWidth >= 1100,
|
||||||
canBack: false,
|
canBack: false,
|
||||||
disconnectedDialog: null as Promise<void> | null,
|
disconnectedDialog: null as Promise<void> | null,
|
||||||
faChevronLeft, faComments, faHashtag, faBroadcastTower, faFireAlt, faEllipsisH, faPencilAlt, faBars, faTimes, faBell, faSearch, faUserCog, faCog, faUser, faHome, faStar, faCircle, faAt, faEnvelope, faListUl, faPlus, faUserClock, faLaugh, faUsers, faTachometerAlt, faExchangeAlt, faGlobe, faChartBar, faCloud, faServer
|
faGripVertical, faChevronLeft, faComments, faHashtag, faBroadcastTower, faFireAlt, faEllipsisH, faPencilAlt, faBars, faTimes, faBell, faSearch, faUserCog, faCog, faUser, faHome, faStar, faCircle, faAt, faEnvelope, faListUl, faPlus, faUserClock, faLaugh, faUsers, faTachometerAlt, faExchangeAlt, faGlobe, faChartBar, faCloud, faServer
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -199,7 +202,7 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
widgets(): any[] {
|
widgets(): any[] {
|
||||||
return this.$store.state.settings.widgets;
|
return this.$store.state.deviceUser.widgets;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -230,9 +233,15 @@ export default Vue.extend({
|
|||||||
this.connection.on('notification', this.onNotification);
|
this.connection.on('notification', this.onNotification);
|
||||||
|
|
||||||
if (this.widgets.length === 0) {
|
if (this.widgets.length === 0) {
|
||||||
this.$store.dispatch('settings/setWidgets', [{
|
this.$store.commit('deviceUser/setWidgets', [{
|
||||||
name: 'notifications',
|
name: 'calendar',
|
||||||
id: 'a', data: {}
|
id: 'a', data: {}
|
||||||
|
}, {
|
||||||
|
name: 'notifications',
|
||||||
|
id: 'b', data: {}
|
||||||
|
}, {
|
||||||
|
name: 'trends',
|
||||||
|
id: 'c', data: {}
|
||||||
}]);
|
}]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -256,21 +265,34 @@ export default Vue.extend({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
setInterval(() => {
|
mounted() {
|
||||||
if (this.showNav) return; // TODO: トランジション中も false になるので、これだけでは不十分
|
|
||||||
this.$refs.title.style.left = (this.$refs.main.getBoundingClientRect().left - this.$refs.nav.offsetWidth) + 'px';
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
// https://stackoverflow.com/questions/33891709/when-flexbox-items-wrap-in-column-mode-container-does-not-grow-its-width
|
// https://stackoverflow.com/questions/33891709/when-flexbox-items-wrap-in-column-mode-container-does-not-grow-its-width
|
||||||
if (this.enableWidgets) {
|
if (this.enableWidgets) {
|
||||||
setInterval(() => {
|
const adjustWidgetsWidth = () => {
|
||||||
if (!this.$refs.widgetsEditButton) return;
|
const lastChild = this.$refs.widgets.children[this.$refs.widgets.children.length - 1];
|
||||||
|
if (lastChild == null) return;
|
||||||
|
|
||||||
const width = this.$refs.widgetsEditButton.offsetLeft + 300;
|
const width = lastChild.offsetLeft + 300;
|
||||||
this.$refs.widgets.style.width = width + 'px';
|
this.$refs.widgets.style.width = width + 'px';
|
||||||
}, 1000);
|
};
|
||||||
|
setInterval(adjustWidgetsWidth, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const adjustTitlePosition = () => {
|
||||||
|
this.$refs.title.style.left = (this.$refs.main.getBoundingClientRect().left - this.$refs.nav.offsetWidth) + 'px';
|
||||||
|
};
|
||||||
|
|
||||||
|
adjustTitlePosition();
|
||||||
|
|
||||||
|
const ro = new ResizeObserver((entries, observer) => {
|
||||||
|
adjustTitlePosition();
|
||||||
|
});
|
||||||
|
|
||||||
|
ro.observe(this.$refs.contents);
|
||||||
|
|
||||||
|
window.addEventListener('resize', adjustTitlePosition);
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
@ -482,9 +504,10 @@ export default Vue.extend({
|
|||||||
this.$store.dispatch('switchAccount', {
|
this.$store.dispatch('switchAccount', {
|
||||||
...i,
|
...i,
|
||||||
token: token
|
token: token
|
||||||
});
|
}).then(() => {
|
||||||
location.reload();
|
location.reload();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onNotification(notification) {
|
onNotification(notification) {
|
||||||
@ -530,7 +553,7 @@ export default Vue.extend({
|
|||||||
items: widgets.map(widget => ({
|
items: widgets.map(widget => ({
|
||||||
text: this.$t('_widgets.' + widget),
|
text: this.$t('_widgets.' + widget),
|
||||||
action: () => {
|
action: () => {
|
||||||
this.$store.dispatch('settings/addWidget', {
|
this.$store.commit('deviceUser/addWidget', {
|
||||||
name: widget,
|
name: widget,
|
||||||
id: uuid(),
|
id: uuid(),
|
||||||
data: {}
|
data: {}
|
||||||
@ -542,11 +565,11 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
removeWidget(widget) {
|
removeWidget(widget) {
|
||||||
this.$store.dispatch('settings/removeWidget', widget);
|
this.$store.commit('deviceUser/removeWidget', widget);
|
||||||
},
|
},
|
||||||
|
|
||||||
saveHome() {
|
saveHome() {
|
||||||
this.$store.dispatch('settings/setWidgets', this.widgets);
|
this.$store.commit('deviceUser/setWidgets', this.widgets);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -709,18 +732,20 @@ export default Vue.extend({
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
> [data-icon] {
|
> .edit {
|
||||||
position: absolute;
|
padding: 16px;
|
||||||
top: 0;
|
|
||||||
left: 16px;
|
&.active {
|
||||||
height: $header-height;
|
color: var(--accent);
|
||||||
pointer-events: none;
|
}
|
||||||
font-size: 16px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
> .search {
|
> .search {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
> input {
|
||||||
$margin: 8px;
|
$margin: 8px;
|
||||||
width: calc(100% - #{$post-button-size + $post-button-margin + $margin});
|
width: 200px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
margin-right: $margin;
|
margin-right: $margin;
|
||||||
padding: 0 12px 0 42px;
|
padding: 0 12px 0 42px;
|
||||||
@ -736,6 +761,16 @@ export default Vue.extend({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
> [data-icon] {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 16px;
|
||||||
|
height: 100%;
|
||||||
|
pointer-events: none;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
> .post {
|
> .post {
|
||||||
width: $post-button-size;
|
width: $post-button-size;
|
||||||
height: $post-button-size;
|
height: $post-button-size;
|
||||||
@ -971,12 +1006,6 @@ export default Vue.extend({
|
|||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
> .edit {
|
|
||||||
display: block;
|
|
||||||
font-size: 0.9em;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.customize-container {
|
.customize-container {
|
||||||
margin: 8px 0;
|
margin: 8px 0;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
94
src/client/components/link.vue
Normal file
94
src/client/components/link.vue
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
<template>
|
||||||
|
<component :is="hasRoute ? 'router-link' : 'a'" class="xlcxczvw _link" :[attr]="hasRoute ? url.substr(local.length) : url" :rel="rel" :target="target"
|
||||||
|
@mouseover="onMouseover"
|
||||||
|
@mouseleave="onMouseleave"
|
||||||
|
:title="url"
|
||||||
|
>
|
||||||
|
<slot></slot>
|
||||||
|
<fa :icon="faExternalLinkSquareAlt" v-if="target === '_blank'" class="icon"/>
|
||||||
|
</component>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
import { faExternalLinkSquareAlt } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
import { url as local } from '../config';
|
||||||
|
import XUrlPreview from './url-preview-popup.vue';
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
props: {
|
||||||
|
url: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
rel: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
const isSelf = this.url.startsWith(local);
|
||||||
|
const hasRoute = isSelf && (
|
||||||
|
(this.url.substr(local.length) === '/') ||
|
||||||
|
this.url.substr(local.length).startsWith('/@') ||
|
||||||
|
this.url.substr(local.length).startsWith('/notes/') ||
|
||||||
|
this.url.substr(local.length).startsWith('/tags/'));
|
||||||
|
return {
|
||||||
|
local,
|
||||||
|
self: isSelf,
|
||||||
|
hasRoute: hasRoute,
|
||||||
|
attr: hasRoute ? 'to' : 'href',
|
||||||
|
target: hasRoute ? null : '_blank',
|
||||||
|
showTimer: null,
|
||||||
|
hideTimer: null,
|
||||||
|
preview: null,
|
||||||
|
faExternalLinkSquareAlt
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
showPreview() {
|
||||||
|
if (!document.body.contains(this.$el)) return;
|
||||||
|
if (this.preview) return;
|
||||||
|
|
||||||
|
this.preview = new XUrlPreview({
|
||||||
|
parent: this,
|
||||||
|
propsData: {
|
||||||
|
url: this.url,
|
||||||
|
source: this.$el
|
||||||
|
}
|
||||||
|
}).$mount();
|
||||||
|
|
||||||
|
document.body.appendChild(this.preview.$el);
|
||||||
|
},
|
||||||
|
closePreview() {
|
||||||
|
if (this.preview) {
|
||||||
|
this.preview.destroyDom();
|
||||||
|
this.preview = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onMouseover() {
|
||||||
|
clearTimeout(this.showTimer);
|
||||||
|
clearTimeout(this.hideTimer);
|
||||||
|
this.showTimer = setTimeout(this.showPreview, 500);
|
||||||
|
},
|
||||||
|
onMouseleave() {
|
||||||
|
clearTimeout(this.showTimer);
|
||||||
|
clearTimeout(this.hideTimer);
|
||||||
|
this.hideTimer = setTimeout(this.closePreview, 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.xlcxczvw {
|
||||||
|
word-break: break-all;
|
||||||
|
|
||||||
|
> .icon {
|
||||||
|
padding-left: 2px;
|
||||||
|
font-size: .9em;
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -2,6 +2,7 @@ import Vue, { VNode } from 'vue';
|
|||||||
import { MfmForest } from '../../mfm/types';
|
import { MfmForest } from '../../mfm/types';
|
||||||
import { parse, parsePlain } from '../../mfm/parse';
|
import { parse, parsePlain } from '../../mfm/parse';
|
||||||
import MkUrl from './url.vue';
|
import MkUrl from './url.vue';
|
||||||
|
import MkLink from './link.vue';
|
||||||
import MkMention from './mention.vue';
|
import MkMention from './mention.vue';
|
||||||
import { concat } from '../../prelude/array';
|
import { concat } from '../../prelude/array';
|
||||||
import MkFormula from './formula.vue';
|
import MkFormula from './formula.vue';
|
||||||
@ -158,14 +159,12 @@ export default Vue.component('misskey-flavored-markdown', {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case 'link': {
|
case 'link': {
|
||||||
return [createElement('a', {
|
return [createElement(MkLink, {
|
||||||
attrs: {
|
key: Math.random(),
|
||||||
class: 'link _link',
|
props: {
|
||||||
href: token.node.props.url,
|
url: token.node.props.url,
|
||||||
rel: 'nofollow noopener',
|
rel: 'nofollow noopener',
|
||||||
target: '_blank',
|
},
|
||||||
title: token.node.props.url,
|
|
||||||
}
|
|
||||||
}, genEl(token.children))];
|
}, genEl(token.children))];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,7 +179,7 @@ export default Vue.extend({
|
|||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
localOnly() {
|
localOnly() {
|
||||||
this.$store.commit('device/setLocalOnly', this.localOnly);
|
this.$store.commit('deviceUser/setLocalOnly', this.localOnly);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -215,9 +215,9 @@ export default Vue.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// デフォルト公開範囲
|
// デフォルト公開範囲
|
||||||
this.applyVisibility(this.$store.state.settings.rememberNoteVisibility ? this.$store.state.device.visibility : this.$store.state.settings.defaultNoteVisibility);
|
this.applyVisibility(this.$store.state.settings.rememberNoteVisibility ? this.$store.state.deviceUser.visibility : this.$store.state.settings.defaultNoteVisibility);
|
||||||
|
|
||||||
this.localOnly = this.$store.state.settings.rememberNoteVisibility ? this.$store.state.device.localOnly : this.$store.state.settings.defaultNoteLocalOnly;
|
this.localOnly = this.$store.state.settings.rememberNoteVisibility ? this.$store.state.deviceUser.localOnly : this.$store.state.settings.defaultNoteLocalOnly;
|
||||||
|
|
||||||
// 公開以外へのリプライ時は元の公開範囲を引き継ぐ
|
// 公開以外へのリプライ時は元の公開範囲を引き継ぐ
|
||||||
if (this.reply && ['home', 'followers', 'specified'].includes(this.reply.visibility)) {
|
if (this.reply && ['home', 'followers', 'specified'].includes(this.reply.visibility)) {
|
||||||
|
56
src/client/components/url-preview-popup.vue
Normal file
56
src/client/components/url-preview-popup.vue
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
<template>
|
||||||
|
<div class="fgmtyycl _panel" :style="{ top: top + 'px', left: left + 'px' }">
|
||||||
|
<x-url-preview :url="url"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
import i18n from '../i18n';
|
||||||
|
import XUrlPreview from './url-preview.vue';
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
i18n,
|
||||||
|
|
||||||
|
components: {
|
||||||
|
XUrlPreview
|
||||||
|
},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
url: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
source: {
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
u: null,
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
const rect = this.source.getBoundingClientRect();
|
||||||
|
const x = ((rect.left + (this.source.offsetWidth / 2)) - (300 / 2)) + window.pageXOffset;
|
||||||
|
const y = rect.top + this.source.offsetHeight + window.pageYOffset;
|
||||||
|
|
||||||
|
this.top = y;
|
||||||
|
this.left = x;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.fgmtyycl {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 11000;
|
||||||
|
width: 500px;
|
||||||
|
overflow: hidden;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,5 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<component :is="hasRoute ? 'router-link' : 'a'" class="ieqqeuvs _link" :[attr]="hasRoute ? url.substr(local.length) : url" :rel="rel" :target="target">
|
<component :is="hasRoute ? 'router-link' : 'a'" class="ieqqeuvs _link" :[attr]="hasRoute ? url.substr(local.length) : url" :rel="rel" :target="target"
|
||||||
|
@mouseover="onMouseover"
|
||||||
|
@mouseleave="onMouseleave"
|
||||||
|
>
|
||||||
<template v-if="!self">
|
<template v-if="!self">
|
||||||
<span class="schema">{{ schema }}//</span>
|
<span class="schema">{{ schema }}//</span>
|
||||||
<span class="hostname">{{ hostname }}</span>
|
<span class="hostname">{{ hostname }}</span>
|
||||||
@ -20,9 +23,19 @@ import Vue from 'vue';
|
|||||||
import { faExternalLinkSquareAlt } from '@fortawesome/free-solid-svg-icons';
|
import { faExternalLinkSquareAlt } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { toUnicode as decodePunycode } from 'punycode';
|
import { toUnicode as decodePunycode } from 'punycode';
|
||||||
import { url as local } from '../config';
|
import { url as local } from '../config';
|
||||||
|
import XUrlPreview from './url-preview-popup.vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
props: ['url', 'rel'],
|
props: {
|
||||||
|
url: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
rel: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
const isSelf = this.url.startsWith(local);
|
const isSelf = this.url.startsWith(local);
|
||||||
const hasRoute = isSelf && (
|
const hasRoute = isSelf && (
|
||||||
@ -32,16 +45,19 @@ export default Vue.extend({
|
|||||||
this.url.substr(local.length).startsWith('/tags/'));
|
this.url.substr(local.length).startsWith('/tags/'));
|
||||||
return {
|
return {
|
||||||
local,
|
local,
|
||||||
schema: null,
|
schema: null as string | null,
|
||||||
hostname: null,
|
hostname: null as string | null,
|
||||||
port: null,
|
port: null as string | null,
|
||||||
pathname: null,
|
pathname: null as string | null,
|
||||||
query: null,
|
query: null as string | null,
|
||||||
hash: null,
|
hash: null as string | null,
|
||||||
self: isSelf,
|
self: isSelf,
|
||||||
hasRoute: hasRoute,
|
hasRoute: hasRoute,
|
||||||
attr: hasRoute ? 'to' : 'href',
|
attr: hasRoute ? 'to' : 'href',
|
||||||
target: hasRoute ? null : '_blank',
|
target: hasRoute ? null : '_blank',
|
||||||
|
showTimer: null,
|
||||||
|
hideTimer: null,
|
||||||
|
preview: null,
|
||||||
faExternalLinkSquareAlt
|
faExternalLinkSquareAlt
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -53,6 +69,38 @@ export default Vue.extend({
|
|||||||
this.pathname = decodeURIComponent(url.pathname);
|
this.pathname = decodeURIComponent(url.pathname);
|
||||||
this.query = decodeURIComponent(url.search);
|
this.query = decodeURIComponent(url.search);
|
||||||
this.hash = decodeURIComponent(url.hash);
|
this.hash = decodeURIComponent(url.hash);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
showPreview() {
|
||||||
|
if (!document.body.contains(this.$el)) return;
|
||||||
|
if (this.preview) return;
|
||||||
|
|
||||||
|
this.preview = new XUrlPreview({
|
||||||
|
parent: this,
|
||||||
|
propsData: {
|
||||||
|
url: this.url,
|
||||||
|
source: this.$el
|
||||||
|
}
|
||||||
|
}).$mount();
|
||||||
|
|
||||||
|
document.body.appendChild(this.preview.$el);
|
||||||
|
},
|
||||||
|
closePreview() {
|
||||||
|
if (this.preview) {
|
||||||
|
this.preview.destroyDom();
|
||||||
|
this.preview = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onMouseover() {
|
||||||
|
clearTimeout(this.showTimer);
|
||||||
|
clearTimeout(this.hideTimer);
|
||||||
|
this.showTimer = setTimeout(this.showPreview, 500);
|
||||||
|
},
|
||||||
|
onMouseleave() {
|
||||||
|
clearTimeout(this.showTimer);
|
||||||
|
clearTimeout(this.hideTimer);
|
||||||
|
this.hideTimer = setTimeout(this.closePreview, 500);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import { faAt, faListUl, faEye, faEyeSlash, faBan, faPencilAlt, faComments } from '@fortawesome/free-solid-svg-icons';
|
import { faAt, faListUl, faEye, faEyeSlash, faBan, faPencilAlt, faComments, faUsers } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { faSnowflake, faEnvelope } from '@fortawesome/free-regular-svg-icons';
|
import { faSnowflake, faEnvelope } from '@fortawesome/free-regular-svg-icons';
|
||||||
import i18n from '../i18n';
|
import i18n from '../i18n';
|
||||||
import XMenu from './menu.vue';
|
import XMenu from './menu.vue';
|
||||||
@ -43,7 +43,11 @@ export default Vue.extend({
|
|||||||
icon: faListUl,
|
icon: faListUl,
|
||||||
text: this.$t('addToList'),
|
text: this.$t('addToList'),
|
||||||
action: this.pushList
|
action: this.pushList
|
||||||
}] as any;
|
}, this.$store.state.i.id != this.user.id ? {
|
||||||
|
icon: faUsers,
|
||||||
|
text: this.$t('inviteToGroup'),
|
||||||
|
action: this.inviteGroup
|
||||||
|
} : undefined] as any;
|
||||||
|
|
||||||
if (this.$store.getters.isSignedIn && this.$store.state.i.id != this.user.id) {
|
if (this.$store.getters.isSignedIn && this.$store.state.i.id != this.user.id) {
|
||||||
menu = menu.concat([null, {
|
menu = menu.concat([null, {
|
||||||
@ -118,6 +122,42 @@ export default Vue.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async inviteGroup() {
|
||||||
|
const groups = await this.$root.api('users/groups/owned');
|
||||||
|
if (groups.length === 0) {
|
||||||
|
this.$root.dialog({
|
||||||
|
type: 'error',
|
||||||
|
text: this.$t('youHaveNoGroups')
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { canceled, result: groupId } = await this.$root.dialog({
|
||||||
|
type: null,
|
||||||
|
title: this.$t('group'),
|
||||||
|
select: {
|
||||||
|
items: groups.map(group => ({
|
||||||
|
value: group.id, text: group.name
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
showCancelButton: true
|
||||||
|
});
|
||||||
|
if (canceled) return;
|
||||||
|
this.$root.api('users/groups/invite', {
|
||||||
|
groupId: groupId,
|
||||||
|
userId: this.user.id
|
||||||
|
}).then(() => {
|
||||||
|
this.$root.dialog({
|
||||||
|
type: 'success',
|
||||||
|
iconOnly: true, autoClose: true
|
||||||
|
});
|
||||||
|
}).catch(e => {
|
||||||
|
this.$root.dialog({
|
||||||
|
type: 'error',
|
||||||
|
text: e
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
async toggleMute() {
|
async toggleMute() {
|
||||||
this.$root.api(this.user.isMuted ? 'mute/delete' : 'mute/create', {
|
this.$root.api(this.user.isMuted ? 'mute/delete' : 'mute/create', {
|
||||||
userId: this.user.id
|
userId: this.user.id
|
||||||
|
@ -56,14 +56,14 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
v: this.$store.state.settings.rememberNoteVisibility ? this.$store.state.device.visibility : (this.currentVisibility || this.$store.state.settings.defaultNoteVisibility),
|
v: this.$store.state.settings.rememberNoteVisibility ? this.$store.state.deviceUser.visibility : (this.currentVisibility || this.$store.state.settings.defaultNoteVisibility),
|
||||||
faGlobe, faUnlock, faEnvelope, faHome
|
faGlobe, faUnlock, faEnvelope, faHome
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
choose(visibility) {
|
choose(visibility) {
|
||||||
if (this.$store.state.settings.rememberNoteVisibility) {
|
if (this.$store.state.settings.rememberNoteVisibility) {
|
||||||
this.$store.commit('device/setVisibility', visibility);
|
this.$store.commit('deviceUser/setVisibility', visibility);
|
||||||
}
|
}
|
||||||
this.$emit('chosen', visibility);
|
this.$emit('chosen', visibility);
|
||||||
this.destroyDom();
|
this.destroyDom();
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import { ResizeObserver } from '@juggle/resize-observer';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
inserted(el, binding, vn) {
|
inserted(el, binding, vn) {
|
||||||
const query = binding.value;
|
const query = binding.value;
|
||||||
@ -52,13 +54,16 @@ export default {
|
|||||||
|
|
||||||
calc();
|
calc();
|
||||||
|
|
||||||
el._sizeResizeCb_ = calc;
|
const ro = new ResizeObserver((entries, observer) => {
|
||||||
|
calc();
|
||||||
|
});
|
||||||
|
|
||||||
window.addEventListener('resize', calc);
|
ro.observe(el);
|
||||||
vn.context.$on('hook:activated', calc);
|
|
||||||
|
el._ro_ = ro;
|
||||||
},
|
},
|
||||||
|
|
||||||
unbind(el, binding, vn) {
|
unbind(el, binding, vn) {
|
||||||
window.removeEventListener('resize', el._sizeResizeCb_);
|
el._ro_.unobserve(el);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -91,13 +91,12 @@ export default Vue.extend({
|
|||||||
this.enableLocalTimeline = !meta.disableLocalTimeline || this.$store.state.i.isModerator || this.$store.state.i.isAdmin
|
this.enableLocalTimeline = !meta.disableLocalTimeline || this.$store.state.i.isModerator || this.$store.state.i.isAdmin
|
||||||
) && ['local', 'social'].includes(this.src)) this.src = 'home';
|
) && ['local', 'social'].includes(this.src)) this.src = 'home';
|
||||||
});
|
});
|
||||||
if (this.$store.state.device.tl) {
|
|
||||||
this.src = this.$store.state.device.tl.src;
|
this.src = this.$store.state.deviceUser.tl.src;
|
||||||
if (this.src === 'list') {
|
if (this.src === 'list') {
|
||||||
this.list = this.$store.state.device.tl.arg;
|
this.list = this.$store.state.deviceUser.tl.arg;
|
||||||
} else if (this.src === 'antenna') {
|
} else if (this.src === 'antenna') {
|
||||||
this.antenna = this.$store.state.device.tl.arg;
|
this.antenna = this.$store.state.deviceUser.tl.arg;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -164,7 +163,7 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
saveSrc() {
|
saveSrc() {
|
||||||
this.$store.commit('device/setTl', {
|
this.$store.commit('deviceUser/setTl', {
|
||||||
src: this.src,
|
src: this.src,
|
||||||
arg: this.src == 'list' ? this.list : this.antenna
|
arg: this.src == 'list' ? this.list : this.antenna
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mk-note-page">
|
<div class="mk-note-page">
|
||||||
|
<portal to="avatar" v-if="note"><mk-avatar class="avatar" :user="note.user" :disable-preview="true"/></portal>
|
||||||
|
<portal to="title" v-if="note">{{ $t('noteOf', { user: note.user.name }) }}</portal>
|
||||||
|
|
||||||
<transition name="zoom" mode="out-in">
|
<transition name="zoom" mode="out-in">
|
||||||
<x-note v-if="note" :note="note" :key="note.id" :detail="true"/>
|
<x-note v-if="note" :note="note" :key="note.id" :detail="true"/>
|
||||||
<div v-else-if="error">
|
<div v-else-if="error">
|
||||||
|
@ -16,7 +16,15 @@ const defaultSettings = {
|
|||||||
wallpaper: null,
|
wallpaper: null,
|
||||||
memo: null,
|
memo: null,
|
||||||
reactions: ['👍', '❤️', '😆', '🤔', '😮', '🎉', '💢', '😥', '😇', '🍮'],
|
reactions: ['👍', '❤️', '😆', '🤔', '😮', '🎉', '💢', '😥', '😇', '🍮'],
|
||||||
widgets: []
|
};
|
||||||
|
|
||||||
|
const defaultDeviceUserSettings = {
|
||||||
|
visibility: 'public',
|
||||||
|
localOnly: false,
|
||||||
|
widgets: [],
|
||||||
|
tl: {
|
||||||
|
src: 'home'
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultDeviceSettings = {
|
const defaultDeviceSettings = {
|
||||||
@ -27,16 +35,19 @@ const defaultDeviceSettings = {
|
|||||||
autoReload: false,
|
autoReload: false,
|
||||||
accounts: [],
|
accounts: [],
|
||||||
recentEmojis: [],
|
recentEmojis: [],
|
||||||
visibility: 'public',
|
|
||||||
localOnly: false,
|
|
||||||
themes: [],
|
themes: [],
|
||||||
theme: 'light',
|
theme: 'light',
|
||||||
animation: true,
|
animation: true,
|
||||||
|
userData: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function copy(data) {
|
||||||
|
return JSON.parse(JSON.stringify(data));
|
||||||
|
}
|
||||||
|
|
||||||
export default (os: MiOS) => new Vuex.Store({
|
export default (os: MiOS) => new Vuex.Store({
|
||||||
plugins: [createPersistedState({
|
plugins: [createPersistedState({
|
||||||
paths: ['i', 'device', 'settings']
|
paths: ['i', 'device', 'deviceUser', 'settings']
|
||||||
})],
|
})],
|
||||||
|
|
||||||
state: {
|
state: {
|
||||||
@ -58,10 +69,11 @@ export default (os: MiOS) => new Vuex.Store({
|
|||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
login(ctx, i) {
|
async login(ctx, i) {
|
||||||
ctx.commit('updateI', i);
|
ctx.commit('updateI', i);
|
||||||
ctx.dispatch('settings/merge', i.clientData);
|
ctx.commit('settings/init', i.clientData);
|
||||||
ctx.dispatch('addAcount', { id: i.id, i: localStorage.getItem('i') });
|
ctx.commit('deviceUser/init', ctx.state.device.userData[i.id] || {});
|
||||||
|
await ctx.dispatch('addAcount', { id: i.id, i: localStorage.getItem('i') });
|
||||||
},
|
},
|
||||||
|
|
||||||
addAcount(ctx, info) {
|
addAcount(ctx, info) {
|
||||||
@ -74,14 +86,17 @@ export default (os: MiOS) => new Vuex.Store({
|
|||||||
},
|
},
|
||||||
|
|
||||||
logout(ctx) {
|
logout(ctx) {
|
||||||
|
ctx.commit('device/setUserData', { userId: ctx.state.i.id, data: ctx.state.deviceUser });
|
||||||
ctx.commit('updateI', null);
|
ctx.commit('updateI', null);
|
||||||
|
ctx.commit('settings/init', {});
|
||||||
|
ctx.commit('deviceUser/init', {});
|
||||||
localStorage.removeItem('i');
|
localStorage.removeItem('i');
|
||||||
},
|
},
|
||||||
|
|
||||||
switchAccount(ctx, i) {
|
async switchAccount(ctx, i) {
|
||||||
ctx.commit('updateI', i);
|
ctx.commit('device/setUserData', { userId: ctx.state.i.id, data: ctx.state.deviceUser });
|
||||||
ctx.commit('settings/init', i.clientData);
|
|
||||||
localStorage.setItem('i', i.token);
|
localStorage.setItem('i', i.token);
|
||||||
|
await ctx.dispatch('login', i);
|
||||||
},
|
},
|
||||||
|
|
||||||
mergeMe(ctx, me) {
|
mergeMe(ctx, me) {
|
||||||
@ -90,7 +105,7 @@ export default (os: MiOS) => new Vuex.Store({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (me.clientData) {
|
if (me.clientData) {
|
||||||
ctx.dispatch('settings/merge', me.clientData);
|
ctx.commit('settings/init', me.clientData);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -106,6 +121,32 @@ export default (os: MiOS) => new Vuex.Store({
|
|||||||
state[x.key] = x.value;
|
state[x.key] = x.value;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setUserData(state, x: { userId: string; data: any }) {
|
||||||
|
state.userData[x.userId] = copy(x.data);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
deviceUser: {
|
||||||
|
namespaced: true,
|
||||||
|
|
||||||
|
state: defaultDeviceUserSettings,
|
||||||
|
|
||||||
|
mutations: {
|
||||||
|
init(state, x) {
|
||||||
|
for (const [key, value] of Object.entries(defaultDeviceUserSettings)) {
|
||||||
|
if (x[key]) {
|
||||||
|
state[key] = x[key];
|
||||||
|
} else {
|
||||||
|
state[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
set(state, x: { key: string; value: any }) {
|
||||||
|
state[x.key] = x.value;
|
||||||
|
},
|
||||||
|
|
||||||
setTl(state, x) {
|
setTl(state, x) {
|
||||||
state.tl = {
|
state.tl = {
|
||||||
src: x.src,
|
src: x.src,
|
||||||
@ -120,6 +161,25 @@ export default (os: MiOS) => new Vuex.Store({
|
|||||||
setLocalOnly(state, localOnly) {
|
setLocalOnly(state, localOnly) {
|
||||||
state.localOnly = localOnly;
|
state.localOnly = localOnly;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setWidgets(state, widgets) {
|
||||||
|
state.widgets = widgets;
|
||||||
|
},
|
||||||
|
|
||||||
|
addWidget(state, widget) {
|
||||||
|
state.widgets.unshift(widget);
|
||||||
|
},
|
||||||
|
|
||||||
|
removeWidget(state, widget) {
|
||||||
|
state.widgets = state.widgets.filter(w => w.id != widget.id);
|
||||||
|
},
|
||||||
|
|
||||||
|
updateWidget(state, x) {
|
||||||
|
const w = state.widgets.find(w => w.id == x.id);
|
||||||
|
if (w) {
|
||||||
|
w.data = x.data;
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -145,13 +205,6 @@ export default (os: MiOS) => new Vuex.Store({
|
|||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
merge(ctx, settings) {
|
|
||||||
if (settings == null) return;
|
|
||||||
for (const [key, value] of Object.entries(settings)) {
|
|
||||||
ctx.commit('set', { key, value });
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
set(ctx, x) {
|
set(ctx, x) {
|
||||||
ctx.commit('set', x);
|
ctx.commit('set', x);
|
||||||
|
|
||||||
@ -162,41 +215,6 @@ export default (os: MiOS) => new Vuex.Store({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setWidgets(ctx, widgets) {
|
|
||||||
ctx.state.widgets = widgets;
|
|
||||||
ctx.dispatch('updateWidgets');
|
|
||||||
},
|
|
||||||
|
|
||||||
addWidget(ctx, widget) {
|
|
||||||
ctx.state.widgets.unshift(widget);
|
|
||||||
ctx.dispatch('updateWidgets');
|
|
||||||
},
|
|
||||||
|
|
||||||
removeWidget(ctx, widget) {
|
|
||||||
ctx.state.widgets = ctx.state.widgets.filter(w => w.id != widget.id);
|
|
||||||
ctx.dispatch('updateWidgets');
|
|
||||||
},
|
|
||||||
|
|
||||||
updateWidget(ctx, x) {
|
|
||||||
const w = ctx.state.widgets.find(w => w.id == x.id);
|
|
||||||
if (w) {
|
|
||||||
w.data = x.data;
|
|
||||||
ctx.dispatch('updateWidgets');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
updateWidgets(ctx) {
|
|
||||||
const widgets = ctx.state.widgets;
|
|
||||||
ctx.commit('set', {
|
|
||||||
key: 'widgets',
|
|
||||||
value: widgets
|
|
||||||
});
|
|
||||||
os.api('i/update-client-setting', {
|
|
||||||
name: 'widgets',
|
|
||||||
value: widgets
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ export default function <T extends object>(data: {
|
|||||||
},
|
},
|
||||||
|
|
||||||
save() {
|
save() {
|
||||||
this.$store.dispatch('settings/updateWidget', this.widget);
|
this.$store.commit('deviceUser/updateWidget', this.widget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -3,6 +3,8 @@ import { Note } from '../../models/entities/note';
|
|||||||
import { User } from '../../models/entities/user';
|
import { User } from '../../models/entities/user';
|
||||||
import { NoteUnreads, Antennas, AntennaNotes, Users } from '../../models';
|
import { NoteUnreads, Antennas, AntennaNotes, Users } from '../../models';
|
||||||
|
|
||||||
|
// TODO: 状態が変化していない場合は各種イベントを送信しない
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark a note as read
|
* Mark a note as read
|
||||||
*/
|
*/
|
||||||
|
@ -102,6 +102,11 @@
|
|||||||
normalize-path "^2.0.1"
|
normalize-path "^2.0.1"
|
||||||
through2 "^2.0.3"
|
through2 "^2.0.3"
|
||||||
|
|
||||||
|
"@juggle/resize-observer@3.0.2":
|
||||||
|
version "3.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@juggle/resize-observer/-/resize-observer-3.0.2.tgz#f4f326806826c0da5221411374e4c54902c327bb"
|
||||||
|
integrity sha512-9fEfZIxZ1qTahMSX50pigfSJ/1N6X2oABhmgd4Dt2SsPkZi0lTlvoHu5V2yrGZ6m+oALfS4tJrpx9nbVIxwOYQ==
|
||||||
|
|
||||||
"@koa/cors@3.0.0":
|
"@koa/cors@3.0.0":
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@koa/cors/-/cors-3.0.0.tgz#df021b4df2dadf1e2b04d7c8ddf93ba2d42519cb"
|
resolved "https://registry.yarnpkg.com/@koa/cors/-/cors-3.0.0.tgz#df021b4df2dadf1e2b04d7c8ddf93ba2d42519cb"
|
||||||
|
Reference in New Issue
Block a user