summaryrefslogtreecommitdiff
path: root/src/client/pages
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2020-03-28 19:52:41 +0900
committersyuilo <syuilotan@yahoo.co.jp>2020-03-28 19:52:41 +0900
commitf014a79f8dbb101a80d638d025a27bbb5ea02575 (patch)
treecc8af5c152e6470cddf1f34d083e2e0e222e7610 /src/client/pages
parentMerge branch 'develop' (diff)
parent12.27.0 (diff)
downloadmisskey-f014a79f8dbb101a80d638d025a27bbb5ea02575.tar.gz
misskey-f014a79f8dbb101a80d638d025a27bbb5ea02575.tar.bz2
misskey-f014a79f8dbb101a80d638d025a27bbb5ea02575.zip
Merge branch 'develop'
Diffstat (limited to 'src/client/pages')
-rw-r--r--src/client/pages/apps.vue101
-rwxr-xr-xsrc/client/pages/auth.vue8
-rw-r--r--src/client/pages/doc.vue25
-rw-r--r--src/client/pages/follow-requests.vue14
-rw-r--r--src/client/pages/messaging/index.vue14
-rw-r--r--src/client/pages/miauth.vue103
-rw-r--r--src/client/pages/my-settings/index.vue4
-rw-r--r--src/client/pages/preferences/theme.vue28
8 files changed, 258 insertions, 39 deletions
diff --git a/src/client/pages/apps.vue b/src/client/pages/apps.vue
new file mode 100644
index 0000000000..03c6707f95
--- /dev/null
+++ b/src/client/pages/apps.vue
@@ -0,0 +1,101 @@
+<template>
+<div>
+ <portal to="icon"><fa :icon="faPlug"/></portal>
+ <portal to="title">{{ $t('installedApps') }}</portal>
+
+ <mk-pagination :pagination="pagination" class="bfomjevm" ref="list">
+ <template #empty>
+ <div class="_fullinfo">
+ <img src="https://xn--931a.moe/assets/info.jpg" class="_ghost"/>
+ <div>{{ $t('nothing') }}</div>
+ </div>
+ </template>
+ <template #default="{items}">
+ <div class="token _panel" v-for="token in items" :key="token.id">
+ <img class="icon" :src="token.iconUrl" alt=""/>
+ <div class="body">
+ <div class="name">{{ token.name }}</div>
+ <div class="description">{{ token.description }}</div>
+ <div class="_keyValue">
+ <div>{{ $t('installedDate') }}:</div>
+ <div><mk-time :time="token.createdAt"/></div>
+ </div>
+ <div class="_keyValue">
+ <div>{{ $t('lastUsedDate') }}:</div>
+ <div><mk-time :time="token.lastUsedAt"/></div>
+ </div>
+ <div class="actions">
+ <button class="_button" @click="revoke(token)"><fa :icon="faTrashAlt"/></button>
+ </div>
+ </div>
+ </div>
+ </template>
+ </mk-pagination>
+</div>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+import { faTrashAlt, faPlug } from '@fortawesome/free-solid-svg-icons';
+import MkPagination from '../components/ui/pagination.vue';
+
+export default Vue.extend({
+ metaInfo() {
+ return {
+ title: this.$t('installedApps') as string
+ };
+ },
+
+ components: {
+ MkPagination
+ },
+
+ data() {
+ return {
+ pagination: {
+ endpoint: 'i/apps',
+ limit: 100,
+ params: {
+ sort: '+lastUsedAt'
+ }
+ },
+ faTrashAlt, faPlug
+ };
+ },
+
+ methods: {
+ revoke(token) {
+ this.$root.api('i/revoke-token', { tokenId: token.id }).then(() => {
+ this.$refs.list.reload();
+ });
+ }
+ }
+});
+</script>
+
+<style lang="scss" scoped>
+.bfomjevm {
+ > .token {
+ display: flex;
+ padding: 16px;
+
+ > .icon {
+ display: block;
+ flex-shrink: 0;
+ margin: 0 12px 0 0;
+ width: 50px;
+ height: 50px;
+ border-radius: 8px;
+ }
+
+ > .body {
+ width: calc(100% - 62px);
+ position: relative;
+
+ > .name {
+ font-weight: bold;
+ }
+ }
+ }
+}
+</style>
diff --git a/src/client/pages/auth.vue b/src/client/pages/auth.vue
index 9f5b45f001..e025924fe0 100755
--- a/src/client/pages/auth.vue
+++ b/src/client/pages/auth.vue
@@ -12,20 +12,18 @@
@accepted="accepted"
/>
<div class="denied _panel" v-if="state == 'denied'">
- <h1>{{ $t('denied') }}</h1>
- <p>{{ $t('denied-paragraph') }}</p>
+ <h1>{{ $t('_auth.denied') }}</h1>
</div>
<div class="accepted _panel" v-if="state == 'accepted'">
<h1>{{ session.app.isAuthorized ? this.$t('already-authorized') : this.$t('allowed') }}</h1>
- <p v-if="session.app.callbackUrl">{{ $t('callback-url') }}<mk-ellipsis/></p>
- <p v-if="!session.app.callbackUrl">{{ $t('please-go-back') }}</p>
+ <p v-if="session.app.callbackUrl">{{ $t('_auth.callback') }}<mk-ellipsis/></p>
+ <p v-if="!session.app.callbackUrl">{{ $t('_auth.pleaseGoBack') }}</p>
</div>
<div class="error _panel" v-if="state == 'fetch-session-error'">
<p>{{ $t('error') }}</p>
</div>
</div>
<div class="signin" v-else>
- <h1>{{ $t('sign-in') }}</h1>
<mk-signin @login="onLogin"/>
</div>
</template>
diff --git a/src/client/pages/doc.vue b/src/client/pages/doc.vue
index e0db5a3746..7c4f7ebccf 100644
--- a/src/client/pages/doc.vue
+++ b/src/client/pages/doc.vue
@@ -18,6 +18,7 @@
import Vue from 'vue';
import { faFileAlt } from '@fortawesome/free-solid-svg-icons'
import MarkdownIt from 'markdown-it';
+import MarkdownItAnchor from 'markdown-it-anchor';
import i18n from '../i18n';
import { url, lang } from '../config';
import MkLink from '../components/link.vue';
@@ -26,6 +27,10 @@ const markdown = MarkdownIt({
html: true
});
+markdown.use(MarkdownItAnchor, {
+ slugify: (s) => encodeURIComponent(String(s).trim().replace(/\s+/g, '-'))
+});
+
export default Vue.extend({
i18n,
@@ -72,6 +77,9 @@ export default Vue.extend({
},
parse(md: string) {
+ // 変数置換
+ md = md.replace(/\{_URL_\}/g, url);
+
// markdown の全容をパースする
const parsed = markdown.parse(md, {});
if (parsed.length === 0) return;
@@ -115,6 +123,23 @@ export default Vue.extend({
margin-bottom: 0;
}
+ ::v-deep a {
+ color: var(--link);
+ }
+
+ ::v-deep blockquote {
+ display: block;
+ margin: 8px;
+ padding: 6px 0 6px 12px;
+ color: var(--fg);
+ border-left: solid 3px var(--fg);
+ opacity: 0.7;
+
+ p {
+ margin: 0;
+ }
+ }
+
::v-deep h2 {
font-size: 1.25em;
padding: 0 0 0.5em 0;
diff --git a/src/client/pages/follow-requests.vue b/src/client/pages/follow-requests.vue
index a900bf735c..b310d9f581 100644
--- a/src/client/pages/follow-requests.vue
+++ b/src/client/pages/follow-requests.vue
@@ -5,7 +5,7 @@
<mk-pagination :pagination="pagination" class="mk-follow-requests" ref="list">
<template #empty>
- <div class="tkdrhpxr">
+ <div class="_fullinfo">
<img src="https://xn--931a.moe/assets/info.jpg" class="_ghost"/>
<div>{{ $t('noFollowRequests') }}</div>
</div>
@@ -75,18 +75,6 @@ export default Vue.extend({
<style lang="scss" scoped>
.mk-follow-requests {
- .tkdrhpxr {
- padding: 32px;
- text-align: center;
-
- > img {
- vertical-align: bottom;
- height: 128px;
- margin-bottom: 16px;
- border-radius: 16px;
- }
- }
-
> .user {
display: flex;
padding: 16px;
diff --git a/src/client/pages/messaging/index.vue b/src/client/pages/messaging/index.vue
index ed24f8ef54..7a55004cbf 100644
--- a/src/client/pages/messaging/index.vue
+++ b/src/client/pages/messaging/index.vue
@@ -31,7 +31,7 @@
</div>
</router-link>
</div>
- <div class="no-history" v-if="!fetching && messages.length == 0">
+ <div class="_fullinfo" v-if="!fetching && messages.length == 0">
<img src="https://xn--931a.moe/assets/info.jpg" class="_ghost"/>
<div>{{ $t('noHistory') }}</div>
</div>
@@ -287,18 +287,6 @@ export default Vue.extend({
}
}
- > .no-history {
- padding: 32px;
- text-align: center;
-
- > img {
- vertical-align: bottom;
- height: 128px;
- margin-bottom: 16px;
- border-radius: 16px;
- }
- }
-
@media (max-width: 400px) {
> .history {
> .message {
diff --git a/src/client/pages/miauth.vue b/src/client/pages/miauth.vue
new file mode 100644
index 0000000000..2ee0f23479
--- /dev/null
+++ b/src/client/pages/miauth.vue
@@ -0,0 +1,103 @@
+<template>
+<div v-if="$store.getters.isSignedIn">
+ <div class="waiting _card" v-if="state == 'waiting'">
+ <div class="_content">
+ <mk-loading/>
+ </div>
+ </div>
+ <div class="denied _card" v-if="state == 'denied'">
+ <div class="_content">
+ <p>{{ $t('_auth.denied') }}</p>
+ </div>
+ </div>
+ <div class="accepted _card" v-else-if="state == 'accepted'">
+ <div class="_content">
+ <p v-if="callback">{{ $t('_auth.callback') }}<mk-ellipsis/></p>
+ <p v-else>{{ $t('_auth.pleaseGoBack') }}</p>
+ </div>
+ </div>
+ <div class="_card" v-else>
+ <div class="_title" v-if="name">{{ $t('_auth.shareAccess', { name: name }) }}</div>
+ <div class="_title" v-else>{{ $t('_auth.shareAccessAsk') }}</div>
+ <div class="_content">
+ <p>{{ $t('_auth.permissionAsk') }}</p>
+ <ul>
+ <template v-for="p in permission">
+ <li :key="p">{{ $t(`_permissions.${p}`) }}</li>
+ </template>
+ </ul>
+ </div>
+ <div class="_footer">
+ <mk-button @click="deny" inline>{{ $t('cancel') }}</mk-button>
+ <mk-button @click="accept" inline primary>{{ $t('accept') }}</mk-button>
+ </div>
+ </div>
+</div>
+<div class="signin" v-else>
+ <mk-signin @login="onLogin"/>
+</div>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+import i18n from '../i18n';
+import MkSignin from '../components/signin.vue';
+import MkButton from '../components/ui/button.vue';
+
+export default Vue.extend({
+ i18n,
+ components: {
+ MkSignin,
+ MkButton,
+ },
+ data() {
+ return {
+ state: null
+ };
+ },
+ computed: {
+ session(): string {
+ return this.$route.params.session;
+ },
+ callback(): string {
+ return this.$route.query.callback;
+ },
+ name(): string {
+ return this.$route.query.name;
+ },
+ icon(): string {
+ return this.$route.query.icon;
+ },
+ permission(): string {
+ return this.$route.query.permission;
+ },
+ },
+ methods: {
+ async accept() {
+ this.state = 'waiting';
+ await this.$root.api('miauth/gen-token', {
+ session: this.session,
+ name: this.name,
+ iconUrl: this.icon,
+ permission: this.permission || [],
+ });
+
+ this.state = 'accepted';
+ if (this.callback) {
+ location.href = `${this.callback}?session=${this.session}`;
+ }
+ },
+ deny() {
+ this.state = 'denied';
+ },
+ onLogin(res) {
+ localStorage.setItem('i', res.i);
+ location.reload();
+ }
+ }
+});
+</script>
+
+<style lang="scss" scoped>
+
+</style>
diff --git a/src/client/pages/my-settings/index.vue b/src/client/pages/my-settings/index.vue
index 4742793f2b..c3080e0f81 100644
--- a/src/client/pages/my-settings/index.vue
+++ b/src/client/pages/my-settings/index.vue
@@ -32,7 +32,9 @@
<x-integration/>
<x-api/>
- <mk-button @click="$root.signout()" primary style="margin: var(--margin) auto;">{{ $t('logout') }}</mk-button>
+ <router-link class="_panel _buttonPrimary" to="/my/apps" style="margin: var(--margin) auto;">{{ $t('installedApps') }}</router-link>
+
+ <button class="_panel _buttonPrimary" @click="$root.signout()" style="margin: var(--margin) auto;">{{ $t('logout') }}</button>
</div>
</template>
diff --git a/src/client/pages/preferences/theme.vue b/src/client/pages/preferences/theme.vue
index fcea457396..f35b5d6ed8 100644
--- a/src/client/pages/preferences/theme.vue
+++ b/src/client/pages/preferences/theme.vue
@@ -57,7 +57,8 @@
<mk-textarea v-model="installThemeCode">
<span>{{ $t('_theme.code') }}</span>
</mk-textarea>
- <mk-button @click="() => install(this.installThemeCode)" :disabled="installThemeCode == null"><fa :icon="faCheck"/> {{ $t('install') }}</mk-button>
+ <mk-button @click="() => install(this.installThemeCode)" :disabled="installThemeCode == null" primary inline><fa :icon="faCheck"/> {{ $t('install') }}</mk-button>
+ <mk-button @click="() => preview(this.installThemeCode)" :disabled="installThemeCode == null" inline><fa :icon="faEye"/> {{ $t('preview') }}</mk-button>
</details>
</div>
<div class="_content">
@@ -79,7 +80,7 @@
<script lang="ts">
import Vue from 'vue';
-import { faPalette, faDownload, faFolderOpen, faCheck, faTrashAlt } from '@fortawesome/free-solid-svg-icons';
+import { faPalette, faDownload, faFolderOpen, faCheck, faTrashAlt, faEye } from '@fortawesome/free-solid-svg-icons';
import * as JSON5 from 'json5';
import MkInput from '../../components/ui/input.vue';
import MkButton from '../../components/ui/button.vue';
@@ -108,7 +109,7 @@ export default Vue.extend({
installThemeCode: null,
selectedThemeId: null,
wallpaper: localStorage.getItem('wallpaper'),
- faPalette, faDownload, faFolderOpen, faCheck, faTrashAlt
+ faPalette, faDownload, faFolderOpen, faCheck, faTrashAlt, faEye
}
},
@@ -196,8 +197,9 @@ export default Vue.extend({
});
},
- install(code) {
+ parseThemeCode(code) {
let theme;
+
try {
theme = JSON5.parse(code);
} catch (e) {
@@ -205,22 +207,34 @@ export default Vue.extend({
type: 'error',
text: this.$t('_theme.invalid')
});
- return;
+ return false;
}
if (!validateTheme(theme)) {
this.$root.dialog({
type: 'error',
text: this.$t('_theme.invalid')
});
- return;
+ return false;
}
if (this.$store.state.device.themes.some(t => t.id === theme.id)) {
this.$root.dialog({
type: 'info',
text: this.$t('_theme.alreadyInstalled')
});
- return;
+ return false;
}
+
+ return theme;
+ },
+
+ preview(code) {
+ const theme = this.parseThemeCode(code);
+ if (theme) applyTheme(theme, false);
+ },
+
+ install(code) {
+ const theme = this.parseThemeCode(code);
+ if (!theme) return;
const themes = this.$store.state.device.themes.concat(theme);
this.$store.commit('device/set', {
key: 'themes', value: themes