リファクタリングなど
This commit is contained in:
parent
1625b37b44
commit
372bfaceda
|
@ -18,61 +18,65 @@ export default function<T extends object>(data: {
|
||||||
default: false
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
id(): string {
|
id(): string {
|
||||||
return this.widget.id;
|
return this.widget.id;
|
||||||
|
},
|
||||||
|
|
||||||
|
props(): T {
|
||||||
|
return this.widget.data;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
props: data.props ? data.props() : {} as T,
|
bakedOldProps: null
|
||||||
bakedOldProps: null,
|
|
||||||
preventSave: false
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
if (this.props) {
|
this.mergeProps();
|
||||||
Object.keys(this.props).forEach(prop => {
|
|
||||||
if (this.widget.data.hasOwnProperty(prop)) {
|
this.$watch('props', () => {
|
||||||
this.props[prop] = this.widget.data[prop];
|
this.mergeProps();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.bakeProps();
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
bakeProps() {
|
||||||
|
this.bakedOldProps = JSON.stringify(this.props);
|
||||||
|
},
|
||||||
|
|
||||||
|
mergeProps() {
|
||||||
|
if (data.props) {
|
||||||
|
const defaultProps = data.props();
|
||||||
|
Object.keys(defaultProps).forEach(prop => {
|
||||||
|
if (!this.props.hasOwnProperty(prop)) {
|
||||||
|
Vue.set(this.props, prop, defaultProps[prop]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
this.bakeProps();
|
save() {
|
||||||
|
if (this.bakedOldProps == JSON.stringify(this.props)) return;
|
||||||
this.$watch('props', newProps => {
|
|
||||||
if (this.preventSave) {
|
|
||||||
this.preventSave = false;
|
|
||||||
this.bakeProps();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this.bakedOldProps == JSON.stringify(newProps)) return;
|
|
||||||
|
|
||||||
this.bakeProps();
|
this.bakeProps();
|
||||||
|
|
||||||
if (this.isMobile) {
|
if (this.isMobile) {
|
||||||
(this as any).api('i/update_mobile_home', {
|
(this as any).api('i/update_mobile_home', {
|
||||||
id: this.id,
|
id: this.id,
|
||||||
data: newProps
|
data: this.props
|
||||||
}).then(() => {
|
|
||||||
(this as any).os.i.clientSettings.mobileHome.find(w => w.id == this.id).data = newProps;
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
(this as any).api('i/update_home', {
|
(this as any).api('i/update_home', {
|
||||||
id: this.id,
|
id: this.id,
|
||||||
data: newProps
|
data: this.props
|
||||||
}).then(() => {
|
|
||||||
(this as any).os.i.clientSettings.home.find(w => w.id == this.id).data = newProps;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, {
|
|
||||||
deep: true
|
|
||||||
});
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
bakeProps() {
|
|
||||||
this.bakedOldProps = JSON.stringify(this.props);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { EventEmitter } from 'eventemitter3';
|
||||||
import * as merge from 'object-assign-deep';
|
import * as merge from 'object-assign-deep';
|
||||||
import * as uuid from 'uuid';
|
import * as uuid from 'uuid';
|
||||||
|
|
||||||
|
import initStore from '../store';
|
||||||
import { hostname, apiUrl, swPublickey, version, lang, googleMapsApiKey } from '../config';
|
import { hostname, apiUrl, swPublickey, version, lang, googleMapsApiKey } from '../config';
|
||||||
import Progress from './scripts/loading';
|
import Progress from './scripts/loading';
|
||||||
import Connection from './scripts/streaming/stream';
|
import Connection from './scripts/streaming/stream';
|
||||||
|
@ -16,16 +17,6 @@ import Err from '../common/views/components/connect-failed.vue';
|
||||||
import { LocalTimelineStreamManager } from './scripts/streaming/local-timeline';
|
import { LocalTimelineStreamManager } from './scripts/streaming/local-timeline';
|
||||||
import { GlobalTimelineStreamManager } from './scripts/streaming/global-timeline';
|
import { GlobalTimelineStreamManager } from './scripts/streaming/global-timeline';
|
||||||
|
|
||||||
const defaultSettings = {
|
|
||||||
fetchOnScroll: true,
|
|
||||||
showMaps: true,
|
|
||||||
showPostFormOnTopOfTl: false,
|
|
||||||
gradientWindowHeader: false,
|
|
||||||
showReplyTarget: true,
|
|
||||||
showMyRenotes: true,
|
|
||||||
showRenotedMyNotes: true
|
|
||||||
};
|
|
||||||
|
|
||||||
//#region api requests
|
//#region api requests
|
||||||
let spinner = null;
|
let spinner = null;
|
||||||
let pending = 0;
|
let pending = 0;
|
||||||
|
@ -117,6 +108,8 @@ export default class MiOS extends EventEmitter {
|
||||||
return localStorage.getItem('enableSounds') == 'true';
|
return localStorage.getItem('enableSounds') == 'true';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public store: ReturnType<typeof initStore>;
|
||||||
|
|
||||||
public apis: API;
|
public apis: API;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -232,6 +225,11 @@ export default class MiOS extends EventEmitter {
|
||||||
console.error.apply(null, args);
|
console.error.apply(null, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bakeMe() {
|
||||||
|
// ローカルストレージにキャッシュ
|
||||||
|
localStorage.setItem('me', JSON.stringify(this.i));
|
||||||
|
}
|
||||||
|
|
||||||
public signout() {
|
public signout() {
|
||||||
localStorage.removeItem('me');
|
localStorage.removeItem('me');
|
||||||
document.cookie = `i=; domain=${hostname}; expires=Thu, 01 Jan 1970 00:00:01 GMT;`;
|
document.cookie = `i=; domain=${hostname}; expires=Thu, 01 Jan 1970 00:00:01 GMT;`;
|
||||||
|
@ -243,6 +241,8 @@ export default class MiOS extends EventEmitter {
|
||||||
* @param callback A function that call when initialized
|
* @param callback A function that call when initialized
|
||||||
*/
|
*/
|
||||||
public async init(callback) {
|
public async init(callback) {
|
||||||
|
this.store = initStore(this);
|
||||||
|
|
||||||
//#region Init stream managers
|
//#region Init stream managers
|
||||||
this.streams.serverStream = new ServerStreamManager(this);
|
this.streams.serverStream = new ServerStreamManager(this);
|
||||||
|
|
||||||
|
@ -307,15 +307,10 @@ export default class MiOS extends EventEmitter {
|
||||||
|
|
||||||
// フェッチが完了したとき
|
// フェッチが完了したとき
|
||||||
const fetched = me => {
|
const fetched = me => {
|
||||||
if (me) {
|
this.i = me;
|
||||||
// デフォルトの設定をマージ
|
|
||||||
me.clientSettings = Object.assign(defaultSettings, me.clientSettings);
|
|
||||||
|
|
||||||
// ローカルストレージにキャッシュ
|
// ローカルストレージにキャッシュ
|
||||||
localStorage.setItem('me', JSON.stringify(me));
|
this.bakeMe();
|
||||||
}
|
|
||||||
|
|
||||||
this.i = me;
|
|
||||||
|
|
||||||
this.emit('signedin');
|
this.emit('signedin');
|
||||||
|
|
||||||
|
@ -333,6 +328,14 @@ export default class MiOS extends EventEmitter {
|
||||||
// Get cached account data
|
// Get cached account data
|
||||||
const cachedMe = JSON.parse(localStorage.getItem('me'));
|
const cachedMe = JSON.parse(localStorage.getItem('me'));
|
||||||
|
|
||||||
|
//#region キャッシュされた設定を復元
|
||||||
|
const cachedSettings = JSON.parse(localStorage.getItem('settings'));
|
||||||
|
|
||||||
|
if (cachedSettings) {
|
||||||
|
this.store.commit('settings/init', cachedSettings);
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
// キャッシュがあったとき
|
// キャッシュがあったとき
|
||||||
if (cachedMe) {
|
if (cachedMe) {
|
||||||
if (cachedMe.token == null) {
|
if (cachedMe.token == null) {
|
||||||
|
@ -346,12 +349,25 @@ export default class MiOS extends EventEmitter {
|
||||||
// 後から新鮮なデータをフェッチ
|
// 後から新鮮なデータをフェッチ
|
||||||
fetchme(cachedMe.token, freshData => {
|
fetchme(cachedMe.token, freshData => {
|
||||||
merge(cachedMe, freshData);
|
merge(cachedMe, freshData);
|
||||||
|
|
||||||
|
this.store.commit('settings/init', freshData.clientSettings);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Get token from cookie
|
// Get token from cookie
|
||||||
const i = (document.cookie.match(/i=(!\w+)/) || [null, null])[1];
|
const i = (document.cookie.match(/i=(!\w+)/) || [null, null])[1];
|
||||||
|
|
||||||
fetchme(i, fetched);
|
fetchme(i, me => {
|
||||||
|
if (me) {
|
||||||
|
Object.entries(me.clientSettings).forEach(([key, value]) => {
|
||||||
|
this.store.commit('settings/set', { key, value });
|
||||||
|
});
|
||||||
|
|
||||||
|
fetched(me);
|
||||||
|
} else {
|
||||||
|
// Finish init
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -456,7 +472,7 @@ export default class MiOS extends EventEmitter {
|
||||||
};
|
};
|
||||||
|
|
||||||
const promise = new Promise((resolve, reject) => {
|
const promise = new Promise((resolve, reject) => {
|
||||||
const viaStream = this.stream.hasConnection &&
|
const viaStream = this.stream && this.stream.hasConnection &&
|
||||||
(localStorage.getItem('apiViaStream') ? localStorage.getItem('apiViaStream') == 'true' : true);
|
(localStorage.getItem('apiViaStream') ? localStorage.getItem('apiViaStream') == 'true' : true);
|
||||||
|
|
||||||
if (viaStream) {
|
if (viaStream) {
|
||||||
|
|
|
@ -25,10 +25,31 @@ export class HomeStream extends Stream {
|
||||||
console.log('I updated:', i);
|
console.log('I updated:', i);
|
||||||
}
|
}
|
||||||
merge(me, i);
|
merge(me, i);
|
||||||
|
|
||||||
|
// キャッシュ更新
|
||||||
|
os.bakeMe();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.on('clientSettingUpdated', x => {
|
||||||
|
os.store.commit('settings/set', {
|
||||||
|
key: x.key,
|
||||||
|
value: x.value
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
this.on('home_updated', x => {
|
||||||
|
if (x.home) {
|
||||||
|
os.store.commit('settings/setHome', x.home);
|
||||||
|
} else {
|
||||||
|
os.store.commit('settings/setHomeWidget', {
|
||||||
|
id: x.id,
|
||||||
|
data: x.data
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// トークンが再生成されたとき
|
// トークンが再生成されたとき
|
||||||
// このままではAPIが利用できないので強制的にサインアウトさせる
|
// このままではMisskeyが利用できないので強制的にサインアウトさせる
|
||||||
this.on('my_token_regenerated', () => {
|
this.on('my_token_regenerated', () => {
|
||||||
alert('%i18n:!common.my-token-regenerated%');
|
alert('%i18n:!common.my-token-regenerated%');
|
||||||
os.signout();
|
os.signout();
|
||||||
|
|
38
src/client/app/common/views/components/avatar.vue
Normal file
38
src/client/app/common/views/components/avatar.vue
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
<template>
|
||||||
|
<router-link class="mk-avatar" :to="user | userPage" :title="user | acct" :target="target" :style="{ borderRadius: clientSettings.circleIcons ? '100%' : null }">
|
||||||
|
<img v-if="disablePreview" :src="`${user.avatarUrl}?thumbnail&size=128`" alt=""/>
|
||||||
|
<img v-else :src="`${user.avatarUrl}?thumbnail&size=128`" alt="" v-user-preview="user.id"/>
|
||||||
|
</router-link>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
export default Vue.extend({
|
||||||
|
props: {
|
||||||
|
user: {
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
target: {
|
||||||
|
required: false,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
disablePreview: {
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
.mk-avatar
|
||||||
|
display block
|
||||||
|
|
||||||
|
> img
|
||||||
|
display inline-block
|
||||||
|
width 100%
|
||||||
|
height 100%
|
||||||
|
margin 0
|
||||||
|
border-radius inherit
|
||||||
|
vertical-align bottom
|
||||||
|
</style>
|
|
@ -3,6 +3,7 @@ import Vue from 'vue';
|
||||||
import signin from './signin.vue';
|
import signin from './signin.vue';
|
||||||
import signup from './signup.vue';
|
import signup from './signup.vue';
|
||||||
import forkit from './forkit.vue';
|
import forkit from './forkit.vue';
|
||||||
|
import avatar from './avatar.vue';
|
||||||
import nav from './nav.vue';
|
import nav from './nav.vue';
|
||||||
import noteHtml from './note-html';
|
import noteHtml from './note-html';
|
||||||
import poll from './poll.vue';
|
import poll from './poll.vue';
|
||||||
|
@ -28,6 +29,7 @@ import welcomeTimeline from './welcome-timeline.vue';
|
||||||
Vue.component('mk-signin', signin);
|
Vue.component('mk-signin', signin);
|
||||||
Vue.component('mk-signup', signup);
|
Vue.component('mk-signup', signup);
|
||||||
Vue.component('mk-forkit', forkit);
|
Vue.component('mk-forkit', forkit);
|
||||||
|
Vue.component('mk-avatar', avatar);
|
||||||
Vue.component('mk-nav', nav);
|
Vue.component('mk-nav', nav);
|
||||||
Vue.component('mk-note-html', noteHtml);
|
Vue.component('mk-note-html', noteHtml);
|
||||||
Vue.component('mk-poll', poll);
|
Vue.component('mk-poll', poll);
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="message" :data-is-me="isMe">
|
<div class="message" :data-is-me="isMe">
|
||||||
<router-link class="avatar-anchor" :to="message.user | userPage" :title="message.user | acct" target="_blank">
|
<mk-avatar class="avatar" :user="message.user" target="_blank"/>
|
||||||
<img class="avatar" :src="`${message.user.avatarUrl}?thumbnail&size=80`" alt=""/>
|
|
||||||
</router-link>
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="balloon" :data-no-text="message.text == null">
|
<div class="balloon" :data-no-text="message.text == null">
|
||||||
<p class="read" v-if="isMe && message.isRead">%i18n:@is-read%</p>
|
<p class="read" v-if="isMe && message.isRead">%i18n:@is-read%</p>
|
||||||
|
@ -67,18 +65,12 @@ export default Vue.extend({
|
||||||
padding 10px 12px 10px 12px
|
padding 10px 12px 10px 12px
|
||||||
background-color transparent
|
background-color transparent
|
||||||
|
|
||||||
> .avatar-anchor
|
> .avatar
|
||||||
display block
|
display block
|
||||||
position absolute
|
position absolute
|
||||||
top 10px
|
top 10px
|
||||||
|
width 54px
|
||||||
> .avatar
|
height 54px
|
||||||
display block
|
|
||||||
min-width 54px
|
|
||||||
min-height 54px
|
|
||||||
max-width 54px
|
|
||||||
max-height 54px
|
|
||||||
margin 0
|
|
||||||
border-radius 8px
|
border-radius 8px
|
||||||
transition all 0.1s ease
|
transition all 0.1s ease
|
||||||
|
|
||||||
|
@ -201,7 +193,7 @@ export default Vue.extend({
|
||||||
margin-left 4px
|
margin-left 4px
|
||||||
|
|
||||||
&:not([data-is-me])
|
&:not([data-is-me])
|
||||||
> .avatar-anchor
|
> .avatar
|
||||||
left 12px
|
left 12px
|
||||||
|
|
||||||
> .content
|
> .content
|
||||||
|
@ -225,7 +217,7 @@ export default Vue.extend({
|
||||||
text-align left
|
text-align left
|
||||||
|
|
||||||
&[data-is-me]
|
&[data-is-me]
|
||||||
> .avatar-anchor
|
> .avatar
|
||||||
right 12px
|
right 12px
|
||||||
|
|
||||||
> .content
|
> .content
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
@click="navigate(user)"
|
@click="navigate(user)"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<img class="avatar" :src="`${user.avatarUrl}?thumbnail&size=32`" alt=""/>
|
<mk-avatar class="avatar" :user="user"/>
|
||||||
<span class="name">{{ user | userName }}</span>
|
<span class="name">{{ user | userName }}</span>
|
||||||
<span class="username">@{{ user | acct }}</span>
|
<span class="username">@{{ user | acct }}</span>
|
||||||
</li>
|
</li>
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
:key="message.id"
|
:key="message.id"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<img class="avatar" :src="`${isMe(message) ? message.recipient.avatarUrl : message.user.avatarUrl}?thumbnail&size=64`" alt=""/>
|
<mk-avatar class="avatar" :user="isMe(message) ? message.recipient : message.user"/>
|
||||||
<header>
|
<header>
|
||||||
<span class="name">{{ isMe(message) ? message.recipient : message.user | userName }}</span>
|
<span class="name">{{ isMe(message) ? message.recipient : message.user | userName }}</span>
|
||||||
<span class="username">@{{ isMe(message) ? message.recipient : message.user | acct }}</span>
|
<span class="username">@{{ isMe(message) ? message.recipient : message.user | acct }}</span>
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="mk-welcome-timeline">
|
<div class="mk-welcome-timeline">
|
||||||
<div v-for="note in notes">
|
<div v-for="note in notes">
|
||||||
<router-link class="avatar-anchor" :to="note.user | userPage" v-user-preview="note.user.id">
|
<mk-avatar class="avatar" :user="note.user" target="_blank"/>
|
||||||
<img class="avatar" :src="`${note.user.avatarUrl}?thumbnail&size=96`" alt="avatar"/>
|
|
||||||
</router-link>
|
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<header>
|
<header>
|
||||||
<router-link class="name" :to="note.user | userPage" v-user-preview="note.user.id">{{ note.user | userName }}</router-link>
|
<router-link class="name" :to="note.user | userPage" v-user-preview="note.user.id">{{ note.user | userName }}</router-link>
|
||||||
|
@ -69,15 +67,12 @@ export default Vue.extend({
|
||||||
display block
|
display block
|
||||||
clear both
|
clear both
|
||||||
|
|
||||||
> .avatar-anchor
|
> .avatar
|
||||||
display block
|
display block
|
||||||
float left
|
float left
|
||||||
position -webkit-sticky
|
position -webkit-sticky
|
||||||
position sticky
|
position sticky
|
||||||
top 16px
|
top 16px
|
||||||
|
|
||||||
> img
|
|
||||||
display block
|
|
||||||
width 42px
|
width 42px
|
||||||
height 42px
|
height 42px
|
||||||
border-radius 6px
|
border-radius 6px
|
||||||
|
|
|
@ -61,6 +61,7 @@ export default define({
|
||||||
} else {
|
} else {
|
||||||
this.props.design++;
|
this.props.design++;
|
||||||
}
|
}
|
||||||
|
this.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -68,6 +68,7 @@ export default define({
|
||||||
} else {
|
} else {
|
||||||
this.props.design++;
|
this.props.design++;
|
||||||
}
|
}
|
||||||
|
this.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -73,6 +73,7 @@ export default define({
|
||||||
} else {
|
} else {
|
||||||
this.props.design++;
|
this.props.design++;
|
||||||
}
|
}
|
||||||
|
this.save();
|
||||||
},
|
},
|
||||||
tick() {
|
tick() {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
|
|
|
@ -59,6 +59,8 @@ export default define({
|
||||||
} else {
|
} else {
|
||||||
this.props.design++;
|
this.props.design++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -40,6 +40,7 @@ export default define({
|
||||||
methods: {
|
methods: {
|
||||||
func() {
|
func() {
|
||||||
this.props.compact = !this.props.compact;
|
this.props.compact = !this.props.compact;
|
||||||
|
this.save();
|
||||||
},
|
},
|
||||||
fetch() {
|
fetch() {
|
||||||
fetch(`https://api.rss2json.com/v1/api.json?rss_url=${this.url}`, {
|
fetch(`https://api.rss2json.com/v1/api.json?rss_url=${this.url}`, {
|
||||||
|
|
|
@ -68,6 +68,7 @@ export default define({
|
||||||
} else {
|
} else {
|
||||||
this.props.view++;
|
this.props.view++;
|
||||||
}
|
}
|
||||||
|
this.save();
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
if (this.props.design == 2) {
|
if (this.props.design == 2) {
|
||||||
|
@ -75,6 +76,7 @@ export default define({
|
||||||
} else {
|
} else {
|
||||||
this.props.design++;
|
this.props.design++;
|
||||||
}
|
}
|
||||||
|
this.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -64,6 +64,7 @@ export default define({
|
||||||
} else {
|
} else {
|
||||||
this.props.size++;
|
this.props.size++;
|
||||||
}
|
}
|
||||||
|
this.save();
|
||||||
|
|
||||||
this.applySize();
|
this.applySize();
|
||||||
},
|
},
|
||||||
|
@ -111,6 +112,7 @@ export default define({
|
||||||
choose() {
|
choose() {
|
||||||
(this as any).apis.chooseDriveFolder().then(folder => {
|
(this as any).apis.chooseDriveFolder().then(folder => {
|
||||||
this.props.folder = folder ? folder.id : null;
|
this.props.folder = folder ? folder.id : null;
|
||||||
|
this.save();
|
||||||
this.fetch();
|
this.fetch();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,7 @@
|
||||||
<p class="title">気になるユーザーをフォロー:</p>
|
<p class="title">気になるユーザーをフォロー:</p>
|
||||||
<div class="users" v-if="!fetching && users.length > 0">
|
<div class="users" v-if="!fetching && users.length > 0">
|
||||||
<div class="user" v-for="user in users" :key="user.id">
|
<div class="user" v-for="user in users" :key="user.id">
|
||||||
<router-link class="avatar-anchor" :to="user | userPage">
|
<mk-avatar class="avatar" :user="user" target="_blank"/>
|
||||||
<img class="avatar" :src="`${user.avatarUrl}?thumbnail&size=42`" alt="" v-user-preview="user.id"/>
|
|
||||||
</router-link>
|
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<router-link class="name" :to="user | userPage" v-user-preview="user.id">{{ user | userName }}</router-link>
|
<router-link class="name" :to="user | userPage" v-user-preview="user.id">{{ user | userName }}</router-link>
|
||||||
<p class="username">@{{ user | acct }}</p>
|
<p class="username">@{{ user | acct }}</p>
|
||||||
|
@ -86,18 +84,13 @@ export default Vue.extend({
|
||||||
display block
|
display block
|
||||||
clear both
|
clear both
|
||||||
|
|
||||||
> .avatar-anchor
|
> .avatar
|
||||||
display block
|
display block
|
||||||
float left
|
float left
|
||||||
margin 0 12px 0 0
|
margin 0 12px 0 0
|
||||||
|
|
||||||
> .avatar
|
|
||||||
display block
|
|
||||||
width 42px
|
width 42px
|
||||||
height 42px
|
height 42px
|
||||||
margin 0
|
|
||||||
border-radius 8px
|
border-radius 8px
|
||||||
vertical-align bottom
|
|
||||||
|
|
||||||
> .body
|
> .body
|
||||||
float left
|
float left
|
||||||
|
|
|
@ -53,7 +53,7 @@
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<a @click="hint">カスタマイズのヒント</a>
|
<a @click="hint">カスタマイズのヒント</a>
|
||||||
<div>
|
<div>
|
||||||
<mk-post-form v-if="os.i.clientSettings.showPostFormOnTopOfTl"/>
|
<mk-post-form v-if="clientSettings.showPostFormOnTopOfTl"/>
|
||||||
<mk-timeline ref="tl" @loaded="onTlLoaded"/>
|
<mk-timeline ref="tl" @loaded="onTlLoaded"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -63,7 +63,7 @@
|
||||||
<component v-for="widget in widgets[place]" :is="`mkw-${widget.name}`" :key="widget.id" :ref="widget.id" :widget="widget" @chosen="warp"/>
|
<component v-for="widget in widgets[place]" :is="`mkw-${widget.name}`" :key="widget.id" :ref="widget.id" :widget="widget" @chosen="warp"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<mk-post-form v-if="os.i.clientSettings.showPostFormOnTopOfTl"/>
|
<mk-post-form v-if="clientSettings.showPostFormOnTopOfTl"/>
|
||||||
<mk-timeline ref="tl" @loaded="onTlLoaded" v-if="mode == 'timeline'"/>
|
<mk-timeline ref="tl" @loaded="onTlLoaded" v-if="mode == 'timeline'"/>
|
||||||
<mk-mentions @loaded="onTlLoaded" v-if="mode == 'mentions'"/>
|
<mk-mentions @loaded="onTlLoaded" v-if="mode == 'mentions'"/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -81,6 +81,7 @@ export default Vue.extend({
|
||||||
components: {
|
components: {
|
||||||
XDraggable
|
XDraggable
|
||||||
},
|
},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
customize: {
|
customize: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
|
@ -91,61 +92,43 @@ export default Vue.extend({
|
||||||
default: 'timeline'
|
default: 'timeline'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
connection: null,
|
connection: null,
|
||||||
connectionId: null,
|
connectionId: null,
|
||||||
widgetAdderSelected: null,
|
widgetAdderSelected: null,
|
||||||
trash: [],
|
trash: []
|
||||||
widgets: {
|
|
||||||
left: [],
|
|
||||||
right: []
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
home: {
|
home(): any[] {
|
||||||
get(): any[] {
|
return this.$store.state.settings.data.home;
|
||||||
//#region 互換性のため
|
|
||||||
(this as any).os.i.clientSettings.home.forEach(w => {
|
|
||||||
if (w.name == 'rss-reader') w.name = 'rss';
|
|
||||||
if (w.name == 'user-recommendation') w.name = 'users';
|
|
||||||
if (w.name == 'recommended-polls') w.name = 'polls';
|
|
||||||
});
|
|
||||||
//#endregion
|
|
||||||
return (this as any).os.i.clientSettings.home;
|
|
||||||
},
|
|
||||||
set(value) {
|
|
||||||
(this as any).os.i.clientSettings.home = value;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
left(): any[] {
|
left(): any[] {
|
||||||
return this.home.filter(w => w.place == 'left');
|
return this.home.filter(w => w.place == 'left');
|
||||||
},
|
},
|
||||||
right(): any[] {
|
right(): any[] {
|
||||||
return this.home.filter(w => w.place == 'right');
|
return this.home.filter(w => w.place == 'right');
|
||||||
|
},
|
||||||
|
widgets(): any {
|
||||||
|
return {
|
||||||
|
left: this.left,
|
||||||
|
right: this.right
|
||||||
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
|
||||||
this.widgets.left = this.left;
|
|
||||||
this.widgets.right = this.right;
|
|
||||||
this.$watch('os.i.clientSettings', i => {
|
|
||||||
this.widgets.left = this.left;
|
|
||||||
this.widgets.right = this.right;
|
|
||||||
}, {
|
|
||||||
deep: true
|
|
||||||
});
|
|
||||||
},
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.connection = (this as any).os.stream.getConnection();
|
this.connection = (this as any).os.stream.getConnection();
|
||||||
this.connectionId = (this as any).os.stream.use();
|
this.connectionId = (this as any).os.stream.use();
|
||||||
|
|
||||||
this.connection.on('home_updated', this.onHomeUpdated);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.connection.off('home_updated', this.onHomeUpdated);
|
|
||||||
(this as any).os.stream.dispose(this.connectionId);
|
(this as any).os.stream.dispose(this.connectionId);
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
hint() {
|
hint() {
|
||||||
(this as any).apis.dialog({
|
(this as any).apis.dialog({
|
||||||
|
@ -159,56 +142,44 @@ export default Vue.extend({
|
||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onTlLoaded() {
|
onTlLoaded() {
|
||||||
this.$emit('loaded');
|
this.$emit('loaded');
|
||||||
},
|
},
|
||||||
onHomeUpdated(data) {
|
|
||||||
if (data.home) {
|
|
||||||
(this as any).os.i.clientSettings.home = data.home;
|
|
||||||
this.widgets.left = data.home.filter(w => w.place == 'left');
|
|
||||||
this.widgets.right = data.home.filter(w => w.place == 'right');
|
|
||||||
} else {
|
|
||||||
const w = (this as any).os.i.clientSettings.home.find(w => w.id == data.id);
|
|
||||||
if (w != null) {
|
|
||||||
w.data = data.data;
|
|
||||||
this.$refs[w.id][0].preventSave = true;
|
|
||||||
this.$refs[w.id][0].props = w.data;
|
|
||||||
this.widgets.left = (this as any).os.i.clientSettings.home.filter(w => w.place == 'left');
|
|
||||||
this.widgets.right = (this as any).os.i.clientSettings.home.filter(w => w.place == 'right');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onWidgetContextmenu(widgetId) {
|
onWidgetContextmenu(widgetId) {
|
||||||
const w = (this.$refs[widgetId] as any)[0];
|
const w = (this.$refs[widgetId] as any)[0];
|
||||||
if (w.func) w.func();
|
if (w.func) w.func();
|
||||||
},
|
},
|
||||||
|
|
||||||
onWidgetSort() {
|
onWidgetSort() {
|
||||||
this.saveHome();
|
this.saveHome();
|
||||||
},
|
},
|
||||||
|
|
||||||
onTrash(evt) {
|
onTrash(evt) {
|
||||||
this.saveHome();
|
this.saveHome();
|
||||||
},
|
},
|
||||||
|
|
||||||
addWidget() {
|
addWidget() {
|
||||||
const widget = {
|
this.$store.dispatch('settings/addHomeWidget', {
|
||||||
name: this.widgetAdderSelected,
|
name: this.widgetAdderSelected,
|
||||||
id: uuid(),
|
id: uuid(),
|
||||||
place: 'left',
|
place: 'left',
|
||||||
data: {}
|
data: {}
|
||||||
};
|
});
|
||||||
|
|
||||||
this.widgets.left.unshift(widget);
|
|
||||||
this.saveHome();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
saveHome() {
|
saveHome() {
|
||||||
const left = this.widgets.left;
|
const left = this.widgets.left;
|
||||||
const right = this.widgets.right;
|
const right = this.widgets.right;
|
||||||
this.home = left.concat(right);
|
this.$store.commit('settings/setHome', left.concat(right));
|
||||||
left.forEach(w => w.place = 'left');
|
left.forEach(w => w.place = 'left');
|
||||||
right.forEach(w => w.place = 'right');
|
right.forEach(w => w.place = 'right');
|
||||||
(this as any).api('i/update_home', {
|
(this as any).api('i/update_home', {
|
||||||
home: this.home
|
home: this.home
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
warp(date) {
|
warp(date) {
|
||||||
(this.$refs.tl as any).warp(date);
|
(this.$refs.tl as any).warp(date);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="sub" :title="title">
|
<div class="sub" :title="title">
|
||||||
<router-link class="avatar-anchor" :to="note.user | userPage">
|
<mk-avatar class="avatar" :user="note.user"/>
|
||||||
<img class="avatar" :src="`${note.user.avatarUrl}?thumbnail&size=64`" alt="avatar" v-user-preview="note.userId"/>
|
|
||||||
</router-link>
|
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<header>
|
<header>
|
||||||
<div class="left">
|
<div class="left">
|
||||||
|
@ -57,18 +55,13 @@ root(isDark)
|
||||||
> .main > footer > button
|
> .main > footer > button
|
||||||
color #888
|
color #888
|
||||||
|
|
||||||
> .avatar-anchor
|
> .avatar
|
||||||
display block
|
display block
|
||||||
float left
|
float left
|
||||||
margin 0 16px 0 0
|
margin 0 16px 0 0
|
||||||
|
|
||||||
> .avatar
|
|
||||||
display block
|
|
||||||
width 44px
|
width 44px
|
||||||
height 44px
|
height 44px
|
||||||
margin 0
|
|
||||||
border-radius 4px
|
border-radius 4px
|
||||||
vertical-align bottom
|
|
||||||
|
|
||||||
> .main
|
> .main
|
||||||
float left
|
float left
|
||||||
|
|
|
@ -18,18 +18,14 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="renote" v-if="isRenote">
|
<div class="renote" v-if="isRenote">
|
||||||
<p>
|
<p>
|
||||||
<router-link class="avatar-anchor" :to="note.user | userPage" v-user-preview="note.userId">
|
<mk-avatar class="avatar" :user="note.user"/>
|
||||||
<img class="avatar" :src="`${note.user.avatarUrl}?thumbnail&size=32`" alt="avatar"/>
|
|
||||||
</router-link>
|
|
||||||
%fa:retweet%
|
%fa:retweet%
|
||||||
<router-link class="name" :href="note.user | userPage">{{ note.user | userName }}</router-link>
|
<router-link class="name" :href="note.user | userPage">{{ note.user | userName }}</router-link>
|
||||||
がRenote
|
がRenote
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<article>
|
<article>
|
||||||
<router-link class="avatar-anchor" :to="p.user | userPage">
|
<mk-avatar class="avatar" :user="p.user"/>
|
||||||
<img class="avatar" :src="`${p.user.avatarUrl}?thumbnail&size=64`" alt="avatar" v-user-preview="p.user.id"/>
|
|
||||||
</router-link>
|
|
||||||
<header>
|
<header>
|
||||||
<router-link class="name" :to="p.user | userPage" v-user-preview="p.user.id">{{ p.user | userName }}</router-link>
|
<router-link class="name" :to="p.user | userPage" v-user-preview="p.user.id">{{ p.user | userName }}</router-link>
|
||||||
<span class="username">@{{ p.user | acct }}</span>
|
<span class="username">@{{ p.user | acct }}</span>
|
||||||
|
@ -159,7 +155,7 @@ export default Vue.extend({
|
||||||
|
|
||||||
// Draw map
|
// Draw map
|
||||||
if (this.p.geo) {
|
if (this.p.geo) {
|
||||||
const shouldShowMap = (this as any).os.isSignedIn ? (this as any).os.i.clientSettings.showMaps : true;
|
const shouldShowMap = (this as any).os.isSignedIn ? (this as any).clientSettings.showMaps : true;
|
||||||
if (shouldShowMap) {
|
if (shouldShowMap) {
|
||||||
(this as any).os.getGoogleMaps().then(maps => {
|
(this as any).os.getGoogleMaps().then(maps => {
|
||||||
const uluru = new maps.LatLng(this.p.geo.coordinates[1], this.p.geo.coordinates[0]);
|
const uluru = new maps.LatLng(this.p.geo.coordinates[1], this.p.geo.coordinates[0]);
|
||||||
|
@ -262,15 +258,10 @@ root(isDark)
|
||||||
margin 0
|
margin 0
|
||||||
padding 16px 32px
|
padding 16px 32px
|
||||||
|
|
||||||
.avatar-anchor
|
|
||||||
display inline-block
|
|
||||||
|
|
||||||
.avatar
|
.avatar
|
||||||
vertical-align bottom
|
display inline-block
|
||||||
min-width 28px
|
width 28px
|
||||||
min-height 28px
|
height 28px
|
||||||
max-width 28px
|
|
||||||
max-height 28px
|
|
||||||
margin 0 8px 0 0
|
margin 0 8px 0 0
|
||||||
border-radius 6px
|
border-radius 6px
|
||||||
|
|
||||||
|
@ -298,18 +289,10 @@ root(isDark)
|
||||||
> footer > button
|
> footer > button
|
||||||
color isDark ? #707b97 : #888
|
color isDark ? #707b97 : #888
|
||||||
|
|
||||||
> .avatar-anchor
|
|
||||||
display block
|
|
||||||
width 60px
|
|
||||||
height 60px
|
|
||||||
|
|
||||||
> .avatar
|
> .avatar
|
||||||
display block
|
|
||||||
width 60px
|
width 60px
|
||||||
height 60px
|
height 60px
|
||||||
margin 0
|
|
||||||
border-radius 8px
|
border-radius 8px
|
||||||
vertical-align bottom
|
|
||||||
|
|
||||||
> header
|
> header
|
||||||
position absolute
|
position absolute
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="mk-note-preview" :title="title">
|
<div class="mk-note-preview" :title="title">
|
||||||
<router-link class="avatar-anchor" :to="note.user | userPage">
|
<mk-avatar class="avatar" :user="note.user"/>
|
||||||
<img class="avatar" :src="`${note.user.avatarUrl}?thumbnail&size=64`" alt="avatar" v-user-preview="note.userId"/>
|
|
||||||
</router-link>
|
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<header>
|
<header>
|
||||||
<router-link class="name" :to="note.user | userPage" v-user-preview="note.userId">{{ note.user | userName }}</router-link>
|
<router-link class="name" :to="note.user | userPage" v-user-preview="note.userId">{{ note.user | userName }}</router-link>
|
||||||
|
@ -41,18 +39,13 @@ root(isDark)
|
||||||
display block
|
display block
|
||||||
clear both
|
clear both
|
||||||
|
|
||||||
> .avatar-anchor
|
> .avatar
|
||||||
display block
|
display block
|
||||||
float left
|
float left
|
||||||
margin 0 16px 0 0
|
margin 0 16px 0 0
|
||||||
|
|
||||||
> .avatar
|
|
||||||
display block
|
|
||||||
width 52px
|
width 52px
|
||||||
height 52px
|
height 52px
|
||||||
margin 0
|
|
||||||
border-radius 8px
|
border-radius 8px
|
||||||
vertical-align bottom
|
|
||||||
|
|
||||||
> .main
|
> .main
|
||||||
float left
|
float left
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="sub" :title="title">
|
<div class="sub" :title="title">
|
||||||
<router-link class="avatar-anchor" :to="note.user | userPage">
|
<mk-avatar class="avatar" :user="note.user"/>
|
||||||
<img class="avatar" :src="`${note.user.avatarUrl}?thumbnail&size=64`" alt="avatar" v-user-preview="note.userId"/>
|
|
||||||
</router-link>
|
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<header>
|
<header>
|
||||||
<router-link class="name" :to="note.user | userPage" v-user-preview="note.userId">{{ note.user | userName }}</router-link>
|
<router-link class="name" :to="note.user | userPage" v-user-preview="note.userId">{{ note.user | userName }}</router-link>
|
||||||
|
@ -53,18 +51,13 @@ root(isDark)
|
||||||
display block
|
display block
|
||||||
clear both
|
clear both
|
||||||
|
|
||||||
> .avatar-anchor
|
> .avatar
|
||||||
display block
|
display block
|
||||||
float left
|
float left
|
||||||
margin 0 14px 0 0
|
margin 0 14px 0 0
|
||||||
|
|
||||||
> .avatar
|
|
||||||
display block
|
|
||||||
width 52px
|
width 52px
|
||||||
height 52px
|
height 52px
|
||||||
margin 0
|
|
||||||
border-radius 8px
|
border-radius 8px
|
||||||
vertical-align bottom
|
|
||||||
|
|
||||||
> .main
|
> .main
|
||||||
float left
|
float left
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="note" tabindex="-1" :title="title" @keydown="onKeydown">
|
<div class="note" tabindex="-1" :title="title" @keydown="onKeydown">
|
||||||
<div class="reply-to" v-if="p.reply && (!os.isSignedIn || os.i.clientSettings.showReplyTarget)">
|
<div class="reply-to" v-if="p.reply && (!os.isSignedIn || clientSettings.showReplyTarget)">
|
||||||
<x-sub :note="p.reply"/>
|
<x-sub :note="p.reply"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="renote" v-if="isRenote">
|
<div class="renote" v-if="isRenote">
|
||||||
<router-link class="avatar-anchor" :to="note.user | userPage" v-user-preview="note.userId">
|
<mk-avatar class="avatar" :user="note.user"/>
|
||||||
<img class="avatar" :src="`${note.user.avatarUrl}?thumbnail&size=32`" alt="avatar"/>
|
|
||||||
</router-link>
|
|
||||||
%fa:retweet%
|
%fa:retweet%
|
||||||
<span>{{ '%i18n:!@reposted-by%'.substr(0, '%i18n:!@reposted-by%'.indexOf('{')) }}</span>
|
<span>{{ '%i18n:!@reposted-by%'.substr(0, '%i18n:!@reposted-by%'.indexOf('{')) }}</span>
|
||||||
<a class="name" :href="note.user | userPage" v-user-preview="note.userId">{{ note.user | userName }}</a>
|
<a class="name" :href="note.user | userPage" v-user-preview="note.userId">{{ note.user | userName }}</a>
|
||||||
|
@ -14,9 +12,7 @@
|
||||||
<mk-time :time="note.createdAt"/>
|
<mk-time :time="note.createdAt"/>
|
||||||
</div>
|
</div>
|
||||||
<article>
|
<article>
|
||||||
<router-link class="avatar-anchor" :to="p.user | userPage">
|
<mk-avatar class="avatar" :user="p.user"/>
|
||||||
<img class="avatar" :src="`${p.user.avatarUrl}?thumbnail&size=64`" alt="avatar" v-user-preview="p.user.id"/>
|
|
||||||
</router-link>
|
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<header>
|
<header>
|
||||||
<router-link class="name" :to="p.user | userPage" v-user-preview="p.user.id">{{ p.user | userName }}</router-link>
|
<router-link class="name" :to="p.user | userPage" v-user-preview="p.user.id">{{ p.user | userName }}</router-link>
|
||||||
|
@ -182,7 +178,7 @@ export default Vue.extend({
|
||||||
|
|
||||||
// Draw map
|
// Draw map
|
||||||
if (this.p.geo) {
|
if (this.p.geo) {
|
||||||
const shouldShowMap = (this as any).os.isSignedIn ? (this as any).os.i.clientSettings.showMaps : true;
|
const shouldShowMap = (this as any).os.isSignedIn ? (this as any).clientSettings.showMaps : true;
|
||||||
if (shouldShowMap) {
|
if (shouldShowMap) {
|
||||||
(this as any).os.getGoogleMaps().then(maps => {
|
(this as any).os.getGoogleMaps().then(maps => {
|
||||||
const uluru = new maps.LatLng(this.p.geo.coordinates[1], this.p.geo.coordinates[0]);
|
const uluru = new maps.LatLng(this.p.geo.coordinates[1], this.p.geo.coordinates[0]);
|
||||||
|
@ -343,11 +339,8 @@ root(isDark)
|
||||||
color #9dbb00
|
color #9dbb00
|
||||||
background isDark ? linear-gradient(to bottom, #314027 0%, #282c37 100%) : linear-gradient(to bottom, #edfde2 0%, #fff 100%)
|
background isDark ? linear-gradient(to bottom, #314027 0%, #282c37 100%) : linear-gradient(to bottom, #edfde2 0%, #fff 100%)
|
||||||
|
|
||||||
.avatar-anchor
|
|
||||||
display inline-block
|
|
||||||
|
|
||||||
.avatar
|
.avatar
|
||||||
vertical-align bottom
|
display inline-block
|
||||||
width 28px
|
width 28px
|
||||||
height 28px
|
height 28px
|
||||||
margin 0 8px 0 0
|
margin 0 8px 0 0
|
||||||
|
@ -390,22 +383,17 @@ root(isDark)
|
||||||
> .main > footer > button
|
> .main > footer > button
|
||||||
color isDark ? #707b97 : #888
|
color isDark ? #707b97 : #888
|
||||||
|
|
||||||
> .avatar-anchor
|
> .avatar
|
||||||
display block
|
display block
|
||||||
float left
|
float left
|
||||||
margin 0 16px 10px 0
|
margin 0 16px 10px 0
|
||||||
|
width 58px
|
||||||
|
height 58px
|
||||||
|
border-radius 8px
|
||||||
//position -webkit-sticky
|
//position -webkit-sticky
|
||||||
//position sticky
|
//position sticky
|
||||||
//top 74px
|
//top 74px
|
||||||
|
|
||||||
> .avatar
|
|
||||||
display block
|
|
||||||
width 58px
|
|
||||||
height 58px
|
|
||||||
margin 0
|
|
||||||
border-radius 8px
|
|
||||||
vertical-align bottom
|
|
||||||
|
|
||||||
> .main
|
> .main
|
||||||
float left
|
float left
|
||||||
width calc(100% - 74px)
|
width calc(100% - 74px)
|
||||||
|
|
|
@ -121,13 +121,13 @@ export default Vue.extend({
|
||||||
const isMyNote = note.userId == (this as any).os.i.id;
|
const isMyNote = note.userId == (this as any).os.i.id;
|
||||||
const isPureRenote = note.renoteId != null && note.text == null && note.mediaIds.length == 0 && note.poll == null;
|
const isPureRenote = note.renoteId != null && note.text == null && note.mediaIds.length == 0 && note.poll == null;
|
||||||
|
|
||||||
if ((this as any).os.i.clientSettings.showMyRenotes === false) {
|
if ((this as any).clientSettings.showMyRenotes === false) {
|
||||||
if (isMyNote && isPureRenote) {
|
if (isMyNote && isPureRenote) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((this as any).os.i.clientSettings.showRenotedMyNotes === false) {
|
if ((this as any).clientSettings.showRenotedMyNotes === false) {
|
||||||
if (isPureRenote && (note.renote.userId == (this as any).os.i.id)) {
|
if (isPureRenote && (note.renote.userId == (this as any).os.i.id)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -199,7 +199,7 @@ export default Vue.extend({
|
||||||
this.clearNotification();
|
this.clearNotification();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((this as any).os.i.clientSettings.fetchOnScroll !== false) {
|
if ((this as any).clientSettings.fetchOnScroll !== false) {
|
||||||
const current = window.scrollY + window.innerHeight;
|
const current = window.scrollY + window.innerHeight;
|
||||||
if (current > document.body.offsetHeight - 8) this.loadMore();
|
if (current > document.body.offsetHeight - 8) this.loadMore();
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,7 @@
|
||||||
<div class="notification" :class="notification.type" :key="notification.id">
|
<div class="notification" :class="notification.type" :key="notification.id">
|
||||||
<mk-time :time="notification.createdAt"/>
|
<mk-time :time="notification.createdAt"/>
|
||||||
<template v-if="notification.type == 'reaction'">
|
<template v-if="notification.type == 'reaction'">
|
||||||
<router-link class="avatar-anchor" :to="notification.user | userPage" v-user-preview="notification.user.id">
|
<mk-avatar class="avatar" :user="notification.user"/>
|
||||||
<img class="avatar" :src="`${notification.user.avatarUrl}?thumbnail&size=48`" alt="avatar"/>
|
|
||||||
</router-link>
|
|
||||||
<div class="text">
|
<div class="text">
|
||||||
<p>
|
<p>
|
||||||
<mk-reaction-icon :reaction="notification.reaction"/>
|
<mk-reaction-icon :reaction="notification.reaction"/>
|
||||||
|
@ -20,9 +18,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="notification.type == 'renote'">
|
<template v-if="notification.type == 'renote'">
|
||||||
<router-link class="avatar-anchor" :to="notification.note.user | userPage" v-user-preview="notification.note.userId">
|
<mk-avatar class="avatar" :user="notification.note.user"/>
|
||||||
<img class="avatar" :src="`${notification.note.user.avatarUrl}?thumbnail&size=48`" alt="avatar"/>
|
|
||||||
</router-link>
|
|
||||||
<div class="text">
|
<div class="text">
|
||||||
<p>%fa:retweet%
|
<p>%fa:retweet%
|
||||||
<router-link :to="notification.note.user | userPage" v-user-preview="notification.note.userId">{{ notification.note.user | userName }}</router-link>
|
<router-link :to="notification.note.user | userPage" v-user-preview="notification.note.userId">{{ notification.note.user | userName }}</router-link>
|
||||||
|
@ -33,9 +29,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="notification.type == 'quote'">
|
<template v-if="notification.type == 'quote'">
|
||||||
<router-link class="avatar-anchor" :to="notification.note.user | userPage" v-user-preview="notification.note.userId">
|
<mk-avatar class="avatar" :user="notification.note.user"/>
|
||||||
<img class="avatar" :src="`${notification.note.user.avatarUrl}?thumbnail&size=48`" alt="avatar"/>
|
|
||||||
</router-link>
|
|
||||||
<div class="text">
|
<div class="text">
|
||||||
<p>%fa:quote-left%
|
<p>%fa:quote-left%
|
||||||
<router-link :to="notification.note.user | userPage" v-user-preview="notification.note.userId">{{ notification.note.user | userName }}</router-link>
|
<router-link :to="notification.note.user | userPage" v-user-preview="notification.note.userId">{{ notification.note.user | userName }}</router-link>
|
||||||
|
@ -44,9 +38,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="notification.type == 'follow'">
|
<template v-if="notification.type == 'follow'">
|
||||||
<router-link class="avatar-anchor" :to="notification.user | userPage" v-user-preview="notification.user.id">
|
<mk-avatar class="avatar" :user="notification.user"/>
|
||||||
<img class="avatar" :src="`${notification.user.avatarUrl}?thumbnail&size=48`" alt="avatar"/>
|
|
||||||
</router-link>
|
|
||||||
<div class="text">
|
<div class="text">
|
||||||
<p>%fa:user-plus%
|
<p>%fa:user-plus%
|
||||||
<router-link :to="notification.user | userPage" v-user-preview="notification.user.id">{{ notification.user | userName }}</router-link>
|
<router-link :to="notification.user | userPage" v-user-preview="notification.user.id">{{ notification.user | userName }}</router-link>
|
||||||
|
@ -54,9 +46,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="notification.type == 'reply'">
|
<template v-if="notification.type == 'reply'">
|
||||||
<router-link class="avatar-anchor" :to="notification.note.user | userPage" v-user-preview="notification.note.userId">
|
<mk-avatar class="avatar" :user="notification.note.user"/>
|
||||||
<img class="avatar" :src="`${notification.note.user.avatarUrl}?thumbnail&size=48`" alt="avatar"/>
|
|
||||||
</router-link>
|
|
||||||
<div class="text">
|
<div class="text">
|
||||||
<p>%fa:reply%
|
<p>%fa:reply%
|
||||||
<router-link :to="notification.note.user | userPage" v-user-preview="notification.note.userId">{{ notification.note.user | userName }}</router-link>
|
<router-link :to="notification.note.user | userPage" v-user-preview="notification.note.userId">{{ notification.note.user | userName }}</router-link>
|
||||||
|
@ -65,9 +55,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="notification.type == 'mention'">
|
<template v-if="notification.type == 'mention'">
|
||||||
<router-link class="avatar-anchor" :to="notification.note.user | userPage" v-user-preview="notification.note.userId">
|
<mk-avatar class="avatar" :user="notification.note.user"/>
|
||||||
<img class="avatar" :src="`${notification.note.user.avatarUrl}?thumbnail&size=48`" alt="avatar"/>
|
|
||||||
</router-link>
|
|
||||||
<div class="text">
|
<div class="text">
|
||||||
<p>%fa:at%
|
<p>%fa:at%
|
||||||
<router-link :to="notification.note.user | userPage" v-user-preview="notification.note.userId">{{ notification.note.user | userName }}</router-link>
|
<router-link :to="notification.note.user | userPage" v-user-preview="notification.note.userId">{{ notification.note.user | userName }}</router-link>
|
||||||
|
@ -76,9 +64,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="notification.type == 'poll_vote'">
|
<template v-if="notification.type == 'poll_vote'">
|
||||||
<router-link class="avatar-anchor" :to="notification.user | userPage" v-user-preview="notification.user.id">
|
<mk-avatar class="avatar" :user="notification.user"/>
|
||||||
<img class="avatar" :src="`${notification.user.avatarUrl}?thumbnail&size=48`" alt="avatar"/>
|
|
||||||
</router-link>
|
|
||||||
<div class="text">
|
<div class="text">
|
||||||
<p>%fa:chart-pie%<a :href="notification.user | userPage" v-user-preview="notification.user.id">{{ notification.user | userName }}</a></p>
|
<p>%fa:chart-pie%<a :href="notification.user | userPage" v-user-preview="notification.user.id">{{ notification.user | userName }}</a></p>
|
||||||
<router-link class="note-ref" :to="notification.note | notePage">
|
<router-link class="note-ref" :to="notification.note | notePage">
|
||||||
|
@ -223,19 +209,14 @@ root(isDark)
|
||||||
display block
|
display block
|
||||||
clear both
|
clear both
|
||||||
|
|
||||||
> .avatar-anchor
|
> .avatar
|
||||||
display block
|
display block
|
||||||
float left
|
float left
|
||||||
position -webkit-sticky
|
position -webkit-sticky
|
||||||
position sticky
|
position sticky
|
||||||
top 16px
|
top 16px
|
||||||
|
width 36px
|
||||||
> img
|
height 36px
|
||||||
display block
|
|
||||||
min-width 36px
|
|
||||||
min-height 36px
|
|
||||||
max-width 36px
|
|
||||||
max-height 36px
|
|
||||||
border-radius 6px
|
border-radius 6px
|
||||||
|
|
||||||
> .text
|
> .text
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
<section class="web" v-show="page == 'web'">
|
<section class="web" v-show="page == 'web'">
|
||||||
<h1>動作</h1>
|
<h1>動作</h1>
|
||||||
<mk-switch v-model="os.i.clientSettings.fetchOnScroll" @change="onChangeFetchOnScroll" text="スクロールで自動読み込み">
|
<mk-switch v-model="clientSettings.fetchOnScroll" @change="onChangeFetchOnScroll" text="スクロールで自動読み込み">
|
||||||
<span>ページを下までスクロールしたときに自動で追加のコンテンツを読み込みます。</span>
|
<span>ページを下までスクロールしたときに自動で追加のコンテンツを読み込みます。</span>
|
||||||
</mk-switch>
|
</mk-switch>
|
||||||
<mk-switch v-model="autoPopout" text="ウィンドウの自動ポップアウト">
|
<mk-switch v-model="autoPopout" text="ウィンドウの自動ポップアウト">
|
||||||
|
@ -41,13 +41,14 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="div">
|
<div class="div">
|
||||||
<mk-switch v-model="darkmode" text="ダークモード"/>
|
<mk-switch v-model="darkmode" text="ダークモード"/>
|
||||||
<mk-switch v-model="os.i.clientSettings.gradientWindowHeader" @change="onChangeGradientWindowHeader" text="ウィンドウのタイトルバーにグラデーションを使用"/>
|
<mk-switch v-model="clientSettings.circleIcons" @change="onChangeCircleIcons" text="丸いアイコンを使用"/>
|
||||||
|
<mk-switch v-model="clientSettings.gradientWindowHeader" @change="onChangeGradientWindowHeader" text="ウィンドウのタイトルバーにグラデーションを使用"/>
|
||||||
</div>
|
</div>
|
||||||
<mk-switch v-model="os.i.clientSettings.showPostFormOnTopOfTl" @change="onChangeShowPostFormOnTopOfTl" text="タイムライン上部に投稿フォームを表示する"/>
|
<mk-switch v-model="clientSettings.showPostFormOnTopOfTl" @change="onChangeShowPostFormOnTopOfTl" text="タイムライン上部に投稿フォームを表示する"/>
|
||||||
<mk-switch v-model="os.i.clientSettings.showReplyTarget" @change="onChangeShowReplyTarget" text="リプライ先を表示する"/>
|
<mk-switch v-model="clientSettings.showReplyTarget" @change="onChangeShowReplyTarget" text="リプライ先を表示する"/>
|
||||||
<mk-switch v-model="os.i.clientSettings.showMyRenotes" @change="onChangeShowMyRenotes" text="自分の行ったRenoteをタイムラインに表示する"/>
|
<mk-switch v-model="clientSettings.showMyRenotes" @change="onChangeShowMyRenotes" text="自分の行ったRenoteをタイムラインに表示する"/>
|
||||||
<mk-switch v-model="os.i.clientSettings.showRenotedMyNotes" @change="onChangeShowRenotedMyNotes" text="Renoteされた自分の投稿をタイムラインに表示する"/>
|
<mk-switch v-model="clientSettings.showRenotedMyNotes" @change="onChangeShowRenotedMyNotes" text="Renoteされた自分の投稿をタイムラインに表示する"/>
|
||||||
<mk-switch v-model="os.i.clientSettings.showMaps" @change="onChangeShowMaps" text="マップの自動展開">
|
<mk-switch v-model="clientSettings.showMaps" @change="onChangeShowMaps" text="マップの自動展開">
|
||||||
<span>位置情報が添付された投稿のマップを自動的に展開します。</span>
|
<span>位置情報が添付された投稿のマップを自動的に展開します。</span>
|
||||||
</mk-switch>
|
</mk-switch>
|
||||||
</section>
|
</section>
|
||||||
|
@ -69,7 +70,7 @@
|
||||||
|
|
||||||
<section class="web" v-show="page == 'web'">
|
<section class="web" v-show="page == 'web'">
|
||||||
<h1>モバイル</h1>
|
<h1>モバイル</h1>
|
||||||
<mk-switch v-model="os.i.clientSettings.disableViaMobile" @change="onChangeDisableViaMobile" text="「モバイルからの投稿」フラグを付けない"/>
|
<mk-switch v-model="clientSettings.disableViaMobile" @change="onChangeDisableViaMobile" text="「モバイルからの投稿」フラグを付けない"/>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="web" v-show="page == 'web'">
|
<section class="web" v-show="page == 'web'">
|
||||||
|
@ -297,8 +298,8 @@ export default Vue.extend({
|
||||||
this.$emit('done');
|
this.$emit('done');
|
||||||
},
|
},
|
||||||
onChangeFetchOnScroll(v) {
|
onChangeFetchOnScroll(v) {
|
||||||
(this as any).api('i/update_client_setting', {
|
this.$store.dispatch('settings/set', {
|
||||||
name: 'fetchOnScroll',
|
key: 'fetchOnScroll',
|
||||||
value: v
|
value: v
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -308,50 +309,56 @@ export default Vue.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onChangeDark(v) {
|
onChangeDark(v) {
|
||||||
(this as any).api('i/update_client_setting', {
|
this.$store.dispatch('settings/set', {
|
||||||
name: 'dark',
|
key: 'dark',
|
||||||
value: v
|
value: v
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onChangeShowPostFormOnTopOfTl(v) {
|
onChangeShowPostFormOnTopOfTl(v) {
|
||||||
(this as any).api('i/update_client_setting', {
|
this.$store.dispatch('settings/set', {
|
||||||
name: 'showPostFormOnTopOfTl',
|
key: 'showPostFormOnTopOfTl',
|
||||||
value: v
|
value: v
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onChangeShowReplyTarget(v) {
|
onChangeShowReplyTarget(v) {
|
||||||
(this as any).api('i/update_client_setting', {
|
this.$store.dispatch('settings/set', {
|
||||||
name: 'showReplyTarget',
|
key: 'showReplyTarget',
|
||||||
value: v
|
value: v
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onChangeShowMyRenotes(v) {
|
onChangeShowMyRenotes(v) {
|
||||||
(this as any).api('i/update_client_setting', {
|
this.$store.dispatch('settings/set', {
|
||||||
name: 'showMyRenotes',
|
key: 'showMyRenotes',
|
||||||
value: v
|
value: v
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onChangeShowRenotedMyNotes(v) {
|
onChangeShowRenotedMyNotes(v) {
|
||||||
(this as any).api('i/update_client_setting', {
|
this.$store.dispatch('settings/set', {
|
||||||
name: 'showRenotedMyNotes',
|
key: 'showRenotedMyNotes',
|
||||||
value: v
|
value: v
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onChangeShowMaps(v) {
|
onChangeShowMaps(v) {
|
||||||
(this as any).api('i/update_client_setting', {
|
this.$store.dispatch('settings/set', {
|
||||||
name: 'showMaps',
|
key: 'showMaps',
|
||||||
|
value: v
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onChangeCircleIcons(v) {
|
||||||
|
this.$store.dispatch('settings/set', {
|
||||||
|
key: 'circleIcons',
|
||||||
value: v
|
value: v
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onChangeGradientWindowHeader(v) {
|
onChangeGradientWindowHeader(v) {
|
||||||
(this as any).api('i/update_client_setting', {
|
this.$store.dispatch('settings/set', {
|
||||||
name: 'gradientWindowHeader',
|
key: 'gradientWindowHeader',
|
||||||
value: v
|
value: v
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onChangeDisableViaMobile(v) {
|
onChangeDisableViaMobile(v) {
|
||||||
(this as any).api('i/update_client_setting', {
|
this.$store.dispatch('settings/set', {
|
||||||
name: 'disableViaMobile',
|
key: 'disableViaMobile',
|
||||||
value: v
|
value: v
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -101,8 +101,8 @@ export default Vue.extend({
|
||||||
(this as any).api(this.endpoint, {
|
(this as any).api(this.endpoint, {
|
||||||
limit: fetchLimit + 1,
|
limit: fetchLimit + 1,
|
||||||
untilDate: this.date ? this.date.getTime() : undefined,
|
untilDate: this.date ? this.date.getTime() : undefined,
|
||||||
includeMyRenotes: (this as any).os.i.clientSettings.showMyRenotes,
|
includeMyRenotes: (this as any).clientSettings.showMyRenotes,
|
||||||
includeRenotedMyNotes: (this as any).os.i.clientSettings.showRenotedMyNotes
|
includeRenotedMyNotes: (this as any).clientSettings.showRenotedMyNotes
|
||||||
}).then(notes => {
|
}).then(notes => {
|
||||||
if (notes.length == fetchLimit + 1) {
|
if (notes.length == fetchLimit + 1) {
|
||||||
notes.pop();
|
notes.pop();
|
||||||
|
@ -123,8 +123,8 @@ export default Vue.extend({
|
||||||
(this as any).api(this.endpoint, {
|
(this as any).api(this.endpoint, {
|
||||||
limit: fetchLimit + 1,
|
limit: fetchLimit + 1,
|
||||||
untilId: (this.$refs.timeline as any).tail().id,
|
untilId: (this.$refs.timeline as any).tail().id,
|
||||||
includeMyRenotes: (this as any).os.i.clientSettings.showMyRenotes,
|
includeMyRenotes: (this as any).clientSettings.showMyRenotes,
|
||||||
includeRenotedMyNotes: (this as any).os.i.clientSettings.showRenotedMyNotes
|
includeRenotedMyNotes: (this as any).clientSettings.showRenotedMyNotes
|
||||||
}).then(notes => {
|
}).then(notes => {
|
||||||
if (notes.length == fetchLimit + 1) {
|
if (notes.length == fetchLimit + 1) {
|
||||||
notes.pop();
|
notes.pop();
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<div class="account">
|
<div class="account">
|
||||||
<button class="header" :data-active="isOpen" @click="toggle">
|
<button class="header" :data-active="isOpen" @click="toggle">
|
||||||
<span class="username">{{ os.i.username }}<template v-if="!isOpen">%fa:angle-down%</template><template v-if="isOpen">%fa:angle-up%</template></span>
|
<span class="username">{{ os.i.username }}<template v-if="!isOpen">%fa:angle-down%</template><template v-if="isOpen">%fa:angle-up%</template></span>
|
||||||
<img class="avatar" :src="`${ os.i.avatarUrl }?thumbnail&size=64`" alt="avatar"/>
|
<mk-avatar class="avatar" :user="os.i"/>
|
||||||
</button>
|
</button>
|
||||||
<transition name="zoom-in-top">
|
<transition name="zoom-in-top">
|
||||||
<div class="menu" v-if="isOpen">
|
<div class="menu" v-if="isOpen">
|
||||||
|
|
|
@ -46,8 +46,8 @@ export default Vue.extend({
|
||||||
(this as any).api('notes/user-list-timeline', {
|
(this as any).api('notes/user-list-timeline', {
|
||||||
listId: this.list.id,
|
listId: this.list.id,
|
||||||
limit: fetchLimit + 1,
|
limit: fetchLimit + 1,
|
||||||
includeMyRenotes: (this as any).os.i.clientSettings.showMyRenotes,
|
includeMyRenotes: (this as any).clientSettings.showMyRenotes,
|
||||||
includeRenotedMyNotes: (this as any).os.i.clientSettings.showRenotedMyNotes
|
includeRenotedMyNotes: (this as any).clientSettings.showRenotedMyNotes
|
||||||
}).then(notes => {
|
}).then(notes => {
|
||||||
if (notes.length == fetchLimit + 1) {
|
if (notes.length == fetchLimit + 1) {
|
||||||
notes.pop();
|
notes.pop();
|
||||||
|
@ -66,8 +66,8 @@ export default Vue.extend({
|
||||||
listId: this.list.id,
|
listId: this.list.id,
|
||||||
limit: fetchLimit + 1,
|
limit: fetchLimit + 1,
|
||||||
untilId: (this.$refs.timeline as any).tail().id,
|
untilId: (this.$refs.timeline as any).tail().id,
|
||||||
includeMyRenotes: (this as any).os.i.clientSettings.showMyRenotes,
|
includeMyRenotes: (this as any).clientSettings.showMyRenotes,
|
||||||
includeRenotedMyNotes: (this as any).os.i.clientSettings.showRenotedMyNotes
|
includeRenotedMyNotes: (this as any).clientSettings.showRenotedMyNotes
|
||||||
}).then(notes => {
|
}).then(notes => {
|
||||||
if (notes.length == fetchLimit + 1) {
|
if (notes.length == fetchLimit + 1) {
|
||||||
notes.pop();
|
notes.pop();
|
||||||
|
|
|
@ -2,9 +2,7 @@
|
||||||
<div class="mk-user-preview">
|
<div class="mk-user-preview">
|
||||||
<template v-if="u != null">
|
<template v-if="u != null">
|
||||||
<div class="banner" :style="u.bannerUrl ? `background-image: url(${u.bannerUrl}?thumbnail&size=512)` : ''"></div>
|
<div class="banner" :style="u.bannerUrl ? `background-image: url(${u.bannerUrl}?thumbnail&size=512)` : ''"></div>
|
||||||
<router-link class="avatar" :to="u | userPage">
|
<mk-avatar class="avatar" :user="u" :disable-preview="true"/>
|
||||||
<img :src="`${u.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
|
|
||||||
</router-link>
|
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<router-link class="name" :to="u | userPage">{{ u | userName }}</router-link>
|
<router-link class="name" :to="u | userPage">{{ u | userName }}</router-link>
|
||||||
<p class="username">@{{ u | acct }}</p>
|
<p class="username">@{{ u | acct }}</p>
|
||||||
|
@ -111,12 +109,8 @@ root(isDark)
|
||||||
top 62px
|
top 62px
|
||||||
left 13px
|
left 13px
|
||||||
z-index 2
|
z-index 2
|
||||||
|
|
||||||
> img
|
|
||||||
display block
|
|
||||||
width 58px
|
width 58px
|
||||||
height 58px
|
height 58px
|
||||||
margin 0
|
|
||||||
border solid 3px isDark ? #282c37 : #fff
|
border solid 3px isDark ? #282c37 : #fff
|
||||||
border-radius 8px
|
border-radius 8px
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="root item">
|
<div class="root item">
|
||||||
<router-link class="avatar-anchor" :to="user | userPage" v-user-preview="user.id">
|
<mk-avatar class="avatar" :user="user"/>
|
||||||
<img class="avatar" :src="`${user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
|
|
||||||
</router-link>
|
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<header>
|
<header>
|
||||||
<router-link class="name" :to="user | userPage" v-user-preview="user.id">{{ user | userName }}</router-link>
|
<router-link class="name" :to="user | userPage" v-user-preview="user.id">{{ user | userName }}</router-link>
|
||||||
|
@ -35,18 +33,13 @@ export default Vue.extend({
|
||||||
display block
|
display block
|
||||||
clear both
|
clear both
|
||||||
|
|
||||||
> .avatar-anchor
|
> .avatar
|
||||||
display block
|
display block
|
||||||
float left
|
float left
|
||||||
margin 0 16px 0 0
|
margin 0 16px 0 0
|
||||||
|
|
||||||
> .avatar
|
|
||||||
display block
|
|
||||||
width 58px
|
width 58px
|
||||||
height 58px
|
height 58px
|
||||||
margin 0
|
|
||||||
border-radius 8px
|
border-radius 8px
|
||||||
vertical-align bottom
|
|
||||||
|
|
||||||
> .main
|
> .main
|
||||||
float left
|
float left
|
||||||
|
|
|
@ -24,8 +24,8 @@ export default Vue.extend({
|
||||||
computed: {
|
computed: {
|
||||||
withGradient(): boolean {
|
withGradient(): boolean {
|
||||||
return (this as any).os.isSignedIn
|
return (this as any).os.isSignedIn
|
||||||
? (this as any).os.i.clientSettings.gradientWindowHeader != null
|
? (this as any).clientSettings.gradientWindowHeader != null
|
||||||
? (this as any).os.i.clientSettings.gradientWindowHeader
|
? (this as any).clientSettings.gradientWindowHeader
|
||||||
: false
|
: false
|
||||||
: false;
|
: false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,8 +94,8 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
withGradient(): boolean {
|
withGradient(): boolean {
|
||||||
return (this as any).os.isSignedIn
|
return (this as any).os.isSignedIn
|
||||||
? (this as any).os.i.clientSettings.gradientWindowHeader != null
|
? (this as any).clientSettings.gradientWindowHeader != null
|
||||||
? (this as any).os.i.clientSettings.gradientWindowHeader
|
? (this as any).clientSettings.gradientWindowHeader
|
||||||
: false
|
: false
|
||||||
: false;
|
: false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,7 @@
|
||||||
<p class="fetching" v-if="fetching">%fa:spinner .pulse .fw% %i18n:common.loading%<mk-ellipsis/></p>
|
<p class="fetching" v-if="fetching">%fa:spinner .pulse .fw% %i18n:common.loading%<mk-ellipsis/></p>
|
||||||
<template v-else-if="users.length != 0">
|
<template v-else-if="users.length != 0">
|
||||||
<div class="user" v-for="_user in users">
|
<div class="user" v-for="_user in users">
|
||||||
<router-link class="avatar-anchor" :to="_user | userPage">
|
<mk-avatar class="avatar" :user="_user"/>
|
||||||
<img class="avatar" :src="`${_user.avatarUrl}?thumbnail&size=42`" alt="" v-user-preview="_user.id"/>
|
|
||||||
</router-link>
|
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<router-link class="name" :to="_user | userPage" v-user-preview="_user.id">{{ _user | userName }}</router-link>
|
<router-link class="name" :to="_user | userPage" v-user-preview="_user.id">{{ _user | userName }}</router-link>
|
||||||
<p class="username">@{{ _user | acct }}</p>
|
<p class="username">@{{ _user | acct }}</p>
|
||||||
|
@ -80,18 +78,13 @@ root(isDark)
|
||||||
display block
|
display block
|
||||||
clear both
|
clear both
|
||||||
|
|
||||||
> .avatar-anchor
|
> .avatar
|
||||||
display block
|
display block
|
||||||
float left
|
float left
|
||||||
margin 0 12px 0 0
|
margin 0 12px 0 0
|
||||||
|
|
||||||
> .avatar
|
|
||||||
display block
|
|
||||||
width 42px
|
width 42px
|
||||||
height 42px
|
height 42px
|
||||||
margin 0
|
|
||||||
border-radius 8px
|
border-radius 8px
|
||||||
vertical-align bottom
|
|
||||||
|
|
||||||
> .body
|
> .body
|
||||||
float left
|
float left
|
||||||
|
|
|
@ -4,9 +4,7 @@
|
||||||
<p class="initializing" v-if="fetching">%fa:spinner .pulse .fw%%i18n:@loading%<mk-ellipsis/></p>
|
<p class="initializing" v-if="fetching">%fa:spinner .pulse .fw%%i18n:@loading%<mk-ellipsis/></p>
|
||||||
<template v-if="!fetching && users.length != 0">
|
<template v-if="!fetching && users.length != 0">
|
||||||
<div class="user" v-for="friend in users">
|
<div class="user" v-for="friend in users">
|
||||||
<router-link class="avatar-anchor" :to="friend | userPage">
|
<mk-avatar class="avatar" :user="friend"/>
|
||||||
<img class="avatar" :src="`${friend.avatarUrl}?thumbnail&size=42`" alt="" v-user-preview="friend.id"/>
|
|
||||||
</router-link>
|
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<router-link class="name" :to="friend | userPage" v-user-preview="friend.id">{{ friend.name }}</router-link>
|
<router-link class="name" :to="friend | userPage" v-user-preview="friend.id">{{ friend.name }}</router-link>
|
||||||
<p class="username">@{{ friend | acct }}</p>
|
<p class="username">@{{ friend | acct }}</p>
|
||||||
|
@ -82,18 +80,13 @@ export default Vue.extend({
|
||||||
display block
|
display block
|
||||||
clear both
|
clear both
|
||||||
|
|
||||||
> .avatar-anchor
|
> .avatar
|
||||||
display block
|
display block
|
||||||
float left
|
float left
|
||||||
margin 0 12px 0 0
|
margin 0 12px 0 0
|
||||||
|
|
||||||
> .avatar
|
|
||||||
display block
|
|
||||||
width 42px
|
width 42px
|
||||||
height 42px
|
height 42px
|
||||||
margin 0
|
|
||||||
border-radius 8px
|
border-radius 8px
|
||||||
vertical-align bottom
|
|
||||||
|
|
||||||
> .body
|
> .body
|
||||||
float left
|
float left
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<div class="fade"></div>
|
<div class="fade"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<img class="avatar" :src="`${user.avatarUrl}?thumbnail&size=150`" alt="avatar"/>
|
<mk-avatar class="avatar" :user="user" :disable-preview="true"/>
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<p class="name">{{ user | userName }}</p>
|
<p class="name">{{ user | userName }}</p>
|
||||||
<p class="username">@{{ user | acct }}</p>
|
<p class="username">@{{ user | acct }}</p>
|
||||||
|
@ -139,7 +139,6 @@ export default Vue.extend({
|
||||||
z-index 2
|
z-index 2
|
||||||
width 160px
|
width 160px
|
||||||
height 160px
|
height 160px
|
||||||
margin 0
|
|
||||||
border solid 3px #fff
|
border solid 3px #fff
|
||||||
border-radius 8px
|
border-radius 8px
|
||||||
box-shadow 1px 1px 3px rgba(#000, 0.2)
|
box-shadow 1px 1px 3px rgba(#000, 0.2)
|
||||||
|
|
|
@ -8,9 +8,7 @@
|
||||||
<p>ようこそ! <b>Misskey</b>はTwitter風ミニブログSNSです。思ったことや皆と共有したいことを投稿しましょう。タイムラインを見れば、皆の関心事をすぐにチェックすることもできます。<a :href="aboutUrl">詳しく...</a></p>
|
<p>ようこそ! <b>Misskey</b>はTwitter風ミニブログSNSです。思ったことや皆と共有したいことを投稿しましょう。タイムラインを見れば、皆の関心事をすぐにチェックすることもできます。<a :href="aboutUrl">詳しく...</a></p>
|
||||||
<p><button class="signup" @click="signup">はじめる</button><button class="signin" @click="signin">ログイン</button></p>
|
<p><button class="signup" @click="signup">はじめる</button><button class="signin" @click="signin">ログイン</button></p>
|
||||||
<div class="users">
|
<div class="users">
|
||||||
<router-link v-for="user in users" :key="user.id" class="avatar-anchor" :to="user | userPage" v-user-preview="user.id">
|
<mk-avatar class="avatar" :key="user.id" :user="user"/>
|
||||||
<img class="avatar" :src="`${user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
|
|
||||||
</router-link>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -22,9 +22,11 @@ export default define({
|
||||||
} else {
|
} else {
|
||||||
this.props.design++;
|
this.props.design++;
|
||||||
}
|
}
|
||||||
|
this.save();
|
||||||
},
|
},
|
||||||
viewChanged(view) {
|
viewChanged(view) {
|
||||||
this.props.view = view;
|
this.props.view = view;
|
||||||
|
this.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -37,6 +37,7 @@ export default define({
|
||||||
methods: {
|
methods: {
|
||||||
func() {
|
func() {
|
||||||
this.props.compact = !this.props.compact;
|
this.props.compact = !this.props.compact;
|
||||||
|
this.save();
|
||||||
},
|
},
|
||||||
settings() {
|
settings() {
|
||||||
const id = window.prompt('チャンネルID');
|
const id = window.prompt('チャンネルID');
|
||||||
|
|
|
@ -35,6 +35,7 @@ export default define({
|
||||||
} else {
|
} else {
|
||||||
this.props.design++;
|
this.props.design++;
|
||||||
}
|
}
|
||||||
|
this.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -23,6 +23,7 @@ export default define({
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
this.props.compact = !this.props.compact;
|
this.props.compact = !this.props.compact;
|
||||||
|
this.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -39,6 +39,7 @@ export default define({
|
||||||
methods: {
|
methods: {
|
||||||
func() {
|
func() {
|
||||||
this.props.compact = !this.props.compact;
|
this.props.compact = !this.props.compact;
|
||||||
|
this.save();
|
||||||
},
|
},
|
||||||
fetch() {
|
fetch() {
|
||||||
this.fetching = true;
|
this.fetching = true;
|
||||||
|
|
|
@ -29,6 +29,7 @@ export default define({
|
||||||
} else {
|
} else {
|
||||||
this.props.design++;
|
this.props.design++;
|
||||||
}
|
}
|
||||||
|
this.save();
|
||||||
},
|
},
|
||||||
onKeydown(e) {
|
onKeydown(e) {
|
||||||
if ((e.which == 10 || e.which == 13) && (e.ctrlKey || e.metaKey)) this.post();
|
if ((e.which == 10 || e.which == 13) && (e.ctrlKey || e.metaKey)) this.post();
|
||||||
|
|
|
@ -36,6 +36,7 @@ export default define({
|
||||||
} else {
|
} else {
|
||||||
this.props.design++;
|
this.props.design++;
|
||||||
}
|
}
|
||||||
|
this.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -22,6 +22,7 @@ export default define({
|
||||||
} else {
|
} else {
|
||||||
this.props.design++;
|
this.props.design++;
|
||||||
}
|
}
|
||||||
|
this.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -38,6 +38,7 @@ export default define({
|
||||||
methods: {
|
methods: {
|
||||||
func() {
|
func() {
|
||||||
this.props.compact = !this.props.compact;
|
this.props.compact = !this.props.compact;
|
||||||
|
this.save();
|
||||||
},
|
},
|
||||||
fetch() {
|
fetch() {
|
||||||
this.fetching = true;
|
this.fetching = true;
|
||||||
|
|
|
@ -8,9 +8,7 @@
|
||||||
<p class="fetching" v-if="fetching">%fa:spinner .pulse .fw%%i18n:common.loading%<mk-ellipsis/></p>
|
<p class="fetching" v-if="fetching">%fa:spinner .pulse .fw%%i18n:common.loading%<mk-ellipsis/></p>
|
||||||
<template v-else-if="users.length != 0">
|
<template v-else-if="users.length != 0">
|
||||||
<div class="user" v-for="_user in users">
|
<div class="user" v-for="_user in users">
|
||||||
<router-link class="avatar-anchor" :to="_user | userPage">
|
<mk-avatar class="avatar" :user="_user"/>
|
||||||
<img class="avatar" :src="`${_user.avatarUrl}?thumbnail&size=42`" alt="" v-user-preview="_user.id"/>
|
|
||||||
</router-link>
|
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<router-link class="name" :to="_user | userPage" v-user-preview="_user.id">{{ _user | userName }}</router-link>
|
<router-link class="name" :to="_user | userPage" v-user-preview="_user.id">{{ _user | userName }}</router-link>
|
||||||
<p class="username">@{{ _user | acct }}</p>
|
<p class="username">@{{ _user | acct }}</p>
|
||||||
|
@ -48,6 +46,7 @@ export default define({
|
||||||
methods: {
|
methods: {
|
||||||
func() {
|
func() {
|
||||||
this.props.compact = !this.props.compact;
|
this.props.compact = !this.props.compact;
|
||||||
|
this.save();
|
||||||
},
|
},
|
||||||
fetch() {
|
fetch() {
|
||||||
this.fetching = true;
|
this.fetching = true;
|
||||||
|
@ -88,18 +87,13 @@ root(isDark)
|
||||||
display block
|
display block
|
||||||
clear both
|
clear both
|
||||||
|
|
||||||
> .avatar-anchor
|
> .avatar
|
||||||
display block
|
display block
|
||||||
float left
|
float left
|
||||||
margin 0 12px 0 0
|
margin 0 12px 0 0
|
||||||
|
|
||||||
> .avatar
|
|
||||||
display block
|
|
||||||
width 42px
|
width 42px
|
||||||
height 42px
|
height 42px
|
||||||
margin 0
|
|
||||||
border-radius 8px
|
border-radius 8px
|
||||||
vertical-align bottom
|
|
||||||
|
|
||||||
> .body
|
> .body
|
||||||
float left
|
float left
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import Vuex from 'vuex';
|
import Vuex, { mapState } from 'vuex';
|
||||||
import VueRouter from 'vue-router';
|
import VueRouter from 'vue-router';
|
||||||
import VModal from 'vue-js-modal';
|
import VModal from 'vue-js-modal';
|
||||||
import * as TreeView from 'vue-json-tree-view';
|
import * as TreeView from 'vue-json-tree-view';
|
||||||
|
@ -41,17 +41,6 @@ require('./common/views/widgets');
|
||||||
// Register global filters
|
// Register global filters
|
||||||
require('./common/views/filters');
|
require('./common/views/filters');
|
||||||
|
|
||||||
const store = new Vuex.Store({
|
|
||||||
state: {
|
|
||||||
uiHeaderHeight: 0
|
|
||||||
},
|
|
||||||
mutations: {
|
|
||||||
setUiHeaderHeight(state, height) {
|
|
||||||
state.uiHeaderHeight = height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Vue.mixin({
|
Vue.mixin({
|
||||||
destroyed(this: any) {
|
destroyed(this: any) {
|
||||||
if (this.$el.parentNode) {
|
if (this.$el.parentNode) {
|
||||||
|
@ -159,20 +148,15 @@ export default (callback: (launch: (router: VueRouter, api?: (os: MiOS) => API)
|
||||||
api: os.api,
|
api: os.api,
|
||||||
apis: os.apis
|
apis: os.apis
|
||||||
};
|
};
|
||||||
}
|
},
|
||||||
|
computed: mapState({
|
||||||
|
clientSettings: state => state.settings.data
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
const app = new Vue({
|
const app = new Vue({
|
||||||
store,
|
store: os.store,
|
||||||
router,
|
router,
|
||||||
created() {
|
|
||||||
this.$watch('os.i', i => {
|
|
||||||
// キャッシュ更新
|
|
||||||
localStorage.setItem('me', JSON.stringify(i));
|
|
||||||
}, {
|
|
||||||
deep: true
|
|
||||||
});
|
|
||||||
},
|
|
||||||
render: createEl => createEl(App)
|
render: createEl => createEl(App)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="root sub">
|
<div class="root sub">
|
||||||
<router-link class="avatar-anchor" :to="note.user | userPage">
|
<mk-avatar class="avatar" :user="note.user"/>
|
||||||
<img class="avatar" :src="`${note.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
|
|
||||||
</router-link>
|
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<header>
|
<header>
|
||||||
<router-link class="name" :to="note.user | userPage">{{ note.user | userName }}</router-link>
|
<router-link class="name" :to="note.user | userPage">{{ note.user | userName }}</router-link>
|
||||||
|
@ -43,18 +41,13 @@ root(isDark)
|
||||||
display block
|
display block
|
||||||
clear both
|
clear both
|
||||||
|
|
||||||
> .avatar-anchor
|
> .avatar
|
||||||
display block
|
display block
|
||||||
float left
|
float left
|
||||||
margin 0 12px 0 0
|
margin 0 12px 0 0
|
||||||
|
|
||||||
> .avatar
|
|
||||||
display block
|
|
||||||
width 48px
|
width 48px
|
||||||
height 48px
|
height 48px
|
||||||
margin 0
|
|
||||||
border-radius 8px
|
border-radius 8px
|
||||||
vertical-align bottom
|
|
||||||
|
|
||||||
> .main
|
> .main
|
||||||
float left
|
float left
|
||||||
|
|
|
@ -17,17 +17,12 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="renote" v-if="isRenote">
|
<div class="renote" v-if="isRenote">
|
||||||
<p>
|
<p>
|
||||||
<router-link class="avatar-anchor" :to="note.user | userPage">
|
<mk-avatar class="avatar" :user="note.user"/>%fa:retweet%<router-link class="name" :to="note.user | userPage">{{ note.user | userName }}</router-link>がRenote
|
||||||
<img class="avatar" :src="`${note.user.avatarUrl}?thumbnail&size=32`" alt="avatar"/>
|
|
||||||
</router-link>
|
|
||||||
%fa:retweet%<router-link class="name" :to="note.user | userPage">{{ note.user | userName }}</router-link>がRenote
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<article>
|
<article>
|
||||||
<header>
|
<header>
|
||||||
<router-link class="avatar-anchor" :to="p.user | userPage">
|
<mk-avatar class="avatar" :user="p.user"/>
|
||||||
<img class="avatar" :src="`${p.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
|
|
||||||
</router-link>
|
|
||||||
<div>
|
<div>
|
||||||
<router-link class="name" :to="p.user | userPage">{{ p.user | userName }}</router-link>
|
<router-link class="name" :to="p.user | userPage">{{ p.user | userName }}</router-link>
|
||||||
<span class="username">@{{ p.user | acct }}</span>
|
<span class="username">@{{ p.user | acct }}</span>
|
||||||
|
@ -152,7 +147,7 @@ export default Vue.extend({
|
||||||
|
|
||||||
// Draw map
|
// Draw map
|
||||||
if (this.p.geo) {
|
if (this.p.geo) {
|
||||||
const shouldShowMap = (this as any).os.isSignedIn ? (this as any).os.i.clientSettings.showMaps : true;
|
const shouldShowMap = (this as any).os.isSignedIn ? (this as any).clientSettings.showMaps : true;
|
||||||
if (shouldShowMap) {
|
if (shouldShowMap) {
|
||||||
(this as any).os.getGoogleMaps().then(maps => {
|
(this as any).os.getGoogleMaps().then(maps => {
|
||||||
const uluru = new maps.LatLng(this.p.geo.coordinates[1], this.p.geo.coordinates[0]);
|
const uluru = new maps.LatLng(this.p.geo.coordinates[1], this.p.geo.coordinates[0]);
|
||||||
|
@ -262,15 +257,10 @@ root(isDark)
|
||||||
margin 0
|
margin 0
|
||||||
padding 16px 32px
|
padding 16px 32px
|
||||||
|
|
||||||
.avatar-anchor
|
|
||||||
display inline-block
|
|
||||||
|
|
||||||
.avatar
|
.avatar
|
||||||
vertical-align bottom
|
display inline-block
|
||||||
min-width 28px
|
width 28px
|
||||||
min-height 28px
|
height 28px
|
||||||
max-width 28px
|
|
||||||
max-height 28px
|
|
||||||
margin 0 8px 0 0
|
margin 0 8px 0 0
|
||||||
border-radius 6px
|
border-radius 6px
|
||||||
|
|
||||||
|
@ -301,17 +291,12 @@ root(isDark)
|
||||||
display flex
|
display flex
|
||||||
line-height 1.1em
|
line-height 1.1em
|
||||||
|
|
||||||
> .avatar-anchor
|
|
||||||
display block
|
|
||||||
padding 0 12px 0 0
|
|
||||||
|
|
||||||
> .avatar
|
> .avatar
|
||||||
display block
|
display block
|
||||||
|
margin 0 12px 0 0
|
||||||
width 54px
|
width 54px
|
||||||
height 54px
|
height 54px
|
||||||
margin 0
|
|
||||||
border-radius 8px
|
border-radius 8px
|
||||||
vertical-align bottom
|
|
||||||
|
|
||||||
@media (min-width 500px)
|
@media (min-width 500px)
|
||||||
width 60px
|
width 60px
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="mk-note-preview">
|
<div class="mk-note-preview">
|
||||||
<router-link class="avatar-anchor" :to="note.user | userPage">
|
<mk-avatar class="avatar" :user="note.user"/>
|
||||||
<img class="avatar" :src="`${note.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
|
|
||||||
</router-link>
|
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<header>
|
<header>
|
||||||
<router-link class="name" :to="note.user | userPage">{{ note.user | userName }}</router-link>
|
<router-link class="name" :to="note.user | userPage">{{ note.user | userName }}</router-link>
|
||||||
|
@ -37,18 +35,13 @@ root(isDark)
|
||||||
display block
|
display block
|
||||||
clear both
|
clear both
|
||||||
|
|
||||||
> .avatar-anchor
|
> .avatar
|
||||||
display block
|
display block
|
||||||
float left
|
float left
|
||||||
margin 0 12px 0 0
|
margin 0 12px 0 0
|
||||||
|
|
||||||
> .avatar
|
|
||||||
display block
|
|
||||||
width 48px
|
width 48px
|
||||||
height 48px
|
height 48px
|
||||||
margin 0
|
|
||||||
border-radius 8px
|
border-radius 8px
|
||||||
vertical-align bottom
|
|
||||||
|
|
||||||
> .main
|
> .main
|
||||||
float left
|
float left
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="sub">
|
<div class="sub">
|
||||||
<router-link class="avatar-anchor" :to="note.user | userPage">
|
<mk-avatar class="avatar" :user="note.user"/>
|
||||||
<img class="avatar" :src="`${note.user.avatarUrl}?thumbnail&size=96`" alt="avatar"/>
|
|
||||||
</router-link>
|
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<header>
|
<header>
|
||||||
<router-link class="name" :to="note.user | userPage">{{ note.user | userName }}</router-link>
|
<router-link class="name" :to="note.user | userPage">{{ note.user | userName }}</router-link>
|
||||||
|
@ -49,23 +47,16 @@ root(isDark)
|
||||||
display block
|
display block
|
||||||
clear both
|
clear both
|
||||||
|
|
||||||
> .avatar-anchor
|
> .avatar
|
||||||
display block
|
display block
|
||||||
float left
|
float left
|
||||||
margin 0 10px 0 0
|
margin 0 10px 0 0
|
||||||
|
width 44px
|
||||||
|
height 44px
|
||||||
|
border-radius 8px
|
||||||
|
|
||||||
@media (min-width 500px)
|
@media (min-width 500px)
|
||||||
margin-right 16px
|
margin-right 16px
|
||||||
|
|
||||||
> .avatar
|
|
||||||
display block
|
|
||||||
width 44px
|
|
||||||
height 44px
|
|
||||||
margin 0
|
|
||||||
border-radius 8px
|
|
||||||
vertical-align bottom
|
|
||||||
|
|
||||||
@media (min-width 500px)
|
|
||||||
width 52px
|
width 52px
|
||||||
height 52px
|
height 52px
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="note" :class="{ renote: isRenote }">
|
<div class="note" :class="{ renote: isRenote }">
|
||||||
<div class="reply-to" v-if="p.reply && (!os.isSignedIn || os.i.clientSettings.showReplyTarget)">
|
<div class="reply-to" v-if="p.reply && (!os.isSignedIn || clientSettings.showReplyTarget)">
|
||||||
<x-sub :note="p.reply"/>
|
<x-sub :note="p.reply"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="renote" v-if="isRenote">
|
<div class="renote" v-if="isRenote">
|
||||||
<router-link class="avatar-anchor" :to="note.user | userPage">
|
<mk-avatar class="avatar" :user="note.user"/>
|
||||||
<img class="avatar" :src="`${note.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
|
|
||||||
</router-link>
|
|
||||||
%fa:retweet%
|
%fa:retweet%
|
||||||
<span>{{ '%i18n:!@reposted-by%'.substr(0, '%i18n:!@reposted-by%'.indexOf('{')) }}</span>
|
<span>{{ '%i18n:!@reposted-by%'.substr(0, '%i18n:!@reposted-by%'.indexOf('{')) }}</span>
|
||||||
<router-link class="name" :to="note.user | userPage">{{ note.user | userName }}</router-link>
|
<router-link class="name" :to="note.user | userPage">{{ note.user | userName }}</router-link>
|
||||||
|
@ -14,9 +12,7 @@
|
||||||
<mk-time :time="note.createdAt"/>
|
<mk-time :time="note.createdAt"/>
|
||||||
</div>
|
</div>
|
||||||
<article>
|
<article>
|
||||||
<router-link class="avatar-anchor" :to="p.user | userPage">
|
<mk-avatar class="avatar" :user="p.user"/>
|
||||||
<img class="avatar" :src="`${p.user.avatarUrl}?thumbnail&size=96`" alt="avatar"/>
|
|
||||||
</router-link>
|
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<header>
|
<header>
|
||||||
<router-link class="name" :to="p.user | userPage">{{ p.user | userName }}</router-link>
|
<router-link class="name" :to="p.user | userPage">{{ p.user | userName }}</router-link>
|
||||||
|
@ -154,7 +150,7 @@ export default Vue.extend({
|
||||||
|
|
||||||
// Draw map
|
// Draw map
|
||||||
if (this.p.geo) {
|
if (this.p.geo) {
|
||||||
const shouldShowMap = (this as any).os.isSignedIn ? (this as any).os.i.clientSettings.showMaps : true;
|
const shouldShowMap = (this as any).os.isSignedIn ? (this as any).clientSettings.showMaps : true;
|
||||||
if (shouldShowMap) {
|
if (shouldShowMap) {
|
||||||
(this as any).os.getGoogleMaps().then(maps => {
|
(this as any).os.getGoogleMaps().then(maps => {
|
||||||
const uluru = new maps.LatLng(this.p.geo.coordinates[1], this.p.geo.coordinates[0]);
|
const uluru = new maps.LatLng(this.p.geo.coordinates[1], this.p.geo.coordinates[0]);
|
||||||
|
@ -268,11 +264,8 @@ root(isDark)
|
||||||
@media (min-width 600px)
|
@media (min-width 600px)
|
||||||
padding 16px 32px
|
padding 16px 32px
|
||||||
|
|
||||||
.avatar-anchor
|
|
||||||
display inline-block
|
|
||||||
|
|
||||||
.avatar
|
.avatar
|
||||||
vertical-align bottom
|
display inline-block
|
||||||
width 28px
|
width 28px
|
||||||
height 28px
|
height 28px
|
||||||
margin 0 8px 0 0
|
margin 0 8px 0 0
|
||||||
|
@ -314,26 +307,19 @@ root(isDark)
|
||||||
display block
|
display block
|
||||||
clear both
|
clear both
|
||||||
|
|
||||||
> .avatar-anchor
|
> .avatar
|
||||||
display block
|
display block
|
||||||
float left
|
float left
|
||||||
margin 0 10px 8px 0
|
margin 0 10px 8px 0
|
||||||
|
width 48px
|
||||||
|
height 48px
|
||||||
|
border-radius 6px
|
||||||
//position -webkit-sticky
|
//position -webkit-sticky
|
||||||
//position sticky
|
//position sticky
|
||||||
//top 62px
|
//top 62px
|
||||||
|
|
||||||
@media (min-width 500px)
|
@media (min-width 500px)
|
||||||
margin-right 16px
|
margin-right 16px
|
||||||
|
|
||||||
> .avatar
|
|
||||||
display block
|
|
||||||
width 48px
|
|
||||||
height 48px
|
|
||||||
margin 0
|
|
||||||
border-radius 6px
|
|
||||||
vertical-align bottom
|
|
||||||
|
|
||||||
@media (min-width 500px)
|
|
||||||
width 58px
|
width 58px
|
||||||
height 58px
|
height 58px
|
||||||
border-radius 8px
|
border-radius 8px
|
||||||
|
|
|
@ -116,13 +116,13 @@ export default Vue.extend({
|
||||||
const isMyNote = note.userId == (this as any).os.i.id;
|
const isMyNote = note.userId == (this as any).os.i.id;
|
||||||
const isPureRenote = note.renoteId != null && note.text == null && note.mediaIds.length == 0 && note.poll == null;
|
const isPureRenote = note.renoteId != null && note.text == null && note.mediaIds.length == 0 && note.poll == null;
|
||||||
|
|
||||||
if ((this as any).os.i.clientSettings.showMyRenotes === false) {
|
if ((this as any).clientSettings.showMyRenotes === false) {
|
||||||
if (isMyNote && isPureRenote) {
|
if (isMyNote && isPureRenote) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((this as any).os.i.clientSettings.showRenotedMyNotes === false) {
|
if ((this as any).clientSettings.showRenotedMyNotes === false) {
|
||||||
if (isPureRenote && (note.renote.userId == (this as any).os.i.id)) {
|
if (isPureRenote && (note.renote.userId == (this as any).os.i.id)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -187,7 +187,7 @@ export default Vue.extend({
|
||||||
this.clearNotification();
|
this.clearNotification();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((this as any).os.i.clientSettings.fetchOnScroll !== false) {
|
if ((this as any).clientSettings.fetchOnScroll !== false) {
|
||||||
const current = window.scrollY + window.innerHeight;
|
const current = window.scrollY + window.innerHeight;
|
||||||
if (current > document.body.offsetHeight - 8) this.loadMore();
|
if (current > document.body.offsetHeight - 8) this.loadMore();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="mk-notification">
|
<div class="mk-notification">
|
||||||
<div class="notification reaction" v-if="notification.type == 'reaction'">
|
<div class="notification reaction" v-if="notification.type == 'reaction'">
|
||||||
<router-link class="avatar-anchor" :to="notification.user | userPage">
|
<mk-avatar class="avatar" :user="notification.user"/>
|
||||||
<img class="avatar" :src="`${notification.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
|
|
||||||
</router-link>
|
|
||||||
<div>
|
<div>
|
||||||
<header>
|
<header>
|
||||||
<mk-reaction-icon :reaction="notification.reaction"/>
|
<mk-reaction-icon :reaction="notification.reaction"/>
|
||||||
|
@ -18,9 +16,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="notification renote" v-if="notification.type == 'renote'">
|
<div class="notification renote" v-if="notification.type == 'renote'">
|
||||||
<router-link class="avatar-anchor" :to="notification.user | userPage">
|
<mk-avatar class="avatar" :user="notification.user"/>
|
||||||
<img class="avatar" :src="`${notification.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
|
|
||||||
</router-link>
|
|
||||||
<div>
|
<div>
|
||||||
<header>
|
<header>
|
||||||
%fa:retweet%
|
%fa:retweet%
|
||||||
|
@ -34,9 +30,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="notification follow" v-if="notification.type == 'follow'">
|
<div class="notification follow" v-if="notification.type == 'follow'">
|
||||||
<router-link class="avatar-anchor" :to="notification.user | userPage">
|
<mk-avatar class="avatar" :user="notification.user"/>
|
||||||
<img class="avatar" :src="`${notification.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
|
|
||||||
</router-link>
|
|
||||||
<div>
|
<div>
|
||||||
<header>
|
<header>
|
||||||
%fa:user-plus%
|
%fa:user-plus%
|
||||||
|
@ -47,9 +41,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="notification poll_vote" v-if="notification.type == 'poll_vote'">
|
<div class="notification poll_vote" v-if="notification.type == 'poll_vote'">
|
||||||
<router-link class="avatar-anchor" :to="notification.user | userPage">
|
<mk-avatar class="avatar" :user="notification.user"/>
|
||||||
<img class="avatar" :src="`${notification.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
|
|
||||||
</router-link>
|
|
||||||
<div>
|
<div>
|
||||||
<header>
|
<header>
|
||||||
%fa:chart-pie%
|
%fa:chart-pie%
|
||||||
|
@ -111,11 +103,9 @@ root(isDark)
|
||||||
display block
|
display block
|
||||||
clear both
|
clear both
|
||||||
|
|
||||||
> .avatar-anchor
|
> .avatar
|
||||||
display block
|
display block
|
||||||
float left
|
float left
|
||||||
|
|
||||||
img
|
|
||||||
width 36px
|
width 36px
|
||||||
height 36px
|
height 36px
|
||||||
border-radius 6px
|
border-radius 6px
|
||||||
|
|
|
@ -166,7 +166,7 @@ export default Vue.extend({
|
||||||
|
|
||||||
post() {
|
post() {
|
||||||
this.posting = true;
|
this.posting = true;
|
||||||
const viaMobile = (this as any).os.i.clientSettings.disableViaMobile !== true;
|
const viaMobile = (this as any).clientSettings.disableViaMobile !== true;
|
||||||
(this as any).api('notes/create', {
|
(this as any).api('notes/create', {
|
||||||
text: this.text == '' ? undefined : this.text,
|
text: this.text == '' ? undefined : this.text,
|
||||||
mediaIds: this.files.length > 0 ? this.files.map(f => f.id) : undefined,
|
mediaIds: this.files.length > 0 ? this.files.map(f => f.id) : undefined,
|
||||||
|
|
|
@ -46,8 +46,8 @@ export default Vue.extend({
|
||||||
(this as any).api('notes/user-list-timeline', {
|
(this as any).api('notes/user-list-timeline', {
|
||||||
listId: this.list.id,
|
listId: this.list.id,
|
||||||
limit: fetchLimit + 1,
|
limit: fetchLimit + 1,
|
||||||
includeMyRenotes: (this as any).os.i.clientSettings.showMyRenotes,
|
includeMyRenotes: (this as any).clientSettings.showMyRenotes,
|
||||||
includeRenotedMyNotes: (this as any).os.i.clientSettings.showRenotedMyNotes
|
includeRenotedMyNotes: (this as any).clientSettings.showRenotedMyNotes
|
||||||
}).then(notes => {
|
}).then(notes => {
|
||||||
if (notes.length == fetchLimit + 1) {
|
if (notes.length == fetchLimit + 1) {
|
||||||
notes.pop();
|
notes.pop();
|
||||||
|
@ -66,8 +66,8 @@ export default Vue.extend({
|
||||||
listId: this.list.id,
|
listId: this.list.id,
|
||||||
limit: fetchLimit + 1,
|
limit: fetchLimit + 1,
|
||||||
untilId: (this.$refs.timeline as any).tail().id,
|
untilId: (this.$refs.timeline as any).tail().id,
|
||||||
includeMyRenotes: (this as any).os.i.clientSettings.showMyRenotes,
|
includeMyRenotes: (this as any).clientSettings.showMyRenotes,
|
||||||
includeRenotedMyNotes: (this as any).os.i.clientSettings.showRenotedMyNotes
|
includeRenotedMyNotes: (this as any).clientSettings.showRenotedMyNotes
|
||||||
}).then(notes => {
|
}).then(notes => {
|
||||||
if (notes.length == fetchLimit + 1) {
|
if (notes.length == fetchLimit + 1) {
|
||||||
notes.pop();
|
notes.pop();
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="mk-user-preview">
|
<div class="mk-user-preview">
|
||||||
<router-link class="avatar-anchor" :to="user | userPage">
|
<mk-avatar class="avatar" :user="user"/>
|
||||||
<img class="avatar" :src="`${user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
|
|
||||||
</router-link>
|
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<header>
|
<header>
|
||||||
<router-link class="name" :to="user | userPage">{{ user | userName }}</router-link>
|
<router-link class="name" :to="user | userPage">{{ user | userName }}</router-link>
|
||||||
|
@ -40,23 +38,16 @@ export default Vue.extend({
|
||||||
display block
|
display block
|
||||||
clear both
|
clear both
|
||||||
|
|
||||||
> .avatar-anchor
|
> .avatar
|
||||||
display block
|
display block
|
||||||
float left
|
float left
|
||||||
margin 0 10px 0 0
|
margin 0 10px 0 0
|
||||||
|
width 48px
|
||||||
|
height 48px
|
||||||
|
border-radius 6px
|
||||||
|
|
||||||
@media (min-width 500px)
|
@media (min-width 500px)
|
||||||
margin-right 16px
|
margin-right 16px
|
||||||
|
|
||||||
> .avatar
|
|
||||||
display block
|
|
||||||
width 48px
|
|
||||||
height 48px
|
|
||||||
margin 0
|
|
||||||
border-radius 6px
|
|
||||||
vertical-align bottom
|
|
||||||
|
|
||||||
@media (min-width 500px)
|
|
||||||
width 58px
|
width 58px
|
||||||
height 58px
|
height 58px
|
||||||
border-radius 8px
|
border-radius 8px
|
||||||
|
|
|
@ -64,8 +64,8 @@ export default Vue.extend({
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
if ((this as any).os.i.clientSettings.mobileHome == null) {
|
if ((this as any).clientSettings.mobileHome == null) {
|
||||||
Vue.set((this as any).os.i.clientSettings, 'mobileHome', [{
|
Vue.set((this as any).clientSettings, 'mobileHome', [{
|
||||||
name: 'calendar',
|
name: 'calendar',
|
||||||
id: 'a', data: {}
|
id: 'a', data: {}
|
||||||
}, {
|
}, {
|
||||||
|
@ -87,14 +87,14 @@ export default Vue.extend({
|
||||||
name: 'version',
|
name: 'version',
|
||||||
id: 'g', data: {}
|
id: 'g', data: {}
|
||||||
}]);
|
}]);
|
||||||
this.widgets = (this as any).os.i.clientSettings.mobileHome;
|
this.widgets = (this as any).clientSettings.mobileHome;
|
||||||
this.saveHome();
|
this.saveHome();
|
||||||
} else {
|
} else {
|
||||||
this.widgets = (this as any).os.i.clientSettings.mobileHome;
|
this.widgets = (this as any).clientSettings.mobileHome;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$watch('os.i.clientSettings', i => {
|
this.$watch('clientSettings', i => {
|
||||||
this.widgets = (this as any).os.i.clientSettings.mobileHome;
|
this.widgets = (this as any).clientSettings.mobileHome;
|
||||||
}, {
|
}, {
|
||||||
deep: true
|
deep: true
|
||||||
});
|
});
|
||||||
|
@ -107,15 +107,15 @@ export default Vue.extend({
|
||||||
methods: {
|
methods: {
|
||||||
onHomeUpdated(data) {
|
onHomeUpdated(data) {
|
||||||
if (data.home) {
|
if (data.home) {
|
||||||
(this as any).os.i.clientSettings.mobileHome = data.home;
|
(this as any).clientSettings.mobileHome = data.home;
|
||||||
this.widgets = data.home;
|
this.widgets = data.home;
|
||||||
} else {
|
} else {
|
||||||
const w = (this as any).os.i.clientSettings.mobileHome.find(w => w.id == data.id);
|
const w = (this as any).clientSettings.mobileHome.find(w => w.id == data.id);
|
||||||
if (w != null) {
|
if (w != null) {
|
||||||
w.data = data.data;
|
w.data = data.data;
|
||||||
this.$refs[w.id][0].preventSave = true;
|
this.$refs[w.id][0].preventSave = true;
|
||||||
this.$refs[w.id][0].props = w.data;
|
this.$refs[w.id][0].props = w.data;
|
||||||
this.widgets = (this as any).os.i.clientSettings.mobileHome;
|
this.widgets = (this as any).clientSettings.mobileHome;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -144,7 +144,7 @@ export default Vue.extend({
|
||||||
this.saveHome();
|
this.saveHome();
|
||||||
},
|
},
|
||||||
saveHome() {
|
saveHome() {
|
||||||
(this as any).os.i.clientSettings.mobileHome = this.widgets;
|
(this as any).clientSettings.mobileHome = this.widgets;
|
||||||
(this as any).api('i/update_mobile_home', {
|
(this as any).api('i/update_mobile_home', {
|
||||||
home: this.widgets
|
home: this.widgets
|
||||||
});
|
});
|
||||||
|
|
|
@ -92,8 +92,8 @@ export default Vue.extend({
|
||||||
(this as any).api(this.endpoint, {
|
(this as any).api(this.endpoint, {
|
||||||
limit: fetchLimit + 1,
|
limit: fetchLimit + 1,
|
||||||
untilDate: this.date ? this.date.getTime() : undefined,
|
untilDate: this.date ? this.date.getTime() : undefined,
|
||||||
includeMyRenotes: (this as any).os.i.clientSettings.showMyRenotes,
|
includeMyRenotes: (this as any).clientSettings.showMyRenotes,
|
||||||
includeRenotedMyNotes: (this as any).os.i.clientSettings.showRenotedMyNotes
|
includeRenotedMyNotes: (this as any).clientSettings.showRenotedMyNotes
|
||||||
}).then(notes => {
|
}).then(notes => {
|
||||||
if (notes.length == fetchLimit + 1) {
|
if (notes.length == fetchLimit + 1) {
|
||||||
notes.pop();
|
notes.pop();
|
||||||
|
@ -114,8 +114,8 @@ export default Vue.extend({
|
||||||
(this as any).api(this.endpoint, {
|
(this as any).api(this.endpoint, {
|
||||||
limit: fetchLimit + 1,
|
limit: fetchLimit + 1,
|
||||||
untilId: (this.$refs.timeline as any).tail().id,
|
untilId: (this.$refs.timeline as any).tail().id,
|
||||||
includeMyRenotes: (this as any).os.i.clientSettings.showMyRenotes,
|
includeMyRenotes: (this as any).clientSettings.showMyRenotes,
|
||||||
includeRenotedMyNotes: (this as any).os.i.clientSettings.showRenotedMyNotes
|
includeRenotedMyNotes: (this as any).clientSettings.showRenotedMyNotes
|
||||||
}).then(notes => {
|
}).then(notes => {
|
||||||
if (notes.length == fetchLimit + 1) {
|
if (notes.length == fetchLimit + 1) {
|
||||||
notes.pop();
|
notes.pop();
|
||||||
|
|
|
@ -22,9 +22,7 @@
|
||||||
<mk-welcome-timeline/>
|
<mk-welcome-timeline/>
|
||||||
</div>
|
</div>
|
||||||
<div class="users">
|
<div class="users">
|
||||||
<router-link v-for="user in users" :key="user.id" class="avatar-anchor" :to="`/@${user.username}`">
|
<mk-avatar class="avatar" :key="user.id" :user="user"/>
|
||||||
<img class="avatar" :src="`${user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
|
|
||||||
</router-link>
|
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
<footer>
|
||||||
<small>{{ copyright }}</small>
|
<small>{{ copyright }}</small>
|
||||||
|
|
|
@ -21,6 +21,7 @@ export default define({
|
||||||
methods: {
|
methods: {
|
||||||
func() {
|
func() {
|
||||||
this.props.compact = !this.props.compact;
|
this.props.compact = !this.props.compact;
|
||||||
|
this.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
90
src/client/app/store.ts
Normal file
90
src/client/app/store.ts
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
import Vuex from 'vuex';
|
||||||
|
import MiOS from './common/mios';
|
||||||
|
|
||||||
|
const defaultSettings = {
|
||||||
|
home: [],
|
||||||
|
fetchOnScroll: true,
|
||||||
|
showMaps: true,
|
||||||
|
showPostFormOnTopOfTl: false,
|
||||||
|
circleIcons: true,
|
||||||
|
gradientWindowHeader: false,
|
||||||
|
showReplyTarget: true,
|
||||||
|
showMyRenotes: true,
|
||||||
|
showRenotedMyNotes: true
|
||||||
|
};
|
||||||
|
|
||||||
|
export default (os: MiOS) => new Vuex.Store({
|
||||||
|
plugins: [store => {
|
||||||
|
store.subscribe((mutation, state) => {
|
||||||
|
if (mutation.type.startsWith('settings/')) {
|
||||||
|
localStorage.setItem('settings', JSON.stringify(state.settings.data));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}],
|
||||||
|
|
||||||
|
state: {
|
||||||
|
uiHeaderHeight: 0
|
||||||
|
},
|
||||||
|
|
||||||
|
mutations: {
|
||||||
|
setUiHeaderHeight(state, height) {
|
||||||
|
state.uiHeaderHeight = height;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
modules: {
|
||||||
|
settings: {
|
||||||
|
namespaced: true,
|
||||||
|
|
||||||
|
state: {
|
||||||
|
data: defaultSettings
|
||||||
|
},
|
||||||
|
|
||||||
|
mutations: {
|
||||||
|
init(state, settings) {
|
||||||
|
state.data = settings;
|
||||||
|
},
|
||||||
|
|
||||||
|
set(state, x: { key: string; value: any }) {
|
||||||
|
state.data[x.key] = x.value;
|
||||||
|
},
|
||||||
|
|
||||||
|
setHome(state, data) {
|
||||||
|
state.data.home = data;
|
||||||
|
},
|
||||||
|
|
||||||
|
setHomeWidget(state, x) {
|
||||||
|
const w = state.data.home.find(w => w.id == x.id);
|
||||||
|
if (w) {
|
||||||
|
w.data = x.data;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
addHomeWidget(state, widget) {
|
||||||
|
state.data.home.unshift(widget);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
set(ctx, x) {
|
||||||
|
ctx.commit('set', x);
|
||||||
|
|
||||||
|
if (os.isSignedIn) {
|
||||||
|
os.api('i/update_client_setting', {
|
||||||
|
name: x.key,
|
||||||
|
value: x.value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
addHomeWidget(ctx, widget) {
|
||||||
|
ctx.commit('addHomeWidget', widget);
|
||||||
|
|
||||||
|
os.api('i/update_home', {
|
||||||
|
home: ctx.state.data.home
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -24,16 +24,11 @@ module.exports = async (params, user) => new Promise(async (res, rej) => {
|
||||||
$set: x
|
$set: x
|
||||||
});
|
});
|
||||||
|
|
||||||
// Serialize
|
res();
|
||||||
user.clientSettings[name] = value;
|
|
||||||
const iObj = await pack(user, user, {
|
// Publish event
|
||||||
detail: true,
|
event(user._id, 'clientSettingUpdated', {
|
||||||
includeSecrets: true
|
key: name,
|
||||||
|
value
|
||||||
});
|
});
|
||||||
|
|
||||||
// Send response
|
|
||||||
res(iObj);
|
|
||||||
|
|
||||||
// Publish i updated event
|
|
||||||
event(user._id, 'i_updated', iObj);
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -26,9 +26,9 @@ if (process.env.NODE_ENV != 'production') {
|
||||||
app.use(logger());
|
app.use(logger());
|
||||||
|
|
||||||
// Delay
|
// Delay
|
||||||
app.use(slow({
|
//app.use(slow({
|
||||||
delay: 1000
|
// delay: 1000
|
||||||
}));
|
//}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compress response
|
// Compress response
|
||||||
|
|
Loading…
Reference in a new issue