Compare commits

...

25 Commits

Author SHA1 Message Date
ef01eec36e Merge branch 'develop' 2020-03-25 23:21:48 +09:00
5dbdd0e685 12.26.0 2020-03-25 23:21:31 +09:00
5273050ab3 Update patrons 2020-03-25 23:21:23 +09:00
fae3b02e5a 🎨 2020-03-25 23:15:08 +09:00
3489e4af1e 🎨 2020-03-25 22:57:13 +09:00
8e9bd0bbd5 Fix dark mode sync bug 2020-03-25 22:49:42 +09:00
3725b5bc34 New Crowdin translations (#6181)
* New translations ja-JP.yml (Chinese Simplified)

* New translations ja-JP.yml (Chinese Simplified)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)
2020-03-25 22:40:31 +09:00
998a59aa5e Fix #5986 (#6184)
* Fix #5986

* Fix #5986 追加修正
2020-03-25 22:26:50 +09:00
86c017674a Update favicon.png 2020-03-25 21:24:33 +09:00
cbae87cd11 🎨 2020-03-25 21:19:39 +09:00
5bc1f8d468 Update icon.svg 2020-03-25 19:15:34 +09:00
d3a355e164 Adjust icon size 🎨 2020-03-25 19:10:41 +09:00
45413c9d28 Fix #6176 (#6183) 2020-03-25 15:57:35 +09:00
082ee8836f Update icon 🎨 2020-03-25 14:54:34 +09:00
2f5bd5e6d7 Update CHANGELOG.md 2020-03-24 21:12:24 +09:00
639e0137cc Merge branch 'develop' 2020-03-23 19:48:33 +09:00
2f898aa037 12.25.0 2020-03-23 19:48:19 +09:00
a43a225740 Fix #6180 2020-03-23 19:47:02 +09:00
833c39969b Refactor 2020-03-23 19:42:26 +09:00
e25dea27e7 Better theme validation 2020-03-23 19:09:20 +09:00
dac962580b テーマインポート機能を実装するなど 2020-03-23 19:06:46 +09:00
b12bf78c6d Update CHANGELOG.md 2020-03-23 13:17:29 +09:00
a44b005f7c Merge branch 'develop' 2020-03-22 20:23:58 +09:00
4ea65dbe41 12.24.2 2020-03-22 20:23:47 +09:00
90ba51ee9c Fix dark mode sync 2020-03-22 20:23:35 +09:00
31 changed files with 285 additions and 57 deletions

View File

@ -1,6 +1,43 @@
ChangeLog
=========
12.25.0 (2020/03/24)
-------------------
### ✨Improvements
* テーマインポート機能を実装
### 🐛Fixes
* 誰もフォローしていないときにタイムラインの読み込みが遅い問題を修正
12.24.2 (2020/03/22)
-------------------
### 🐛Fixes
* ダークモードの同期を修正
12.24.1 (2020/03/22)
-------------------
### ✨Improvements
* SVG形式のアイコンファイルを追加
### 🐛Fixes
* iOSで起動できない問題を修正
* 画面が小さいとメニューがすべて見えない問題を修正
* Pages画面にタイトルがない問題を修正
12.24.0 (2020/03/22)
-------------------
### ✨Improvements
* クライアント設定にアカウント設定へのリンクを追加
* ダークモードの同期を強化
### 🐛Fixes
* 画面が小さいとメニューがすべて見えない問題を修正
12.23.0 (2020/03/22)
-------------------

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

View File

