MisskeyPagesをホームUIに統合

This commit is contained in:
syuilo 2019-05-24 19:19:43 +09:00
parent 358bb0fc06
commit 36c2d0082f
No known key found for this signature in database
GPG key ID: BDC4C49D06AB9D69
26 changed files with 58 additions and 241 deletions

View file

@ -8,7 +8,7 @@ import { concat, sum } from '../../../../../prelude/array';
import MkFormula from './formula.vue'; import MkFormula from './formula.vue';
import MkCode from './code.vue'; import MkCode from './code.vue';
import MkGoogle from './google.vue'; import MkGoogle from './google.vue';
import { host } from '../../../config'; import { host, url } from '../../../config';
import { preorderF, countNodesF } from '../../../../../prelude/tree'; import { preorderF, countNodesF } from '../../../../../prelude/tree';
function sumTextsLength(ts: MfmForest): number { function sumTextsLength(ts: MfmForest): number {
@ -175,7 +175,9 @@ export default Vue.component('misskey-flavored-markdown', {
props: { props: {
url: token.node.props.url, url: token.node.props.url,
rel: 'nofollow noopener', rel: 'nofollow noopener',
target: '_blank' ...(token.node.props.url.startsWith(url) ? {} : {
target: '_blank'
})
}, },
attrs: { attrs: {
style: 'color:var(--mfmUrl);' style: 'color:var(--mfmUrl);'

View file

@ -9,7 +9,7 @@
</blockquote> </blockquote>
</div> </div>
<div v-else class="mk-url-preview"> <div v-else class="mk-url-preview">
<a :class="{ mini: narrow, compact }" :href="url" rel="nofollow noopener" target="_blank" :title="url" v-if="!fetching"> <component :is="self ? 'router-link' : 'a'" :class="{ mini: narrow, compact }" :[attr]="self ? url.substr(local.length) : url" rel="nofollow noopener" :target="self ? null : '_blank'" :title="url" v-if="!fetching">
<div class="thumbnail" v-if="thumbnail" :style="`background-image: url('${thumbnail}')`"> <div class="thumbnail" v-if="thumbnail" :style="`background-image: url('${thumbnail}')`">
<button v-if="!playerEnabled && player.url" @click.prevent="playerEnabled = true" :title="$t('enable-player')"><fa :icon="['far', 'play-circle']"/></button> <button v-if="!playerEnabled && player.url" @click.prevent="playerEnabled = true" :title="$t('enable-player')"><fa :icon="['far', 'play-circle']"/></button>
</div> </div>
@ -23,17 +23,18 @@
<p :title="sitename">{{ sitename }}</p> <p :title="sitename">{{ sitename }}</p>
</footer> </footer>
</article> </article>
</a> </component>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import Vue from 'vue'; import Vue from 'vue';
import i18n from '../../../i18n'; import i18n from '../../../i18n';
import { url as misskeyUrl } from '../../../config'; import { url as local } from '../../../config';
export default Vue.extend({ export default Vue.extend({
i18n: i18n('common/views/components/url-preview.vue'), i18n: i18n('common/views/components/url-preview.vue'),
props: { props: {
url: { url: {
type: String, type: String,
@ -74,7 +75,9 @@ export default Vue.extend({
}, },
tweetUrl: null, tweetUrl: null,
playerEnabled: false, playerEnabled: false,
misskeyUrl, local,
self: this.url.startsWith(local),
attr: this.url.startsWith(local) ? 'to' : 'href'
}; };
}, },

View file

@ -1,29 +1,33 @@
<template> <template>
<a class="mk-url" :href="url" :rel="rel" :target="target"> <component :is="self ? 'router-link' : 'a'" class="mk-url" :[attr]="self ? url.substr(local.length) : url" :rel="rel" :target="target">
<span class="schema">{{ schema }}//</span> <span class="schema">{{ schema }}//</span>
<span class="hostname">{{ hostname }}</span> <span class="hostname">{{ hostname }}</span>
<span class="port" v-if="port != ''">:{{ port }}</span> <span class="port" v-if="port != ''">:{{ port }}</span>
<span class="pathname" v-if="pathname != ''">{{ pathname }}</span> <span class="pathname" v-if="pathname != ''">{{ pathname }}</span>
<span class="query">{{ query }}</span> <span class="query">{{ query }}</span>
<span class="hash">{{ hash }}</span> <span class="hash">{{ hash }}</span>
<fa icon="external-link-square-alt"/> <fa icon="external-link-square-alt" v-if="!self"/>
</a> </component>
</template> </template>
<script lang="ts"> <script lang="ts">
import Vue from 'vue'; import Vue from 'vue';
import { toUnicode as decodePunycode } from 'punycode'; import { toUnicode as decodePunycode } from 'punycode';
import { url as local } from '../../../config';
export default Vue.extend({ export default Vue.extend({
props: ['url', 'rel', 'target'], props: ['url', 'rel', 'target'],
data() { data() {
return { return {
local,
schema: null, schema: null,
hostname: null, hostname: null,
port: null, port: null,
pathname: null, pathname: null,
query: null, query: null,
hash: null hash: null,
self: this.url.startsWith(local),
attr: this.url.startsWith(local) ? 'to' : 'href'
}; };
}, },
created() { created() {

View file

@ -19,7 +19,7 @@ import { faPencilAlt } from '@fortawesome/free-solid-svg-icons';
import { faImage, faFolderOpen } from '@fortawesome/free-regular-svg-icons'; import { faImage, faFolderOpen } from '@fortawesome/free-regular-svg-icons';
import i18n from '../../../../../i18n'; import i18n from '../../../../../i18n';
import XContainer from '../page-editor.container.vue'; import XContainer from '../page-editor.container.vue';
import XFileThumbnail from '../../drive-file-thumbnail.vue'; import XFileThumbnail from '../../../components/drive-file-thumbnail.vue';
export default Vue.extend({ export default Vue.extend({
i18n: i18n('pages'), i18n: i18n('pages'),

View file

@ -11,7 +11,7 @@
</header> </header>
<section> <section>
<a class="view" v-if="pageId" :href="`/@${ author.username }/pages/${ currentName }`"><fa :icon="faExternalLinkSquareAlt"/> {{ $t('view-page') }}</a> <router-link class="view" v-if="pageId" :to="`/@${ author.username }/pages/${ currentName }`"><fa :icon="faExternalLinkSquareAlt"/> {{ $t('view-page') }}</router-link>
<ui-input v-model="title"> <ui-input v-model="title">
<span>{{ $t('title') }}</span> <span>{{ $t('title') }}</span>
@ -111,20 +111,25 @@ export default Vue.extend({
}, },
props: { props: {
page: { initPageId: {
type: Object, type: String,
required: false required: false
}, },
readonly: { initPageName: {
type: Boolean, type: String,
required: false, required: false
default: false },
initUser: {
type: String,
required: false
}, },
}, },
data() { data() {
return { return {
author: this.$store.state.i, author: this.$store.state.i,
readonly: false,
page: null,
pageId: null, pageId: null,
currentName: null, currentName: null,
title: '', title: '',
@ -156,7 +161,7 @@ export default Vue.extend({
}, },
}, },
created() { async created() {
this.aiScript = new ASTypeChecker(); this.aiScript = new ASTypeChecker();
this.$watch('variables', () => { this.$watch('variables', () => {
@ -167,6 +172,18 @@ export default Vue.extend({
this.aiScript.pageVars = collectPageVars(this.content); this.aiScript.pageVars = collectPageVars(this.content);
}, { deep: true }); }, { deep: true });
if (this.initPageId) {
this.page = await this.$root.api('pages/show', {
pageId: this.initPageId,
});
} else if (this.initPageName && this.initUser) {
this.page = await this.$root.api('pages/show', {
name: this.initPageName,
username: this.initUser,
});
this.readonly = true;
}
if (this.page) { if (this.page) {
this.author = this.page.user; this.author = this.page.user;
this.pageId = this.page.id; this.pageId = this.page.id;

View file

@ -148,8 +148,8 @@ export default Vue.extend({
> .title > .title
z-index 1 z-index 1
margin 0 margin 0
padding 32px 64px padding 16px 32px
font-size 24px font-size 20px
font-weight bold font-weight bold
color var(--text) color var(--text)
box-shadow 0 var(--lineWidth) rgba(#000, 0.07) box-shadow 0 var(--lineWidth) rgba(#000, 0.07)
@ -160,8 +160,8 @@ export default Vue.extend({
> div > div
color var(--text) color var(--text)
padding 48px 64px padding 24px 32px
font-size 18px font-size 16px
@media (max-width 600px) @media (max-width 600px)
padding 24px 32px padding 24px 32px
@ -169,7 +169,7 @@ export default Vue.extend({
> footer > footer
color var(--text) color var(--text)
padding 0 64px 38px 64px padding 0 32px 28px 32px
@media (max-width 600px) @media (max-width 600px)
padding 0 32px 28px 32px padding 0 32px 28px 32px

View file

@ -168,11 +168,11 @@ init(async (launch, os) => {
{ path: '/i/groups', component: () => import('../common/views/pages/user-groups.vue').then(m => m.default) }, { path: '/i/groups', component: () => import('../common/views/pages/user-groups.vue').then(m => m.default) },
{ path: '/i/groups/:groupId', props: true, component: () => import('../common/views/pages/user-group-editor.vue').then(m => m.default) }, { path: '/i/groups/:groupId', props: true, component: () => import('../common/views/pages/user-group-editor.vue').then(m => m.default) },
{ path: '/i/follow-requests', component: () => import('../common/views/pages/follow-requests.vue').then(m => m.default) }, { path: '/i/follow-requests', component: () => import('../common/views/pages/follow-requests.vue').then(m => m.default) },
{ path: '/i/pages/new', component: () => import('../common/views/pages/page-editor/page-editor.vue').then(m => m.default) },
{ path: '/i/pages/edit/:pageId', component: () => import('../common/views/pages/page-editor/page-editor.vue').then(m => m.default), props: route => ({ initPageId: route.params.pageId }) },
{ path: '/@:user/pages/:page', component: () => import('../common/views/pages/page/page.vue').then(m => m.default), props: route => ({ pageName: route.params.page, username: route.params.user }) },
{ path: '/@:user/pages/:pageName/view-source', component: () => import('../common/views/pages/page-editor/page-editor.vue').then(m => m.default), props: route => ({ initUser: route.params.user, initPageName: route.params.pageName }) },
]}, ]},
{ path: '/@:user/pages/:page', props: true, component: () => import('./views/pages/page.vue').then(m => m.default) },
{ path: '/@:user/pages/:pageName/view-source', props: true, component: () => import('./views/pages/page-editor.vue').then(m => m.default) },
{ path: '/i/pages/new', component: () => import('./views/pages/page-editor.vue').then(m => m.default) },
{ path: '/i/pages/edit/:pageId', props: true, component: () => import('./views/pages/page-editor.vue').then(m => m.default) },
{ path: '/i/messaging/group/:group', component: MkMessagingRoom }, { path: '/i/messaging/group/:group', component: MkMessagingRoom },
{ path: '/i/messaging/:user', component: MkMessagingRoom }, { path: '/i/messaging/:user', component: MkMessagingRoom },
{ path: '/i/drive', component: MkDrive }, { path: '/i/drive', component: MkDrive },

View file

@ -1,67 +0,0 @@
<template>
<mk-ui>
<main>
<x-page-editor v-if="page !== undefined" :page="page" :readonly="readonly"/>
</main>
</mk-ui>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
components: {
XPageEditor: () => import('../../../common/views/components/page-editor/page-editor.vue').then(m => m.default)
},
props: {
pageId: {
type: String,
required: false
},
pageName: {
type: String,
required: false
},
user: {
type: String,
required: false
}
},
data() {
return {
page: undefined,
readonly: false
};
},
created() {
if (this.pageId) {
this.$root.api('pages/show', {
pageId: this.pageId,
}).then(page => {
this.page = page;
});
} else if (this.pageName && this.user) {
this.$root.api('pages/show', {
name: this.pageName,
username: this.user,
}).then(page => {
this.readonly = true;
this.page = page;
});
} else {
this.page = null;
}
}
});
</script>
<style lang="stylus" scoped>
main
margin 0 auto
padding 16px
max-width 900px
</style>

View file

@ -1,36 +0,0 @@
<template>
<mk-ui>
<main>
<x-page :page-name="page" :username="user"/>
</main>
</mk-ui>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
components: {
XPage: () => import('../../../common/views/pages/page/page.vue').then(m => m.default)
},
props: {
page: {
type: String,
required: true
},
user: {
type: String,
required: true
},
}
});
</script>
<style lang="stylus" scoped>
main
margin 0 auto
padding 16px
max-width 950px
</style>

View file

@ -149,8 +149,8 @@ init((launch, os) => {
{ path: '/i/drive', name: 'drive', component: MkDrive }, { path: '/i/drive', name: 'drive', component: MkDrive },
{ path: '/i/drive/folder/:folder', component: MkDrive }, { path: '/i/drive/folder/:folder', component: MkDrive },
{ path: '/i/drive/file/:file', component: MkDrive }, { path: '/i/drive/file/:file', component: MkDrive },
{ path: '/i/pages/new', component: () => import('./views/pages/page-editor.vue').then(m => m.default) }, { path: '/i/pages/new', component: UI, props: route => ({ component: () => import('../common/views/pages/page-editor/page-editor.vue').then(m => m.default) }) },
{ path: '/i/pages/edit/:pageId', props: true, component: () => import('./views/pages/page-editor.vue').then(m => m.default) }, { path: '/i/pages/edit/:pageId', component: UI, props: route => ({ component: () => import('../common/views/pages/page-editor/page-editor.vue').then(m => m.default), initPageId: route.params.pageId }) },
{ path: '/selectdrive', component: MkSelectDrive }, { path: '/selectdrive', component: MkSelectDrive },
{ path: '/search', component: MkSearch }, { path: '/search', component: MkSearch },
{ path: '/tags/:tag', component: MkTag }, { path: '/tags/:tag', component: MkTag },
@ -163,8 +163,8 @@ init((launch, os) => {
{ path: 'following', component: () => import('../common/views/pages/following.vue').then(m => m.default) }, { path: 'following', component: () => import('../common/views/pages/following.vue').then(m => m.default) },
{ path: 'followers', component: () => import('../common/views/pages/followers.vue').then(m => m.default) }, { path: 'followers', component: () => import('../common/views/pages/followers.vue').then(m => m.default) },
]}, ]},
{ path: '/@:user/pages/:page', props: true, component: () => import('./views/pages/page.vue').then(m => m.default) }, { path: '/@:user/pages/:page', component: UI, props: route => ({ component: () => import('../common/views/pages/page/page.vue').then(m => m.default), pageName: route.params.page, username: route.params.user }) },
{ path: '/@:user/pages/:pageName/view-source', props: true, component: () => import('./views/pages/page-editor.vue').then(m => m.default) }, { path: '/@:user/pages/:pageName/view-source', component: UI, props: route => ({ component: () => import('../common/views/pages/page-editor/page-editor.vue').then(m => m.default), initUser: route.params.user, initPageName: route.params.pageName }) },
{ path: '/notes/:note', component: MkNote }, { path: '/notes/:note', component: MkNote },
{ path: '/authorize-follow', component: MkFollow }, { path: '/authorize-follow', component: MkFollow },
{ path: '*', component: MkNotFound } { path: '*', component: MkNotFound }

View file

@ -1,67 +0,0 @@
<template>
<mk-ui>
<main>
<x-page-editor v-if="page !== undefined" :page="page" :readonly="readonly"/>
</main>
</mk-ui>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
components: {
XPageEditor: () => import('../../../common/views/components/page-editor/page-editor.vue').then(m => m.default)
},
props: {
pageId: {
type: String,
required: false
},
pageName: {
type: String,
required: false
},
user: {
type: String,
required: false
}
},
data() {
return {
page: undefined,
readonly: false
};
},
created() {
if (this.pageId) {
this.$root.api('pages/show', {
pageId: this.pageId,
}).then(page => {
this.page = page;
});
} else if (this.pageName && this.user) {
this.$root.api('pages/show', {
name: this.pageName,
username: this.user,
}).then(page => {
this.readonly = true;
this.page = page;
});
} else {
this.page = null;
}
}
});
</script>
<style lang="stylus" scoped>
main
margin 0 auto
padding 16px
max-width 1000px
</style>

View file

@ -1,39 +0,0 @@
<template>
<mk-ui>
<main>
<x-page :page-name="page" :username="user"/>
</main>
</mk-ui>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
components: {
XPage: () => import('../../../common/views/pages/page/page.vue').then(m => m.default)
},
props: {
page: {
type: String,
required: true
},
user: {
type: String,
required: true
},
}
});
</script>
<style lang="stylus" scoped>
main
margin 0 auto
padding 16px
max-width 1000px
@media (min-width 600px)
padding 32px
</style>