Compare commits

...

14 Commits

Author SHA1 Message Date
syuilo
294c9840de 12.2.0 2020-02-06 22:27:32 +09:00
syuilo
568ecd9477 Resolve #5861 2020-02-06 22:25:45 +09:00
syuilo
169f3ed541 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2020-02-06 22:18:26 +09:00
syuilo
ff7ae427fd Resolve #5860 2020-02-06 22:18:23 +09:00
tamaina
1597415340 PWAとしてインストールできなかったのを修正 (#5863)
* pwa

* ✌️
2020-02-06 22:11:27 +09:00
syuilo
47f3261b9f Update CHANGELOG.md 2020-02-06 22:10:55 +09:00
syuilo
9e68eefbb7 Resolve #5859 2020-02-06 22:10:33 +09:00
syuilo
630c531d99 Improve messaging form 2020-02-06 19:22:15 +09:00
syuilo
c7da2a4b5f Resolve #5857 2020-02-06 19:11:14 +09:00
syuilo
692078f490 🎨 2020-02-06 18:49:57 +09:00
syuilo
0e29e864c8 Refactor 2020-02-06 18:25:25 +09:00
syuilo
1b7a601d27 Fix i18n 2020-02-06 17:50:59 +09:00
syuilo
a96076ee5b 🎨 2020-02-06 17:48:05 +09:00
syuilo
d580622d1b Update ja-JP.yml 2020-02-06 17:44:41 +09:00
17 changed files with 91 additions and 70 deletions

View File

@@ -1,6 +1,18 @@
ChangeLog ChangeLog
========= =========
12.2.0 (2020/02/06)
--------------------
### ✨Improvements
* UIのアニメーションを無効にできるように
* トークで絵文字ピッカーを表示できるように
* 戻るボタンだけでなく、ホームボタンを押してホームに戻ったときもスクロール位置を復元するように
* タブを見ていないときのタイムライン通知を削除
### 🐛Fixes
* PWAとしてインストールできなかったのを修正
* トークでドライブからファイルを添付出来ない問題を修正
12.1.0 (2020/02/06) 12.1.0 (2020/02/06)
-------------------- --------------------
### ✨Improvements ### ✨Improvements

View File

@@ -350,6 +350,7 @@ post: "投稿"
posted: "投稿しました" posted: "投稿しました"
autoReloadWhenDisconnected: "サーバー切断時に自動リロード" autoReloadWhenDisconnected: "サーバー切断時に自動リロード"
autoNoteWatch: "ノートの自動ウォッチ" autoNoteWatch: "ノートの自動ウォッチ"
reduceUiAnimation: "UIのアニメーションを減らす"
_2fa: _2fa:
registerDevice: "デバイスを登録" registerDevice: "デバイスを登録"
@@ -413,6 +414,7 @@ _widgets:
calendar: "カレンダー" calendar: "カレンダー"
trends: "トレンド" trends: "トレンド"
clock: "時計" clock: "時計"
rss: "RSSリーダー"
_cw: _cw:
hide: "隠す" hide: "隠す"

View File

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

View File

@@ -2,10 +2,10 @@
<div class="mk-app" v-hotkey.global="keymap"> <div class="mk-app" v-hotkey.global="keymap">
<header class="header"> <header class="header">
<div class="title" ref="title"> <div class="title" ref="title">
<transition name="header" mode="out-in" appear> <transition :name="$store.state.device.animation ? 'header' : ''" mode="out-in" appear>
<button class="_button back" v-if="canBack" @click="back()"><fa :icon="faChevronLeft"/></button> <button class="_button back" v-if="canBack" @click="back()"><fa :icon="faChevronLeft"/></button>
</transition> </transition>
<transition name="header" mode="out-in" appear> <transition :name="$store.state.device.animation ? 'header' : ''" mode="out-in" appear>
<div class="body" :key="pageKey"> <div class="body" :key="pageKey">
<div class="default"> <div class="default">
<portal-target name="avatar" slim/> <portal-target name="avatar" slim/>
@@ -76,7 +76,7 @@
<div class="contents"> <div class="contents">
<main ref="main"> <main ref="main">
<div class="content"> <div class="content">
<transition name="page" mode="out-in"> <transition :name="$store.state.device.animation ? 'page' : ''" mode="out-in" @enter="onTransition">
<keep-alive :include="['index']"> <keep-alive :include="['index']">
<router-view></router-view> <router-view></router-view>
</keep-alive> </keep-alive>
@@ -100,9 +100,9 @@
class="sortable" class="sortable"
@sort="onWidgetSort" @sort="onWidgetSort"
> >
<div v-for="widget in widgets" class="customize-container" :key="widget.id"> <div v-for="widget in widgets" class="customize-container _panel" :key="widget.id">
<header> <header>
<span class="handle"><fa :icon="faBars"/></span>{{ widget.name }}<button class="remove" @click="removeWidget(widget)"><fa :icon="faTimes"/></button> <span class="handle"><fa :icon="faBars"/></span>{{ $t('_widgets.' + widget.name) }}<button class="remove _button" @click="removeWidget(widget)"><fa :icon="faTimes"/></button>
</header> </header>
<div @click="widgetFunc(widget.id)"> <div @click="widgetFunc(widget.id)">
<component :is="`mkw-${widget.name}`" :widget="widget" :ref="widget.id" :is-customize-mode="true"/> <component :is="`mkw-${widget.name}`" :widget="widget" :ref="widget.id" :is-customize-mode="true"/>
@@ -258,6 +258,10 @@ export default Vue.extend({
if (this.canBack) window.history.back(); if (this.canBack) window.history.back();
}, },
onTransition() {
if (window._scroll) window._scroll();
},
post() { post() {
this.$root.post(); this.$root.post();
}, },
@@ -965,10 +969,10 @@ export default Vue.extend({
> header { > header {
position: relative; position: relative;
line-height: 32px; line-height: 32px;
background: #eee;
> .handle { > .handle {
padding: 0 8px; padding: 0 8px;
cursor: move;
} }
> .remove { > .remove {

View File

@@ -1,9 +1,9 @@
<template> <template>
<div class="mk-modal"> <div class="mk-modal">
<transition name="bg-fade" appear> <transition :name="$store.state.device.animation ? 'bg-fade' : ''" appear>
<div class="bg" ref="bg" v-if="show" @click="close()"></div> <div class="bg" ref="bg" v-if="show" @click="close()"></div>
</transition> </transition>
<transition name="modal" appear @after-leave="() => { $emit('closed'); destroyDom(); }"> <transition :name="$store.state.device.animation ? 'modal' : ''" appear @after-leave="() => { $emit('closed'); destroyDom(); }">
<div class="content" ref="content" v-if="show" @click.self="close()"><slot></slot></div> <div class="content" ref="content" v-if="show" @click.self="close()"><slot></slot></div>
</transition> </transition>
</div> </div>

View File

@@ -275,8 +275,14 @@ export default Vue.extend({
methods: { methods: {
capture(withHandler = false) { capture(withHandler = false) {
if (this.$store.getters.isSignedIn) { if (this.$store.getters.isSignedIn) {
if (document.body.contains(this.$el)) {
this.connection.send('sn', { id: this.appearNote.id }); this.connection.send('sn', { id: this.appearNote.id });
if (withHandler) this.connection.on('noteUpdated', this.onStreamNoteUpdated); if (withHandler) this.connection.on('noteUpdated', this.onStreamNoteUpdated);
} else {
this.$once('hook:activated', () => {
this.capture(withHandler);
});
}
} }
}, },

View File

@@ -36,19 +36,6 @@ export default Vue.extend({
mixins: [ mixins: [
paging({ paging({
onPrepend: (self, note) => {
// タブが非表示なら通知
if (document.hidden) {
if ('Notification' in window && Notification.permission === 'granted') {
new Notification(getUserName(note.user), {
body: getNoteSummary(note),
icon: note.user.avatarUrl,
tag: 'newNote'
});
}
}
},
before: (self) => { before: (self) => {
self.$emit('before'); self.$emit('before');
}, },

View File

@@ -1,9 +1,9 @@
<template> <template>
<div class="mk-popup"> <div class="mk-popup">
<transition name="bg-fade" appear> <transition :name="$store.state.device.animation ? 'bg-fade' : ''" appear>
<div class="bg" ref="bg" @click="close()" v-if="show"></div> <div class="bg" ref="bg" @click="close()" v-if="show"></div>
</transition> </transition>
<transition name="popup" appear @after-leave="() => { $emit('closed'); destroyDom(); }"> <transition :name="$store.state.device.animation ? 'popup' : ''" appear @after-leave="() => { $emit('closed'); destroyDom(); }">
<div class="content" :class="{ fixed }" ref="content" v-if="show" :style="{ width: width ? width + 'px' : 'auto' }"><slot></slot></div> <div class="content" :class="{ fixed }" ref="content" v-if="show" :style="{ width: width ? width + 'px' : 'auto' }"><slot></slot></div>
</transition> </transition>
</div> </div>

View File

@@ -1,10 +1,10 @@
<template> <template>
<div class="ulveipglmagnxfgvitaxyszerjwiqmwl"> <div class="ulveipglmagnxfgvitaxyszerjwiqmwl">
<transition name="form-fade" appear> <transition :name="$store.state.device.animation ? 'form-fade' : ''" appear>
<div class="bg" ref="bg" v-if="show" @click="close()"></div> <div class="bg" ref="bg" v-if="show" @click="close()"></div>
</transition> </transition>
<div class="main" ref="main" @click.self="close()" @keydown="onKeydown"> <div class="main" ref="main" @click.self="close()" @keydown="onKeydown">
<transition name="form" appear <transition :name="$store.state.device.animation ? 'form' : ''" appear
@after-leave="destroyDom" @after-leave="destroyDom"
> >
<x-post-form ref="form" <x-post-form ref="form"

View File

@@ -1,5 +1,5 @@
<template> <template>
<transition-group <transition-group v-if="$store.state.device.animation"
name="staggered-fade" name="staggered-fade"
tag="div" tag="div"
:css="false" :css="false"
@@ -11,6 +11,9 @@
> >
<slot></slot> <slot></slot>
</transition-group> </transition-group>
<div v-else>
<slot></slot>
</div>
</template> </template>
<script lang="ts"> <script lang="ts">

View File

@@ -5,7 +5,7 @@
> >
<textarea <textarea
v-model="text" v-model="text"
ref="textarea" ref="text"
@keypress="onKeypress" @keypress="onKeypress"
@paste="onPaste" @paste="onPaste"
:placeholder="$t('input-message-here')" :placeholder="$t('input-message-here')"
@@ -16,22 +16,20 @@
<button class="send _button" @click="send" :disabled="!canSend || sending" :title="$t('send')"> <button class="send _button" @click="send" :disabled="!canSend || sending" :title="$t('send')">
<template v-if="!sending"><fa :icon="faPaperPlane"/></template><template v-if="sending"><fa icon="spinner .spin"/></template> <template v-if="!sending"><fa :icon="faPaperPlane"/></template><template v-if="sending"><fa icon="spinner .spin"/></template>
</button> </button>
<button class="attach-from-local _button" @click="chooseFile" :title="$t('attach-from-local')"> <button class="_button" @click="chooseFile"><fa :icon="faPhotoVideo"/></button>
<fa :icon="faUpload"/> <button class="_button" @click="insertEmoji"><fa :icon="faLaughSquint"/></button>
</button>
<button class="attach-from-drive _button" @click="chooseFileFromDrive" :title="$t('attach-from-drive')">
<fa :icon="faCloud"/>
</button>
<input ref="file" type="file" @change="onChangeFile"/> <input ref="file" type="file" @change="onChangeFile"/>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import Vue from 'vue'; import Vue from 'vue';
import { faPaperPlane, faUpload, faCloud } from '@fortawesome/free-solid-svg-icons'; import { faPaperPlane, faPhotoVideo, faLaughSquint } from '@fortawesome/free-solid-svg-icons';
import i18n from '../i18n'; import insertTextAtCursor from 'insert-text-at-cursor';
import * as autosize from 'autosize'; import * as autosize from 'autosize';
import i18n from '../i18n';
import { formatTimeString } from '../../misc/format-time-string'; import { formatTimeString } from '../../misc/format-time-string';
import { selectFile } from '../scripts/select-file';
export default Vue.extend({ export default Vue.extend({
i18n, i18n,
@@ -53,7 +51,7 @@ export default Vue.extend({
text: null, text: null,
file: null, file: null,
sending: false, sending: false,
faPaperPlane, faUpload, faCloud faPaperPlane, faPhotoVideo, faLaughSquint
}; };
}, },
computed: { computed: {
@@ -80,7 +78,7 @@ export default Vue.extend({
} }
}, },
mounted() { mounted() {
autosize(this.$refs.textarea); autosize(this.$refs.text);
// 書きかけの投稿を復元 // 書きかけの投稿を復元
const draft = JSON.parse(localStorage.getItem('message_drafts') || '{}')[this.draftId]; const draft = JSON.parse(localStorage.getItem('message_drafts') || '{}')[this.draftId];
@@ -160,14 +158,8 @@ export default Vue.extend({
} }
}, },
chooseFile() { chooseFile(e) {
(this.$refs.file as any).click(); selectFile(this, e.currentTarget || e.target, this.$t('selectFile'), false).then(file => {
},
chooseFileFromDrive() {
this.$chooseDriveFile({
multiple: false
}).then(file => {
this.file = file; this.file = file;
}); });
}, },
@@ -227,6 +219,15 @@ export default Vue.extend({
localStorage.setItem('message_drafts', JSON.stringify(data)); localStorage.setItem('message_drafts', JSON.stringify(data));
}, },
async insertEmoji(ev) {
const vm = this.$root.new(await import('../components/emoji-picker.vue').then(m => m.default), {
source: ev.currentTarget || ev.target
}).$once('chosen', emoji => {
insertTextAtCursor(this.$refs.text, emoji);
vm.close();
});
}
} }
}); });
</script> </script>
@@ -330,8 +331,7 @@ export default Vue.extend({
} }
} }
.attach-from-local, ._button {
.attach-from-drive {
margin: 0; margin: 0;
padding: 16px; padding: 16px;
font-size: 1em; font-size: 1em;

View File

@@ -32,7 +32,7 @@
</router-link> </router-link>
</sequential-entrance> </sequential-entrance>
<p class="no-history" v-if="!fetching && messages.length == 0">{{ $t('no-history') }}</p> <p class="no-history" v-if="!fetching && messages.length == 0">{{ $t('no-history') }}</p>
<p class="fetching" v-if="fetching"><fa icon="spinner" pulse fixed-width/>{{ $t('@.loading') }}<mk-ellipsis/></p> <mk-loading v-if="fetching"/>
</div> </div>
</template> </template>
@@ -282,17 +282,6 @@ export default Vue.extend({
font-weight: 500; font-weight: 500;
} }
> .fetching {
margin: 0;
padding: 16px;
text-align: center;
color: var(--text);
> [data-icon] {
margin-right: 4px;
}
}
@media (max-width: 400px) { @media (max-width: 400px) {
> .search { > .search {
> .result { > .result {

View File

@@ -22,6 +22,11 @@
<mk-button @click="readAllUnreadNotes">{{ $t('mark-as-read-all-unread-notes') }}</mk-button> <mk-button @click="readAllUnreadNotes">{{ $t('mark-as-read-all-unread-notes') }}</mk-button>
<mk-button @click="readAllMessagingMessages">{{ $t('mark-as-read-all-talk-messages') }}</mk-button> <mk-button @click="readAllMessagingMessages">{{ $t('mark-as-read-all-talk-messages') }}</mk-button>
</div> </div>
<div class="_content">
<mk-switch v-model="reduceAnimation">
{{ $t('reduceUiAnimation') }}
</mk-switch>
</div>
</section> </section>
</template> </template>
@@ -60,6 +65,11 @@ export default Vue.extend({
get() { return this.$store.state.device.autoReload; }, get() { return this.$store.state.device.autoReload; },
set(value) { this.$store.commit('device/set', { key: 'autoReload', value }); } set(value) { this.$store.commit('device/set', { key: 'autoReload', value }); }
}, },
reduceAnimation: {
get() { return !this.$store.state.device.animation; },
set(value) { this.$store.commit('device/set', { key: 'animation', value: !value }); }
},
}, },
methods: { methods: {

View File

@@ -4,7 +4,7 @@
<portal to="avatar" v-if="user"><mk-avatar class="avatar" :user="user" :disable-preview="true"/></portal> <portal to="avatar" v-if="user"><mk-avatar class="avatar" :user="user" :disable-preview="true"/></portal>
<div class="remote-caution _panel" v-if="user.host != null"><fa :icon="faExclamationTriangle" style="margin-right: 8px;"/>{{ $t('remoteUserCaution') }}<a :href="user.url" rel="nofollow noopener" target="_blank">{{ $t('showOnRemote') }}</a></div> <div class="remote-caution _panel" v-if="user.host != null"><fa :icon="faExclamationTriangle" style="margin-right: 8px;"/>{{ $t('remoteUserCaution') }}<a :href="user.url" rel="nofollow noopener" target="_blank">{{ $t('showOnRemote') }}</a></div>
<transition name="zoom" mode="out-in" appear> <transition :name="$store.state.device.animation ? 'zoom' : ''" mode="out-in" appear>
<div class="profile _panel" :key="user.id"> <div class="profile _panel" :key="user.id">
<div class="banner-container" :style="style"> <div class="banner-container" :style="style">
<div class="banner" ref="banner" :style="style"></div> <div class="banner" ref="banner" :style="style"></div>

View File

@@ -6,6 +6,8 @@ Vue.use(VueRouter);
const page = (path: string) => () => import(`./pages/${path}.vue`).then(m => m.default); const page = (path: string) => () => import(`./pages/${path}.vue`).then(m => m.default);
let indexScrollPos = 0;
export const router = new VueRouter({ export const router = new VueRouter({
mode: 'history', mode: 'history',
routes: [ routes: [
@@ -55,14 +57,19 @@ export const router = new VueRouter({
// なんかHacky // なんかHacky
// 通常の使い方をすると scroll メソッドの behavior を設定できないため、自前で window.scroll するようにする // 通常の使い方をすると scroll メソッドの behavior を設定できないため、自前で window.scroll するようにする
// setTimeout しないと、アニメーション(トランジション)の関係でうまく動かない // setTimeout しないと、アニメーション(トランジション)の関係でうまく動かない
scrollBehavior(to, from, savedPosition) { scrollBehavior(to) {
setTimeout(() => { window._scroll = () => { // さらにHacky
if (savedPosition) { if (to.name === 'index') {
window.scroll({ top: savedPosition.y, behavior: 'instant' }); window.scroll({ top: indexScrollPos, behavior: 'instant' });
} else { } else {
window.scroll({ top: 0, behavior: 'instant' }); window.scroll({ top: 0, behavior: 'instant' });
} }
}, 600); };
return; }
});
router.afterEach((to, from) => {
if (from.name === 'index') {
indexScrollPos = window.scrollY;
} }
}); });

View File

@@ -29,6 +29,7 @@ const defaultDeviceSettings = {
localOnly: false, localOnly: false,
themes: [], themes: [],
theme: 'light', theme: 'light',
animation: true,
}; };
export default (os: MiOS) => new Vuex.Store({ export default (os: MiOS) => new Vuex.Store({

View File

@@ -18,7 +18,7 @@ self.addEventListener('install', ev => {
caches.open(cacheName) caches.open(cacheName)
.then(cache => { .then(cache => {
return cache.addAll([ return cache.addAll([
'/assets/error.jpg' '/'
]); ]);
}) })
.then(() => self.skipWaiting()) .then(() => self.skipWaiting())