@ -1,20 +1,27 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 512 512" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<path d="M416,199.998C416,177.908 398.092,160 376.002,160L312.038,160C301.419,160 291.235,164.218 283.727,171.727C276.218,179.235 272,189.419 272,200.038L272,228C272,234.627 277.373,240 284,240L376.002,240C398.092,240 416,222.092 416,200.002L416,199.998Z" style="fill:url(#_Linear1);"/>
<g transform="matrix(6.12323e-17,1,-1,6.12323e-17,512,-4.54747e-13)">
<path d="M416,199.998C416,177.908 398.092,160 376.002,160L312.038,160C301.419,160 291.235,164.218 283.727,171.727C276.218,179.235 272,189.419 272,200.038L272,228C272,234.627 277.373,240 284,240L376.002,240C398.092,240 416,222.092 416,200.002L416,199.998Z" style="fill:url(#_Linear2);"/>
<svg width="100%" height="100%" viewBox="0 0 256 256" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(0.413372,0,0,0.469741,64.564,40.5821)">
<rect x="-156.189" y="-86.393" width="619.297" height="544.981" style="fill:rgb(27,30,31);"/>
</g>
<g transform="matrix(-1,1.22465e-16,-1.22465e-16,-1,512,512)">
<path d="M416,199.998C416,177.908 398.092,160 376.002,160L312.038,160C301.419,160 291.235,164.218 283.727,171.727C276.218,179.235 272,189.419 272,200.038L272,228C272,234.627 277.373,240 284,240L376.002,240C398.092,240 416,222.092 416,200.002L416,199.998Z" style="fill:url(#_Linear3);"/>
<g transform="matrix(0.898356,0,0,0.898356,-130.722,-120.968)">
<g transform="matrix(0.5,0.866025,-0.866025,0.5,288,-166.277)">
<path d="M390.877,136.653C389.457,134.193 386.831,132.677 383.99,132.677C381.149,132.677 378.524,134.193 377.103,136.653C373.093,143.599 368.146,152.168 364.604,158.303C361.749,163.248 361.749,169.34 364.604,174.285C368.142,180.414 373.084,188.972 377.092,195.915C378.515,198.379 381.144,199.898 383.99,199.898C386.836,199.898 389.466,198.379 390.889,195.915C394.897,188.972 399.838,180.414 403.377,174.284C406.232,169.34 406.232,163.248 403.377,158.303C399.835,152.168 394.888,143.599 390.877,136.653Z" style="fill:white;"/>
</g>
<g transform="matrix(1,0,0,1,-96,166.277)">
<path d="M390.877,136.653C389.457,134.193 386.831,132.677 383.99,132.677C381.149,132.677 378.524,134.193 377.103,136.653C373.093,143.599 368.146,152.168 364.604,158.303C361.749,163.248 361.749,169.34 364.604,174.285C368.142,180.414 373.084,188.972 377.092,195.915C378.515,198.379 381.144,199.898 383.99,199.898C386.836,199.898 389.466,198.379 390.889,195.915C394.897,188.972 399.838,180.414 403.377,174.284C406.232,169.34 406.232,163.248 403.377,158.303C399.835,152.168 394.888,143.599 390.877,136.653Z" style="fill:rgb(150,208,74);"/>
</g>
<g transform="matrix(0.5,-0.866025,0.866025,0.5,-96,498.831)">
<path d="M390.877,136.653C389.457,134.193 386.831,132.677 383.99,132.677C381.149,132.677 378.524,134.193 377.103,136.653C373.093,143.599 368.146,152.168 364.604,158.303C361.749,163.248 361.749,169.34 364.604,174.285C368.142,180.414 373.084,188.972 377.092,195.915C378.515,198.379 381.144,199.898 383.99,199.898C386.836,199.898 389.466,198.379 390.889,195.915C394.897,188.972 399.838,180.414 403.377,174.284C406.232,169.34 406.232,163.248 403.377,158.303C399.835,152.168 394.888,143.599 390.877,136.653Z" style="fill:white;"/>
</g>
<g transform="matrix(1,0,0,1,-95.9902,55.4086)">
<path d="M390.877,136.653C389.457,134.193 386.831,132.677 383.99,132.677C381.149,132.677 378.524,134.193 377.103,136.653C373.093,143.599 368.146,152.168 364.604,158.303C361.749,163.248 361.749,169.34 364.604,174.285C368.142,180.414 373.084,188.972 377.092,195.915C378.515,198.379 381.144,199.898 383.99,199.898C386.836,199.898 389.466,198.379 390.889,195.915C394.897,188.972 399.838,180.414 403.377,174.284C406.232,169.34 406.232,163.248 403.377,158.303C399.835,152.168 394.888,143.599 390.877,136.653ZM385.681,139.653C385.332,139.049 384.688,138.677 383.99,138.677C383.293,138.677 382.648,139.049 382.299,139.653C378.289,146.599 373.342,155.168 369.8,161.303C368.017,164.391 368.017,168.196 369.8,171.285C373.339,177.414 378.28,185.972 382.288,192.915C382.639,193.523 383.288,193.898 383.99,193.898C384.692,193.898 385.341,193.523 385.692,192.915C389.701,185.972 394.642,177.414 398.181,171.284C399.964,168.196 399.964,164.391 398.181,161.303L385.681,139.653Z" style="fill:white;"/>
</g>
<g transform="matrix(0.5,-0.866025,0.866025,0.5,-2.64322e-11,554.256)">
<path d="M390.877,136.653C389.457,134.193 386.831,132.677 383.99,132.677C381.149,132.677 378.524,134.193 377.103,136.653C373.093,143.599 368.146,152.168 364.604,158.303C361.749,163.248 361.749,169.34 364.604,174.285C368.142,180.414 373.084,188.972 377.092,195.915C378.515,198.379 381.144,199.898 383.99,199.898C386.836,199.898 389.466,198.379 390.889,195.915C394.897,188.972 399.838,180.414 403.377,174.284C406.232,169.34 406.232,163.248 403.377,158.303C399.835,152.168 394.888,143.599 390.877,136.653ZM385.681,139.653C385.332,139.049 384.688,138.677 383.99,138.677C383.293,138.677 382.648,139.049 382.299,139.653C378.289,146.599 373.342,155.168 369.8,161.303C368.017,164.391 368.017,168.196 369.8,171.285C373.339,177.414 378.28,185.972 382.288,192.915C382.639,193.523 383.288,193.898 383.99,193.898C384.692,193.898 385.341,193.523 385.692,192.915C389.701,185.972 394.642,177.414 398.181,171.284C399.964,168.196 399.964,164.391 398.181,161.303L385.681,139.653Z" style="fill:white;"/>
</g>
<g transform="matrix(0.5,0.866025,-0.866025,0.5,192,-110.851)">
<path d="M390.877,136.653C389.457,134.193 386.831,132.677 383.99,132.677C381.149,132.677 378.524,134.193 377.103,136.653C373.093,143.599 368.146,152.168 364.604,158.303C361.749,163.248 361.749,169.34 364.604,174.285C368.142,180.414 373.084,188.972 377.092,195.915C378.515,198.379 381.144,199.898 383.99,199.898C386.836,199.898 389.466,198.379 390.889,195.915C394.897,188.972 399.838,180.414 403.377,174.284C406.232,169.34 406.232,163.248 403.377,158.303C399.835,152.168 394.888,143.599 390.877,136.653ZM385.681,139.653C385.332,139.049 384.688,138.677 383.99,138.677C383.293,138.677 382.648,139.049 382.299,139.653C378.289,146.599 373.342,155.168 369.8,161.303C368.017,164.391 368.017,168.196 369.8,171.285C373.339,177.414 378.28,185.972 382.288,192.915C382.639,193.523 383.288,193.898 383.99,193.898C384.692,193.898 385.341,193.523 385.692,192.915C389.701,185.972 394.642,177.414 398.181,171.284C399.964,168.196 399.964,164.391 398.181,161.303L385.681,139.653Z" style="fill:white;"/>
</g>
</g>
<g transform="matrix(6.12323e-17,-1,1,6.12323e-17,0,512)">
<path d="M416,199.998C416,177.908 398.092,160 376.002,160L312.038,160C301.419,160 291.235,164.218 283.727,171.727C276.218,179.235 272,189.419 272,200.038L272,228C272,234.627 277.373,240 284,240L376.002,240C398.092,240 416,222.092 416,200.002L416,199.998Z" style="fill:url(#_Linear4);"/>
</g>
<defs>
<linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(144,0,0,80,272,200)"><stop offset="0" style="stop-color:rgb(198,230,111);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(90,200,113);stop-opacity:1"/></linearGradient>
<linearGradient id="_Linear2" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(144,0,0,80,272,200)"><stop offset="0" style="stop-color:rgb(97,232,195);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(90,200,113);stop-opacity:1"/></linearGradient>
<linearGradient id="_Linear3" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(144,0,0,80,272,200)"><stop offset="0" style="stop-color:rgb(198,230,111);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(90,200,113);stop-opacity:1"/></linearGradient>
<linearGradient id="_Linear4" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(144,0,0,80,272,200)"><stop offset="0" style="stop-color:rgb(98,232,195);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(90,200,113);stop-opacity:1"/></linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

@ -18,7 +18,7 @@ instance: "Instance"
settings: "Settings"
profile: "Profile"
timeline: "Timeline"
noAccountDescription: "This user has not created their bio yet."
noAccountDescription: "This user has not written their bio yet."
login: "Sign In"
loggingIn: "Signing In"
logout: "Sign Out"
@ -257,7 +257,7 @@ rename: "Rename"
avatar: "Avatar"
banner: "Banner"
nsfw: "NSFW"
disconnectedFromServer: "Connection to the server was inturrupted"
disconnectedFromServer: "Connection to the server was interrupted."
reload: "Refresh"
doNothing: "Ignore"
reloadConfirm: "Would you like to retry?"
@ -331,7 +331,7 @@ userList: "Lists"
about: "About"
aboutMisskey: "About Misskey"
aboutMisskeyText: "Misskey is an open-source software developed by syuilo since 2014."
misskeyMembers: "It is currently developed an maintained by the members listed below:"
misskeyMembers: "It is currently developed and maintained by the members listed below:"
misskeySource: "Source code is available here:"
misskeyTranslation: "Help us with your contribution to translate Misskey:"
misskeyDonate: "Help us to keep improving the software by donating here:"
@ -352,10 +352,10 @@ resetPassword: "Reset password"
newPasswordIs: "The new password is \"{password}\""
post: "Post"
posted: "Posted!"
autoReloadWhenDisconnected: "Auto reload when disconnected with server"
autoReloadWhenDisconnected: "Auto reload when disconnected from server"
autoNoteWatch: "Watch note automatically"
autoNoteWatchDescription: "Get notified about the notes which you reactioned or replied."
reduceUiAnimation: "Reduce animations of User Interface"
reduceUiAnimation: "Reduce UI animation"
share: "Share"
notFound: "Not found"
notFoundDescription: "There was no page corresponding to the specified URL."
@ -411,11 +411,11 @@ or: "Or"
uiLanguage: "UI display language"
groupInvited: "Invited to group"
aboutX: "About {x}"
useOsNativeEmojis: "Use the OS native Emojis"
useOsNativeEmojis: "Use OS native Emojis"
youHaveNoGroups: "You have no groups"
joinOrCreateGroup: "Get invited to join the groups or you can create your own group."
noHistory: "No history items"
disableAnimatedMfm: "Disable MFM which has animations"
disableAnimatedMfm: "Disable MFM with animation"
doing: "On my way"
category: "Category"
tags: "Tags"
@ -466,6 +466,16 @@ details: "Details"
chooseEmoji: "Choose an emoji"
unableToProcess: "The operation could not be completed."
recentUsed: "Recently used"
install: "Install"
uninstall: "Uninstall"
_theme:
explore: "Explore Themes"
install: "Install theme"
manage: "Themes manager"
code: "Theme code"
installed: "{name} has been installed"
alreadyInstalled: "The theme is already installed"
invalid: "Theme format is invalid"
_sfx:
note: "New note"
noteMy: "My note"

View File

@ -466,6 +466,16 @@ details: "Detalles"
chooseEmoji: "Elije un emoji"
unableToProcess: "La operación no se puede llevar a cabo"
recentUsed: "Usado recientemente"
install: "Instalación"
uninstall: "Desinstalar"
_theme:
explore: "Explorar temas"
install: "Instalar tema"
manage: "Gestor de temas"
code: "Código del tema"
installed: "{name} ha sido instalado"
alreadyInstalled: "Este tema ya está instalado"
invalid: "El formato del tema no es válido"
_sfx:
note: "Notas"
noteMy: "Nota (a mí mismo)"

View File

@ -466,6 +466,16 @@ details: "Détails"
chooseEmoji: "Choisissez des emojis"
unableToProcess: "L'opération n'a pas pu être complétée"
recentUsed: "Récemment utilisé"
install: "Installation"
uninstall: "Désinstaller"
_theme:
explore: "Explorer les thèmes"
install: "Installer un thème"
manage: "Gestion des thèmes"
code: "Code du thème"
installed: "{name} a été installé"
alreadyInstalled: "Ce thème est déjà installé"
invalid: "Le format du thème n'est pas valide"
_sfx:
note: "Nouvelle note"
noteMy: "Ma note"

View File

@ -466,6 +466,17 @@ details: "詳細"
chooseEmoji: "絵文字を選択"
unableToProcess: "操作を完了できません"
recentUsed: "最近使用"
install: "インストール"
uninstall: "アンインストール"
_theme:
explore: "テーマを探す"
install: "テーマのインストール"
manage: "テーマの管理"
code: "テーマコード"
installed: "{name}をインストールしました"
alreadyInstalled: "そのテーマは既にインストールされています"
invalid: "テーマの形式が間違っています"
_sfx:
note: "ノート"

View File

@ -466,6 +466,16 @@ details: "자세히"
chooseEmoji: "이모지 선택"
unableToProcess: "작업을 완료할 수 없습니다"
recentUsed: "최근 사용"
install: "설치"
uninstall: "삭제"
_theme:
explore: "테마 찾아보기"
install: "테마 설치"
manage: "테마 관리"
code: "테마 코드"
installed: "{name} 테마가 설치되었습니다"
alreadyInstalled: "이미 설치된 테마입니다"
invalid: "테마 형식이 올바르지 않습니다"
_sfx:
note: "새 노트"
noteMy: "내 노트"

View File

@ -466,6 +466,16 @@ details: "详情"
chooseEmoji: "选择表情符号"
unableToProcess: "操作无法完成"
recentUsed: "最近使用"
install: "安装"
uninstall: "卸载"
_theme:
explore: "寻找主题"
install: "安装主题"
manage: "主题管理"
code: "主题代码"
installed: "{name} 已安装"
alreadyInstalled: "此主题已经安装"
invalid: "主题格式错误"
_sfx:
note: "帖子"
noteMy: "我的笔记"

View File

@ -1,7 +1,7 @@
{
"name": "misskey",
"author": "syuilo <syuilotan@yahoo.co.jp>",
"version": "12.24.1",
"version": "12.26.0",
"codename": "indigo",
"repository": {
"type": "git",

View File

@ -895,24 +895,25 @@ export default Vue.extend({
color: var(--navActive);
}
&:first-child {
&:first-child, &:last-child {
position: sticky;
z-index: 1;
top: 0;
padding-top: 8px;
padding-bottom: 8px;
background: var(--wboyroyc);
-webkit-backdrop-filter: blur(8px);
backdrop-filter: blur(8px);
}
&:first-child {
top: 0;
margin-bottom: 16px;
background: var(--navBg);
border-bottom: solid 1px var(--divider);
}
&:last-child {
position: sticky;
bottom: 0;
padding-top: 8px;
padding-bottom: 8px;
margin-top: 16px;
background: var(--navBg);
border-top: solid 1px var(--divider);
}

View File

@ -1,6 +1,6 @@
<template>
<div class="mjndxjcg _panel">
<img src="https://xn--931a.moe/assets/error.png" class="_ghost"/>
<img src="https://xn--931a.moe/assets/error.jpg" class="_ghost"/>
<p><fa :icon="faExclamationTriangle"/> {{ $t('error') }}</p>
<mk-button @click="() => $emit('retry')" class="button">{{ $t('retry') }}</mk-button>
</div>

View File

@ -1,7 +1,7 @@
<template>
<div class="mk-notes" v-size="[{ max: 500 }]">
<div class="empty" v-if="empty">
<img src="https://xn--931a.moe/assets/info.png" class="_ghost"/>
<img src="https://xn--931a.moe/assets/info.jpg" class="_ghost"/>
<div>{{ $t('noNotes') }}</div>
</div>

View File

@ -38,7 +38,7 @@
</mk-input>
<mk-switch v-model="ToSAgreement" v-if="meta.tosUrl">
<i18n path="agreeTo">
<a :href="meta.tosUrl" target="_blank">{{ $t('tos') }}</a>
<a :href="meta.tosUrl" class="_link" target="_blank">{{ $t('tos') }}</a>
</i18n>
</mk-switch>
<div v-if="meta.enableRecaptcha" class="g-recaptcha" :data-sitekey="meta.recaptchaSiteKey" style="margin: 16px 0;"></div>

View File

@ -19,6 +19,7 @@ import Dialog from './components/dialog.vue';
import Menu from './components/menu.vue';
import { router } from './router';
import { applyTheme, lightTheme, builtinThemes } from './theme';
import { isDeviceDarkmode } from './scripts/is-device-darkmode';
Vue.use(Vuex);
Vue.use(VueHotkey);
@ -144,11 +145,23 @@ os.init(async () => {
}
}, false)
os.store.watch(state => state.device.darkMode, darkMode => {
// TODO: このファイルでbuiltinThemesを参照するとcode splittingが効かず、初回読み込み時に全てのテーマコードを読み込むことになってしまい無駄なので何とかする
const themes = builtinThemes.concat(os.store.state.device.themes);
applyTheme(themes.find(x => x.id === (darkMode ? os.store.state.device.darkTheme : os.store.state.device.lightTheme)));
});
//#region Sync dark mode
if (os.store.state.device.syncDeviceDarkMode) {
os.store.commit('device/set', { key: 'darkMode', value: isDeviceDarkmode() });
}
window.matchMedia('(prefers-color-scheme: dark)').addListener(mql => {
if (os.store.state.device.syncDeviceDarkMode) {
os.store.commit('device/set', { key: 'darkMode', value: mql.matches });
}
});
//#endregion
if ('Notification' in window && os.store.getters.isSignedIn) {
// 許可を得ていなかったらリクエスト
@ -169,12 +182,6 @@ os.init(async () => {
isMobile: isMobile
};
},
watch: {
'$store.state.device.darkMode'() {
const themes = builtinThemes.concat(this.$store.state.device.themes);
applyTheme(themes.find(x => x.id === (this.$store.state.device.darkMode ? this.$store.state.device.darkTheme : this.$store.state.device.lightTheme)));
}
},
methods: {
api: os.api,
signout: os.signout,

View File

@ -1,9 +1,14 @@
<template>
<div class="znqjceqz">
<portal to="title">🍀 {{ $t('aboutMisskey') }}</portal>
<portal to="title">{{ $t('aboutMisskey') }}</portal>
<section class="_card">
<div class="_title">🍀 {{ $t('aboutMisskey') }}</div>
<div class="_title">{{ $t('aboutMisskey') }}</div>
<div class="_content" style="text-align: center;">
<img src="/assets/icons/512.png" alt="" style="display: block; width: 100px; margin: 0 auto; border-radius: 16px;"/>
<div style="margin-top: 0.75em;">Misskey</div>
<div style="opacity: 0.5;">v{{ version }}</div>
</div>
<div class="_content">
<div style="margin-bottom: 1em;">{{ $t('aboutMisskeyText') }}</div>
<div>🛠 {{ $t('misskeyMembers') }}</div>
@ -44,6 +49,9 @@
<li>wara</li>
<li>Takashi Shibuya</li>
<li>Noizeman</li>
<li>mydarkstar</li>
<li>nenohi</li>
<li>Eduardo Quiros</li>
</ul>
<span>{{ $t('morePatrons') }}</span>
</div>

View File

@ -6,7 +6,7 @@
<mk-pagination :pagination="pagination" class="mk-follow-requests" ref="list">
<template #empty>
<div class="tkdrhpxr">
<img src="https://xn--931a.moe/assets/info.png" class="_ghost"/>
<img src="https://xn--931a.moe/assets/info.jpg" class="_ghost"/>
<div>{{ $t('noFollowRequests') }}</div>
</div>
</template>

View File

@ -64,6 +64,9 @@ export default Vue.extend({
pagination: {
endpoint: 'admin/show-users',
limit: 10,
params: () => ({
sort: '+createdAt'
}),
offsetMode: true
},
target: '',

View File

@ -32,7 +32,7 @@
</router-link>
</div>
<div class="no-history" v-if="!fetching && messages.length == 0">
<img src="https://xn--931a.moe/assets/info.png" class="_ghost"/>
<img src="https://xn--931a.moe/assets/info.jpg" class="_ghost"/>
<div>{{ $t('noHistory') }}</div>
</div>
<mk-loading v-if="fetching"/>

View File

@ -5,7 +5,7 @@
<section class="_card">
<div class="_content">
<img src="https://xn--931a.moe/assets/not-found.png" class="_ghost"/>
<img src="https://xn--931a.moe/assets/not-found.jpg" class="_ghost"/>
<div>{{ $t('notFoundDescription') }}</div>
</div>
</section>

View File

@ -42,6 +42,7 @@
<option v-for="x in lightThemes" :value="x.id" :key="x.id">{{ x.name }}</option>
</optgroup>
</mk-select>
<a href="https://assets.msky.cafe/theme/list" rel="noopener" target="_blank" class="_link">{{ $t('_theme.explore') }}</a>
</div>
<div class="_content">
<mk-switch v-model="syncDeviceDarkMode">{{ $t('syncDeviceDarkMode') }}</mk-switch>
@ -50,18 +51,43 @@
<mk-button primary v-if="wallpaper == null" @click="setWallpaper">{{ $t('setWallpaper') }}</mk-button>
<mk-button primary v-else @click="wallpaper = null">{{ $t('removeWallpaper') }}</mk-button>
</div>
<div class="_content">
<details>
<summary><fa :icon="faDownload"/> {{ $t('_theme.install') }}</summary>
<mk-textarea v-model="installThemeCode">
<span>{{ $t('_theme.code') }}</span>
</mk-textarea>
<mk-button @click="() => install(this.installThemeCode)" :disabled="installThemeCode == null"><fa :icon="faCheck"/> {{ $t('install') }}</mk-button>
</details>
</div>
<div class="_content">
<details>
<summary><fa :icon="faFolderOpen"/> {{ $t('_theme.manage') }}</summary>
<mk-select v-model="selectedThemeId">
<option v-for="x in installedThemes" :value="x.id" :key="x.id">{{ x.name }}</option>
</mk-select>
<template v-if="selectedTheme">
<mk-textarea readonly tall :value="selectedThemeCode">
<span>{{ $t('_theme.code') }}</span>
</mk-textarea>
<mk-button @click="uninstall()" v-if="!builtinThemes.some(t => t.id == selectedTheme.id)"><fa :icon="faTrashAlt"/> {{ $t('uninstall') }}</mk-button>
</template>
</details>
</div>
</section>
</template>
<script lang="ts">
import Vue from 'vue';
import { faPalette } from '@fortawesome/free-solid-svg-icons';
import { faPalette, faDownload, faFolderOpen, faCheck, faTrashAlt } from '@fortawesome/free-solid-svg-icons';
import * as JSON5 from 'json5';
import MkInput from '../../components/ui/input.vue';
import MkButton from '../../components/ui/button.vue';
import MkSelect from '../../components/ui/select.vue';
import MkSwitch from '../../components/ui/switch.vue';
import MkTextarea from '../../components/ui/textarea.vue';
import i18n from '../../i18n';
import { Theme, builtinThemes, applyTheme } from '../../theme';
import { Theme, builtinThemes, applyTheme, validateTheme } from '../../theme';
import { selectFile } from '../../scripts/select-file';
import { isDeviceDarkmode } from '../../scripts/is-device-darkmode';
@ -73,12 +99,16 @@ export default Vue.extend({
MkButton,
MkSelect,
MkSwitch,
MkTextarea,
},
data() {
return {
builtinThemes,
installThemeCode: null,
selectedThemeId: null,
wallpaper: localStorage.getItem('wallpaper'),
faPalette
faPalette, faDownload, faFolderOpen, faCheck, faTrashAlt
}
},
@ -118,6 +148,16 @@ export default Vue.extend({
get() { return this.$store.state.device.syncDeviceDarkMode; },
set(value) { this.$store.commit('device/set', { key: 'syncDeviceDarkMode', value }); }
},
selectedTheme() {
if (this.selectedThemeId == null) return null;
return this.themes.find(x => x.id === this.selectedThemeId);
},
selectedThemeCode() {
if (this.selectedTheme == null) return null;
return JSON5.stringify(this.selectedTheme, null, '\t');
},
},
watch: {
@ -155,6 +195,53 @@ export default Vue.extend({
this.wallpaper = file.url;
});
},
install(code) {
let theme;
try {
theme = JSON5.parse(code);
} catch (e) {
this.$root.dialog({
type: 'error',
text: this.$t('_theme.invalid')
});
return;
}
if (!validateTheme(theme)) {
this.$root.dialog({
type: 'error',
text: this.$t('_theme.invalid')
});
return;
}
if (this.$store.state.device.themes.some(t => t.id === theme.id)) {
this.$root.dialog({
type: 'info',
text: this.$t('_theme.alreadyInstalled')
});
return;
}
const themes = this.$store.state.device.themes.concat(theme);
this.$store.commit('device/set', {
key: 'themes', value: themes
});
this.$root.dialog({
type: 'success',
text: this.$t('_theme.installed', { name: theme.name })
});
},
uninstall() {
const theme = this.selectedTheme;
const themes = this.$store.state.device.themes.filter(t => t.id != theme.id);
this.$store.commit('device/set', {
key: 'themes', value: themes
});
this.$root.dialog({
type: 'info',
iconOnly: true, autoClose: true
});
},
}
});
</script>
@ -179,7 +266,7 @@ export default Vue.extend({
top: 50%;
left: 50%;
overflow: hidden;
padding: 0 200px;
padding: 0 100px;
transform: translate3d(-50%, -50%, 0);
input {

View File

@ -102,3 +102,11 @@ function compile(theme: Theme): { [key: string]: string } {
function genValue(c: tinycolor.Instance): string {
return c.toRgbString();
}
export function validateTheme(theme: Record<string, any>): boolean {
if (theme.id == null || typeof theme.id !== 'string') return false;
if (theme.name == null || typeof theme.name !== 'string') return false;
if (theme.base == null || !['light', 'dark'].includes(theme.base)) return false;
if (theme.props == null || typeof theme.props !== 'object') return false;
return true;
}

View File

@ -65,5 +65,6 @@
aupeazdm: 'rgba(0, 0, 0, 0.3)',
jvhmlskx: 'rgba(255, 255, 255, 0.1)',
yakfpmhl: 'rgba(255, 255, 255, 0.15)',
wboyroyc: ':alpha<0.5<@navBg',
},
}

View File

@ -65,5 +65,6 @@
aupeazdm: 'rgba(0, 0, 0, 0.1)',
jvhmlskx: 'rgba(0, 0, 0, 0.1)',
yakfpmhl: 'rgba(0, 0, 0, 0.15)',
wboyroyc: ':alpha<0.5<@navBg',
},
}

View File

@ -28,15 +28,15 @@ export default define(meta, async (ps, user) => {
const [favorite, watching] = await Promise.all([
NoteFavorites.count({
where: {
userId: user.id,
noteId: ps.noteId
userId: user.id,
noteId: ps.noteId
},
take: 1
}),
NoteWatchings.count({
where: {
userId: user.id,
noteId: ps.noteId
userId: user.id,
noteId: ps.noteId
},
take: 1
})

View File

@ -102,6 +102,13 @@ export const meta = {
};
export default define(meta, async (ps, user) => {
const hasFollowing = (await Followings.count({
where: {
followerId: user.id,
},
take: 1
})) !== 0;
//#region Construct query
const followingQuery = Followings.createQueryBuilder('following')
.select('following.followeeId')
@ -110,8 +117,8 @@ export default define(meta, async (ps, user) => {
const query = makePaginationQuery(Notes.createQueryBuilder('note'),
ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate)
.andWhere(new Brackets(qb => { qb
.where(`note.userId IN (${ followingQuery.getQuery() })`)
.orWhere('note.userId = :meId', { meId: user.id });
.where('note.userId = :meId', { meId: user.id });
if (hasFollowing) qb.orWhere(`note.userId IN (${ followingQuery.getQuery() })`);
}))
.leftJoinAndSelect('note.user', 'user')
.setParameters(followingQuery.getParameters());

View File

@ -16,9 +16,9 @@ html
link(rel='icon' href= icon || '/favicon.ico')
link(rel='apple-touch-icon' href= icon || '/apple-touch-icon.png')
link(rel='manifest' href='/manifest.json')
link(rel='prefetch' href='https://xn--931a.moe/assets/info.png')
link(rel='prefetch' href='https://xn--931a.moe/assets/not-found.png')
link(rel='prefetch' href='https://xn--931a.moe/assets/error.png')
link(rel='prefetch' href='https://xn--931a.moe/assets/info.jpg')
link(rel='prefetch' href='https://xn--931a.moe/assets/not-found.jpg')
link(rel='prefetch' href='https://xn--931a.moe/assets/error.jpg')
title
block title