summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2020-11-15 12:34:47 +0900
committersyuilo <syuilotan@yahoo.co.jp>2020-11-15 12:34:47 +0900
commit8e8459fa559865428963b08e6422fba9617240f5 (patch)
tree9ed13f15c3b3199cf1b9fc4e92c5584ceae2c48d /src
parentwip: clip (diff)
downloadmisskey-8e8459fa559865428963b08e6422fba9617240f5.tar.gz
misskey-8e8459fa559865428963b08e6422fba9617240f5.tar.bz2
misskey-8e8459fa559865428963b08e6422fba9617240f5.zip
wip: clip
Diffstat (limited to 'src')
-rw-r--r--src/client/pages/clip.vue139
-rw-r--r--src/client/pages/my-clips/index.vue32
-rw-r--r--src/client/router.ts1
-rw-r--r--src/models/repositories/clip.ts12
-rw-r--r--src/server/api/endpoints/clips/update.ts12
5 files changed, 192 insertions, 4 deletions
diff --git a/src/client/pages/clip.vue b/src/client/pages/clip.vue
new file mode 100644
index 0000000000..ad9e076fd6
--- /dev/null
+++ b/src/client/pages/clip.vue
@@ -0,0 +1,139 @@
+<template>
+<div v-if="clip" class="_section">
+ <div class="okzinsic _content _panel _vMargin">
+ <div class="description" v-if="clip.description">
+ <Mfm :text="clip.description" :is-note="false" :i="$store.state.i"/>
+ </div>
+ </div>
+
+ <XNotes class="_content _vMargin" :pagination="pagination" :detail="true"/>
+</div>
+</template>
+
+<script lang="ts">
+import { computed, defineComponent } from 'vue';
+import { faEllipsisH, faPaperclip, faPencilAlt, faTrashAlt } from '@fortawesome/free-solid-svg-icons';
+import MkContainer from '@/components/ui/container.vue';
+import XPostForm from '@/components/post-form.vue';
+import XNotes from '@/components/notes.vue';
+import * as os from '@/os';
+
+export default defineComponent({
+ components: {
+ MkContainer,
+ XPostForm,
+ XNotes,
+ },
+
+ props: {
+ clipId: {
+ type: String,
+ required: true
+ }
+ },
+
+ data() {
+ return {
+ INFO: computed(() => this.clip ? {
+ title: this.clip.name,
+ icon: faPaperclip,
+ action: {
+ icon: faEllipsisH,
+ handler: this.menu
+ }
+ } : null),
+ clip: null,
+ pagination: {
+ endpoint: 'clips/notes',
+ limit: 10,
+ params: () => ({
+ clipId: this.clipId,
+ })
+ },
+ };
+ },
+
+ computed: {
+ isOwned(): boolean {
+ return this.$store.getters.isSignedIn && this.clip && (this.$store.state.i.id === this.clip.userId);
+ }
+ },
+
+ watch: {
+ clipId: {
+ async handler() {
+ this.clip = await os.api('clips/show', {
+ clipId: this.clipId,
+ });
+ },
+ immediate: true
+ }
+ },
+
+ created() {
+
+ },
+
+ methods: {
+ menu(ev) {
+ os.modalMenu([this.isOwned ? {
+ icon: faPencilAlt,
+ text: this.$t('edit'),
+ action: async () => {
+ const { canceled, result } = await os.form(this.clip.name, {
+ name: {
+ type: 'string',
+ label: this.$t('name'),
+ default: this.clip.name
+ },
+ description: {
+ type: 'string',
+ required: false,
+ multiline: true,
+ label: this.$t('description'),
+ default: this.clip.description
+ },
+ isPublic: {
+ type: 'boolean',
+ label: this.$t('public'),
+ default: this.clip.isPublic
+ }
+ });
+ if (canceled) return;
+
+ os.apiWithDialog('clips/update', {
+ clipId: this.clip.id,
+ ...result
+ });
+ }
+ } : undefined, this.isOwned ? {
+ icon: faTrashAlt,
+ text: this.$t('delete'),
+ danger: true,
+ action: async () => {
+ const { canceled } = await os.dialog({
+ type: 'warning',
+ text: this.$t('deleteAreYouSure', { x: this.clip.name }),
+ showCancelButton: true
+ });
+ if (canceled) return;
+
+ await os.apiWithDialog('clips/delete', {
+ clipId: this.clip.id,
+ });
+ }
+ } : undefined], ev.currentTarget || ev.target);
+ }
+ }
+});
+</script>
+
+<style lang="scss" scoped>
+.okzinsic {
+ position: relative;
+
+ > .description {
+ padding: 16px;
+ }
+}
+</style>
diff --git a/src/client/pages/my-clips/index.vue b/src/client/pages/my-clips/index.vue
index 93adb94a4b..efead39fcb 100644
--- a/src/client/pages/my-clips/index.vue
+++ b/src/client/pages/my-clips/index.vue
@@ -1,10 +1,13 @@
<template>
-<div class="_section">
+<div class="_section qtcaoidl">
<MkButton @click="create" primary class="add"><Fa :icon="faPlus"/> {{ $t('add') }}</MkButton>
<div class="_content">
- <MkPagination :pagination="pagination" #default="{items}" ref="list">
- <MkA v-for="item in items" :key="item.id" :to="`/clips/${item.id}`">{{ item.name }}</MkA>
+ <MkPagination :pagination="pagination" #default="{items}" ref="list" class="list">
+ <MkA v-for="item in items" :key="item.id" :to="`/clips/${item.id}`" class="item _panel _vMargin">
+ <b>{{ item.name }}</b>
+ <div v-if="item.description" class="description">{{ item.description }}</div>
+ </MkA>
</MkPagination>
</div>
</div>
@@ -76,3 +79,26 @@ export default defineComponent({
}
});
</script>
+
+<style lang="scss" scoped>
+.qtcaoidl {
+ > .add {
+ margin: 0 auto 16px auto;
+ }
+
+ > ._content {
+ > .list {
+ > .item {
+ display: block;
+ padding: 16px;
+
+ > .description {
+ margin-top: 8px;
+ padding-top: 8px;
+ border-top: solid 1px var(--divider);
+ }
+ }
+ }
+ }
+}
+</style>
diff --git a/src/client/router.ts b/src/client/router.ts
index da2945be2c..413e72c320 100644
--- a/src/client/router.ts
+++ b/src/client/router.ts
@@ -37,6 +37,7 @@ export const router = createRouter({
{ path: '/channels/new', component: page('channel-editor') },
{ path: '/channels/:channelId/edit', component: page('channel-editor'), props: true },
{ path: '/channels/:channelId', component: page('channel'), props: route => ({ channelId: route.params.channelId }) },
+ { path: '/clips/:clipId', component: page('clip'), props: route => ({ clipId: route.params.clipId }) },
{ path: '/my/notifications', component: page('notifications') },
{ path: '/my/favorites', component: page('favorites') },
{ path: '/my/messages', component: page('messages') },
diff --git a/src/models/repositories/clip.ts b/src/models/repositories/clip.ts
index 7cc3fb7110..f5c70a1829 100644
--- a/src/models/repositories/clip.ts
+++ b/src/models/repositories/clip.ts
@@ -15,8 +15,10 @@ export class ClipRepository extends Repository<Clip> {
return {
id: clip.id,
createdAt: clip.createdAt.toISOString(),
+ userId: clip.userId,
name: clip.name,
description: clip.description,
+ isPublic: clip.isPublic,
};
}
}
@@ -38,6 +40,11 @@ export const packedClipSchema = {
format: 'date-time',
description: 'The date that the Clip was created.'
},
+ userId: {
+ type: 'string' as const,
+ optional: false as const, nullable: false as const,
+ format: 'id',
+ },
name: {
type: 'string' as const,
optional: false as const, nullable: false as const,
@@ -48,5 +55,10 @@ export const packedClipSchema = {
optional: false as const, nullable: true as const,
description: 'The description of the Clip.'
},
+ isPublic: {
+ type: 'boolean' as const,
+ optional: false as const, nullable: false as const,
+ description: 'Whether this Clip is public.',
+ },
},
};
diff --git a/src/server/api/endpoints/clips/update.ts b/src/server/api/endpoints/clips/update.ts
index 483941214c..4a1a31eb95 100644
--- a/src/server/api/endpoints/clips/update.ts
+++ b/src/server/api/endpoints/clips/update.ts
@@ -18,6 +18,14 @@ export const meta = {
name: {
validator: $.str.range(1, 100),
+ },
+
+ isPublic: {
+ validator: $.optional.bool
+ },
+
+ description: {
+ validator: $.optional.nullable.str.range(1, 2048)
}
},
@@ -42,7 +50,9 @@ export default define(meta, async (ps, user) => {
}
await Clips.update(clip.id, {
- name: ps.name
+ name: ps.name,
+ description: ps.description,
+ isPublic: ps.isPublic,
});
return await Clips.pack(clip.id);