forked from FoundKeyGang/FoundKey
wip
This commit is contained in:
parent
3cc45145fe
commit
e1259409e9
16 changed files with 89 additions and 61 deletions
|
@ -5,6 +5,7 @@ declare const _DOCS_URL_: string;
|
||||||
declare const _STATS_URL_: string;
|
declare const _STATS_URL_: string;
|
||||||
declare const _STATUS_URL_: string;
|
declare const _STATUS_URL_: string;
|
||||||
declare const _DEV_URL_: string;
|
declare const _DEV_URL_: string;
|
||||||
|
declare const _CH_URL_: string;
|
||||||
declare const _LANG_: string;
|
declare const _LANG_: string;
|
||||||
declare const _RECAPTCHA_SITEKEY_: string;
|
declare const _RECAPTCHA_SITEKEY_: string;
|
||||||
declare const _SW_PUBLICKEY_: string;
|
declare const _SW_PUBLICKEY_: string;
|
||||||
|
@ -19,6 +20,7 @@ export const docsUrl = _DOCS_URL_;
|
||||||
export const statsUrl = _STATS_URL_;
|
export const statsUrl = _STATS_URL_;
|
||||||
export const statusUrl = _STATUS_URL_;
|
export const statusUrl = _STATUS_URL_;
|
||||||
export const devUrl = _DEV_URL_;
|
export const devUrl = _DEV_URL_;
|
||||||
|
export const chUrl = _CH_URL_;
|
||||||
export const lang = _LANG_;
|
export const lang = _LANG_;
|
||||||
export const recaptchaSitekey = _RECAPTCHA_SITEKEY_;
|
export const recaptchaSitekey = _RECAPTCHA_SITEKEY_;
|
||||||
export const swPublickey = _SW_PUBLICKEY_;
|
export const swPublickey = _SW_PUBLICKEY_;
|
||||||
|
|
6
src/web/app/desktop/api/post.ts
Normal file
6
src/web/app/desktop/api/post.ts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import PostFormWindow from '../views/components/post-form-window.vue';
|
||||||
|
|
||||||
|
export default function() {
|
||||||
|
const vm = new PostFormWindow().$mount();
|
||||||
|
document.body.appendChild(vm.$el);
|
||||||
|
}
|
|
@ -14,6 +14,7 @@ import chooseDriveFolder from './api/choose-drive-folder';
|
||||||
import chooseDriveFile from './api/choose-drive-file';
|
import chooseDriveFile from './api/choose-drive-file';
|
||||||
import dialog from './api/dialog';
|
import dialog from './api/dialog';
|
||||||
import input from './api/input';
|
import input from './api/input';
|
||||||
|
import post from './api/post';
|
||||||
|
|
||||||
import MkIndex from './views/pages/index.vue';
|
import MkIndex from './views/pages/index.vue';
|
||||||
import MkUser from './views/pages/user/user.vue';
|
import MkUser from './views/pages/user/user.vue';
|
||||||
|
@ -37,7 +38,8 @@ init(async (launch) => {
|
||||||
chooseDriveFolder,
|
chooseDriveFolder,
|
||||||
chooseDriveFile,
|
chooseDriveFile,
|
||||||
dialog,
|
dialog,
|
||||||
input
|
input,
|
||||||
|
post
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,13 +1,6 @@
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
|
||||||
import ui from './ui.vue';
|
import ui from './ui.vue';
|
||||||
import uiHeader from './ui-header.vue';
|
|
||||||
import uiHeaderAccount from './ui-header-account.vue';
|
|
||||||
import uiHeaderClock from './ui-header-clock.vue';
|
|
||||||
import uiHeaderNav from './ui-header-nav.vue';
|
|
||||||
import uiHeaderNotifications from './ui-header-notifications.vue';
|
|
||||||
import uiHeaderPostButton from './ui-header-post-button.vue';
|
|
||||||
import uiHeaderSearch from './ui-header-search.vue';
|
|
||||||
import uiNotification from './ui-notification.vue';
|
import uiNotification from './ui-notification.vue';
|
||||||
import home from './home.vue';
|
import home from './home.vue';
|
||||||
import timeline from './timeline.vue';
|
import timeline from './timeline.vue';
|
||||||
|
@ -46,13 +39,6 @@ import wBroadcast from './widgets/broadcast.vue';
|
||||||
import wTimemachine from './widgets/timemachine.vue';
|
import wTimemachine from './widgets/timemachine.vue';
|
||||||
|
|
||||||
Vue.component('mk-ui', ui);
|
Vue.component('mk-ui', ui);
|
||||||
Vue.component('mk-ui-header', uiHeader);
|
|
||||||
Vue.component('mk-ui-header-account', uiHeaderAccount);
|
|
||||||
Vue.component('mk-ui-header-clock', uiHeaderClock);
|
|
||||||
Vue.component('mk-ui-header-nav', uiHeaderNav);
|
|
||||||
Vue.component('mk-ui-header-notifications', uiHeaderNotifications);
|
|
||||||
Vue.component('mk-ui-header-post-button', uiHeaderPostButton);
|
|
||||||
Vue.component('mk-ui-header-search', uiHeaderSearch);
|
|
||||||
Vue.component('mk-ui-notification', uiNotification);
|
Vue.component('mk-ui-notification', uiNotification);
|
||||||
Vue.component('mk-home', home);
|
Vue.component('mk-home', home);
|
||||||
Vue.component('mk-timeline', timeline);
|
Vue.component('mk-timeline', timeline);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="mk-ui-header-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.avatar_url }?thumbnail&size=64`" alt="avatar"/>
|
<img class="avatar" :src="`${ os.i.avatar_url }?thumbnail&size=64`" alt="avatar"/>
|
||||||
|
@ -81,7 +81,7 @@ export default Vue.extend({
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
.mk-ui-header-account
|
.account
|
||||||
> .header
|
> .header
|
||||||
display block
|
display block
|
||||||
margin 0
|
margin 0
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="mk-ui-header-clock">
|
<div class="clock">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<time ref="time">
|
<time ref="time">
|
||||||
<span class="yyyymmdd">{{ yyyy }}/{{ mm }}/{{ dd }}</span>
|
<span class="yyyymmdd">{{ yyyy }}/{{ mm }}/{{ dd }}</span>
|
||||||
|
@ -56,7 +56,7 @@ export default Vue.extend({
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
.mk-ui-header-clock
|
.clock
|
||||||
display inline-block
|
display inline-block
|
||||||
overflow visible
|
overflow visible
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="mk-ui-header-nav">
|
<div class="nav">
|
||||||
<ul>
|
<ul>
|
||||||
<template v-if="os.isSignedIn">
|
<template v-if="os.isSignedIn">
|
||||||
<li class="home" :class="{ active: page == 'home' }">
|
<li class="home" :class="{ active: page == 'home' }">
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
<li class="ch">
|
<li class="ch">
|
||||||
<a :href="_CH_URL_" target="_blank">
|
<a :href="chUrl" target="_blank">
|
||||||
%fa:tv%
|
%fa:tv%
|
||||||
<p>%i18n:desktop.tags.mk-ui-header-nav.ch%</p>
|
<p>%i18n:desktop.tags.mk-ui-header-nav.ch%</p>
|
||||||
</a>
|
</a>
|
||||||
|
@ -34,6 +34,7 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
import { chUrl } from '../../../config';
|
||||||
import MkMessagingWindow from './messaging-window.vue';
|
import MkMessagingWindow from './messaging-window.vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
|
@ -41,7 +42,8 @@ export default Vue.extend({
|
||||||
return {
|
return {
|
||||||
hasUnreadMessagingMessages: false,
|
hasUnreadMessagingMessages: false,
|
||||||
connection: null,
|
connection: null,
|
||||||
connectionId: null
|
connectionId: null,
|
||||||
|
chUrl
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -84,7 +86,7 @@ export default Vue.extend({
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
.mk-ui-header-nav
|
.nav
|
||||||
display inline-block
|
display inline-block
|
||||||
margin 0
|
margin 0
|
||||||
padding 0
|
padding 0
|
|
@ -1,9 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="mk-ui-header-notifications">
|
<div class="notifications">
|
||||||
<button :data-active="isOpen" @click="toggle" title="%i18n:desktop.tags.mk-ui-header-notifications.title%">
|
<button :data-active="isOpen" @click="toggle" title="%i18n:desktop.tags.mk-ui-header-notifications.title%">
|
||||||
%fa:R bell%<template v-if="hasUnreadNotifications">%fa:circle%</template>
|
%fa:R bell%<template v-if="hasUnreadNotifications">%fa:circle%</template>
|
||||||
</button>
|
</button>
|
||||||
<div class="notifications" v-if="isOpen">
|
<div class="pop" v-if="isOpen">
|
||||||
<mk-notifications/>
|
<mk-notifications/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -82,7 +82,7 @@ export default Vue.extend({
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
.mk-ui-header-notifications
|
.notifications
|
||||||
|
|
||||||
> button
|
> button
|
||||||
display block
|
display block
|
||||||
|
@ -114,7 +114,7 @@ export default Vue.extend({
|
||||||
font-size 10px
|
font-size 10px
|
||||||
color $theme-color
|
color $theme-color
|
||||||
|
|
||||||
> .notifications
|
> .pop
|
||||||
display block
|
display block
|
||||||
position absolute
|
position absolute
|
||||||
top 56px
|
top 56px
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="mk-ui-header-post-button">
|
<div class="post">
|
||||||
<button @click="post" title="%i18n:desktop.tags.mk-ui-header-post-button.post%">%fa:pencil-alt%</button>
|
<button @click="post" title="%i18n:desktop.tags.mk-ui-header-post-button.post%">%fa:pencil-alt%</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -17,7 +17,7 @@ export default Vue.extend({
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
.mk-ui-header-post-button
|
.post
|
||||||
display inline-block
|
display inline-block
|
||||||
padding 8px
|
padding 8px
|
||||||
height 100%
|
height 100%
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<form class="mk-ui-header-search" @submit.prevent="onSubmit">
|
<form class="search" @submit.prevent="onSubmit">
|
||||||
%fa:search%
|
%fa:search%
|
||||||
<input v-model="q" type="search" placeholder="%i18n:desktop.tags.mk-ui-header-search.placeholder%"/>
|
<input v-model="q" type="search" placeholder="%i18n:desktop.tags.mk-ui-header-search.placeholder%"/>
|
||||||
<div class="result"></div>
|
<div class="result"></div>
|
||||||
|
@ -24,7 +24,7 @@ export default Vue.extend({
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
.mk-ui-header-search
|
.search
|
||||||
|
|
||||||
> [data-fa]
|
> [data-fa]
|
||||||
display block
|
display block
|
|
@ -1,19 +1,19 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="mk-ui-header">
|
<div class="header">
|
||||||
<mk-special-message/>
|
<mk-special-message/>
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<div class="backdrop"></div>
|
<div class="backdrop"></div>
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<mk-ui-header-nav/>
|
<x-nav/>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<mk-ui-header-search/>
|
<x-search/>
|
||||||
<mk-ui-header-account v-if="os.isSignedIn"/>
|
<x-account v-if="os.isSignedIn"/>
|
||||||
<mk-ui-header-notifications v-if="os.isSignedIn"/>
|
<x-notifications v-if="os.isSignedIn"/>
|
||||||
<mk-ui-header-post-button v-if="os.isSignedIn"/>
|
<x-post v-if="os.isSignedIn"/>
|
||||||
<mk-ui-header-clock/>
|
<x-clock/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -21,9 +21,30 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
|
||||||
|
import XNav from './ui.header.nav.vue';
|
||||||
|
import XSearch from './ui.header.search.vue';
|
||||||
|
import XAccount from './ui.header.account.vue';
|
||||||
|
import XNotifications from './ui.header.notifications.vue';
|
||||||
|
import XPost from './ui.header.post.vue';
|
||||||
|
import XClock from './ui.header.clock.vue';
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
components: {
|
||||||
|
'x-nav': XNav,
|
||||||
|
'x-search': XSearch,
|
||||||
|
'x-account': XAccount,
|
||||||
|
'x-notifications': XNotifications,
|
||||||
|
'x-post': XPost,
|
||||||
|
'x-clock': XClock,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
.mk-ui-header
|
.header
|
||||||
display block
|
|
||||||
position -webkit-sticky
|
position -webkit-sticky
|
||||||
position sticky
|
position sticky
|
||||||
top 0
|
top 0
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<mk-ui-header/>
|
<x-header/>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
|
@ -10,9 +10,12 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import MkPostFormWindow from './post-form-window.vue';
|
import XHeader from './ui.header.vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
|
components: {
|
||||||
|
'x-header': XHeader
|
||||||
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
document.addEventListener('keydown', this.onKeydown);
|
document.addEventListener('keydown', this.onKeydown);
|
||||||
},
|
},
|
||||||
|
@ -20,17 +23,12 @@ export default Vue.extend({
|
||||||
document.removeEventListener('keydown', this.onKeydown);
|
document.removeEventListener('keydown', this.onKeydown);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
openPostForm() {
|
|
||||||
document.body.appendChild(new MkPostFormWindow({
|
|
||||||
parent: this
|
|
||||||
}).$mount().$el);
|
|
||||||
},
|
|
||||||
onKeydown(e) {
|
onKeydown(e) {
|
||||||
if (e.target.tagName == 'INPUT' || e.target.tagName == 'TEXTAREA') return;
|
if (e.target.tagName == 'INPUT' || e.target.tagName == 'TEXTAREA') return;
|
||||||
|
|
||||||
if (e.which == 80 || e.which == 78) { // p or n
|
if (e.which == 80 || e.which == 78) { // p or n
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.openPostForm();
|
(this as any).apis.post();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<p class="title">%fa:users%%i18n:desktop.tags.mk-user.followers-you-know.title%</p>
|
<p class="title">%fa:users%%i18n:desktop.tags.mk-user.followers-you-know.title%</p>
|
||||||
<p class="initializing" v-if="fetching">%fa:spinner .pulse .fw%%i18n:desktop.tags.mk-user.followers-you-know.loading%<mk-ellipsis/></p>
|
<p class="initializing" v-if="fetching">%fa:spinner .pulse .fw%%i18n:desktop.tags.mk-user.followers-you-know.loading%<mk-ellipsis/></p>
|
||||||
<div v-if="!fetching && users.length > 0">
|
<div v-if="!fetching && users.length > 0">
|
||||||
<router-link v-for="user in users" to="`/${user.username}`" :key="user.id">
|
<router-link v-for="user in users" :to="`/${user.username}`" :key="user.id">
|
||||||
<img :src="`${user.avatar_url}?thumbnail&size=64`" :alt="user.name" v-user-preview="user.id"/>
|
<img :src="`${user.avatar_url}?thumbnail&size=64`" :alt="user.name" v-user-preview="user.id"/>
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,11 +4,11 @@
|
||||||
<p class="initializing" v-if="fetching">%fa:spinner .pulse .fw%%i18n:desktop.tags.mk-user.frequently-replied-users.loading%<mk-ellipsis/></p>
|
<p class="initializing" v-if="fetching">%fa:spinner .pulse .fw%%i18n:desktop.tags.mk-user.frequently-replied-users.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.username}`">
|
<router-link class="avatar-anchor" :to="`/${friend.username}`">
|
||||||
<img class="avatar" :src="`${friend.avatar_url}?thumbnail&size=42`" alt="" v-user-preview="friend.id"/>
|
<img class="avatar" :src="`${friend.avatar_url}?thumbnail&size=42`" alt="" v-user-preview="friend.id"/>
|
||||||
</router-link>
|
</router-link>
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<router-link class="name" to="`/${friend.username}`" v-user-preview="friend.id">{{ friend.name }}</router-link>
|
<router-link class="name" :to="`/${friend.username}`" v-user-preview="friend.id">{{ friend.name }}</router-link>
|
||||||
<p class="username">@{{ friend.username }}</p>
|
<p class="username">@{{ friend.username }}</p>
|
||||||
</div>
|
</div>
|
||||||
<mk-follow-button :user="friend"/>
|
<mk-follow-button :user="friend"/>
|
||||||
|
|
|
@ -30,16 +30,25 @@ export default Vue.extend({
|
||||||
user: null
|
user: null
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
created() {
|
||||||
Progress.start();
|
this.fetch();
|
||||||
(this as any).api('users/show', {
|
},
|
||||||
username: this.$route.params.user
|
watch: {
|
||||||
}).then(user => {
|
$route: 'fetch'
|
||||||
this.user = user;
|
},
|
||||||
this.fetching = false;
|
methods: {
|
||||||
Progress.done();
|
fetch() {
|
||||||
document.title = user.name + ' | Misskey';
|
this.fetching = true;
|
||||||
});
|
Progress.start();
|
||||||
|
(this as any).api('users/show', {
|
||||||
|
username: this.$route.params.user
|
||||||
|
}).then(user => {
|
||||||
|
this.user = user;
|
||||||
|
this.fetching = false;
|
||||||
|
Progress.done();
|
||||||
|
document.title = user.name + ' | Misskey';
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -105,6 +105,8 @@ type API = {
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
default?: string;
|
default?: string;
|
||||||
}) => Promise<string>;
|
}) => Promise<string>;
|
||||||
|
|
||||||
|
post: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
// MiOSを初期化してコールバックする
|
// MiOSを初期化してコールバックする
|
||||||
|
|
Loading…
Reference in a new issue