summaryrefslogtreecommitdiff
path: root/src/client
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2018-04-08 02:30:37 +0900
committersyuilo <syuilotan@yahoo.co.jp>2018-04-08 02:30:37 +0900
commita1b490afa756a71b9cef4afa424575bc223bc612 (patch)
tree06de4d839e17b1e08e0891542af7360c701a154a /src/client
parentMerge pull request #1392 from syuilo/greenkeeper/element-ui-2.3.3 (diff)
downloadmisskey-a1b490afa756a71b9cef4afa424575bc223bc612.tar.gz
misskey-a1b490afa756a71b9cef4afa424575bc223bc612.tar.bz2
misskey-a1b490afa756a71b9cef4afa424575bc223bc612.zip
Post --> Note
Closes #1411
Diffstat (limited to 'src/client')
-rw-r--r--src/client/app/auth/views/form.vue2
-rw-r--r--src/client/app/ch/tags/channel.tag68
-rw-r--r--src/client/app/common/mios.ts4
-rw-r--r--src/client/app/common/scripts/compose-notification.ts10
-rw-r--r--src/client/app/common/scripts/parse-search-query.ts4
-rw-r--r--src/client/app/common/views/components/index.ts4
-rw-r--r--src/client/app/common/views/components/messaging-room.message.vue2
-rw-r--r--src/client/app/common/views/components/note-html.ts (renamed from src/client/app/common/views/components/post-html.ts)2
-rw-r--r--src/client/app/common/views/components/note-menu.vue (renamed from src/client/app/common/views/components/post-menu.vue)10
-rw-r--r--src/client/app/common/views/components/poll.vue8
-rw-r--r--src/client/app/common/views/components/reaction-picker.vue6
-rw-r--r--src/client/app/common/views/components/reactions-viewer.vue4
-rw-r--r--src/client/app/common/views/components/welcome-timeline.vue26
-rw-r--r--src/client/app/desktop/api/post.ts8
-rw-r--r--src/client/app/desktop/script.ts16
-rw-r--r--src/client/app/desktop/views/components/activity.calendar.vue2
-rw-r--r--src/client/app/desktop/views/components/activity.chart.vue16
-rw-r--r--src/client/app/desktop/views/components/index.ts32
-rw-r--r--src/client/app/desktop/views/components/mentions.vue24
-rw-r--r--src/client/app/desktop/views/components/note-detail.sub.vue (renamed from src/client/app/desktop/views/components/post-detail.sub.vue)22
-rw-r--r--src/client/app/desktop/views/components/note-detail.vue448
-rw-r--r--src/client/app/desktop/views/components/note-preview.vue (renamed from src/client/app/desktop/views/components/post-preview.vue)22
-rw-r--r--src/client/app/desktop/views/components/notes.note.sub.vue (renamed from src/client/app/desktop/views/components/posts.post.sub.vue)18
-rw-r--r--src/client/app/desktop/views/components/notes.note.vue596
-rw-r--r--src/client/app/desktop/views/components/notes.vue (renamed from src/client/app/desktop/views/components/posts.vue)38
-rw-r--r--src/client/app/desktop/views/components/notifications.vue54
-rw-r--r--src/client/app/desktop/views/components/post-detail.vue84
-rw-r--r--src/client/app/desktop/views/components/post-form-window.vue6
-rw-r--r--src/client/app/desktop/views/components/post-form.vue32
-rw-r--r--src/client/app/desktop/views/components/posts.post.vue104
-rw-r--r--src/client/app/desktop/views/components/renote-form-window.vue42
-rw-r--r--src/client/app/desktop/views/components/renote-form.vue131
-rw-r--r--src/client/app/desktop/views/components/repost-form-window.vue6
-rw-r--r--src/client/app/desktop/views/components/repost-form.vue26
-rw-r--r--src/client/app/desktop/views/components/sub-note-content.vue44
-rw-r--r--src/client/app/desktop/views/components/sub-post-content.vue44
-rw-r--r--src/client/app/desktop/views/components/timeline.vue42
-rw-r--r--src/client/app/desktop/views/components/ui.header.post.vue6
-rw-r--r--src/client/app/desktop/views/components/user-preview.vue2
-rw-r--r--src/client/app/desktop/views/pages/home.vue12
-rw-r--r--src/client/app/desktop/views/pages/note.vue (renamed from src/client/app/desktop/views/pages/post.vue)18
-rw-r--r--src/client/app/desktop/views/pages/search.vue32
-rw-r--r--src/client/app/desktop/views/pages/user/user.home.vue2
-rw-r--r--src/client/app/desktop/views/pages/user/user.photos.vue8
-rw-r--r--src/client/app/desktop/views/pages/user/user.profile.vue2
-rw-r--r--src/client/app/desktop/views/pages/user/user.timeline.vue24
-rw-r--r--src/client/app/desktop/views/widgets/channel.channel.form.vue4
-rw-r--r--src/client/app/desktop/views/widgets/channel.channel.note.vue (renamed from src/client/app/desktop/views/widgets/channel.channel.post.vue)24
-rw-r--r--src/client/app/desktop/views/widgets/channel.channel.vue36
-rw-r--r--src/client/app/desktop/views/widgets/polls.vue8
-rw-r--r--src/client/app/desktop/views/widgets/post-form.vue4
-rw-r--r--src/client/app/desktop/views/widgets/trends.vue24
-rw-r--r--src/client/app/dev/views/new-app.vue2
-rw-r--r--src/client/app/mobile/api/post.ts20
-rw-r--r--src/client/app/mobile/script.ts4
-rw-r--r--src/client/app/mobile/views/components/activity.vue16
-rw-r--r--src/client/app/mobile/views/components/index.ts24
-rw-r--r--src/client/app/mobile/views/components/note-card.vue (renamed from src/client/app/mobile/views/components/post-card.vue)18
-rw-r--r--src/client/app/mobile/views/components/note-detail.sub.vue (renamed from src/client/app/mobile/views/components/post-detail.sub.vue)16
-rw-r--r--src/client/app/mobile/views/components/note-detail.vue462
-rw-r--r--src/client/app/mobile/views/components/note-preview.vue (renamed from src/client/app/mobile/views/components/post-preview.vue)18
-rw-r--r--src/client/app/mobile/views/components/note.sub.vue (renamed from src/client/app/mobile/views/components/post.sub.vue)16
-rw-r--r--src/client/app/mobile/views/components/note.vue540
-rw-r--r--src/client/app/mobile/views/components/notes.vue (renamed from src/client/app/mobile/views/components/posts.vue)34
-rw-r--r--src/client/app/mobile/views/components/notification-preview.vue42
-rw-r--r--src/client/app/mobile/views/components/notification.vue38
-rw-r--r--src/client/app/mobile/views/components/post-detail.vue80
-rw-r--r--src/client/app/mobile/views/components/post-form.vue10
-rw-r--r--src/client/app/mobile/views/components/post.vue90
-rw-r--r--src/client/app/mobile/views/components/sub-note-content.vue43
-rw-r--r--src/client/app/mobile/views/components/sub-post-content.vue43
-rw-r--r--src/client/app/mobile/views/components/timeline.vue38
-rw-r--r--src/client/app/mobile/views/components/user-timeline.vue32
-rw-r--r--src/client/app/mobile/views/pages/home.vue12
-rw-r--r--src/client/app/mobile/views/pages/note.vue (renamed from src/client/app/mobile/views/pages/post.vue)18
-rw-r--r--src/client/app/mobile/views/pages/search.vue30
-rw-r--r--src/client/app/mobile/views/pages/user.vue8
-rw-r--r--src/client/app/mobile/views/pages/user/home.notes.vue (renamed from src/client/app/mobile/views/pages/user/home.posts.vue)20
-rw-r--r--src/client/app/mobile/views/pages/user/home.photos.vue12
-rw-r--r--src/client/app/mobile/views/pages/user/home.vue14
-rw-r--r--src/client/app/stats/tags/index.tag28
-rw-r--r--src/client/docs/api/endpoints/notes/create.yaml (renamed from src/client/docs/api/endpoints/posts/create.yaml)22
-rw-r--r--src/client/docs/api/endpoints/notes/timeline.yaml (renamed from src/client/docs/api/endpoints/posts/timeline.yaml)6
-rw-r--r--src/client/docs/api/entities/note.yaml174
-rw-r--r--src/client/docs/api/entities/post.yaml40
-rw-r--r--src/client/docs/api/entities/user.yaml16
-rw-r--r--src/client/docs/mute.ja.pug2
-rw-r--r--src/client/docs/search.ja.pug16
88 files changed, 3305 insertions, 912 deletions
diff --git a/src/client/app/auth/views/form.vue b/src/client/app/auth/views/form.vue
index eb55b9035b..b323907eb0 100644
--- a/src/client/app/auth/views/form.vue
+++ b/src/client/app/auth/views/form.vue
@@ -16,7 +16,7 @@
<template v-for="p in app.permission">
<li v-if="p == 'account-read'">アカウントの情報を見る。</li>
<li v-if="p == 'account-write'">アカウントの情報を操作する。</li>
- <li v-if="p == 'post-write'">投稿する。</li>
+ <li v-if="p == 'note-write'">投稿する。</li>
<li v-if="p == 'like-write'">いいねしたりいいね解除する。</li>
<li v-if="p == 'following-write'">フォローしたりフォロー解除する。</li>
<li v-if="p == 'drive-read'">ドライブを見る。</li>
diff --git a/src/client/app/ch/tags/channel.tag b/src/client/app/ch/tags/channel.tag
index 4856728dec..c0561c9b92 100644
--- a/src/client/app/ch/tags/channel.tag
+++ b/src/client/app/ch/tags/channel.tag
@@ -15,11 +15,11 @@
</div>
<div class="body">
- <p v-if="postsFetching">読み込み中<mk-ellipsis/></p>
- <div v-if="!postsFetching">
- <p v-if="posts == null || posts.length == 0">まだ投稿がありません</p>
- <template v-if="posts != null">
- <mk-channel-post each={ post in posts.slice().reverse() } post={ post } form={ parent.refs.form }/>
+ <p v-if="notesFetching">読み込み中<mk-ellipsis/></p>
+ <div v-if="!notesFetching">
+ <p v-if="notes == null || notes.length == 0">まだ投稿がありません</p>
+ <template v-if="notes != null">
+ <mk-channel-note each={ note in notes.slice().reverse() } note={ note } form={ parent.refs.form }/>
</template>
</div>
</div>
@@ -62,9 +62,9 @@
this.id = this.opts.id;
this.fetching = true;
- this.postsFetching = true;
+ this.notesFetching = true;
this.channel = null;
- this.posts = null;
+ this.notes = null;
this.connection = new ChannelStream(this.id);
this.unreadCount = 0;
@@ -95,9 +95,9 @@
});
// 投稿読み込み
- this.$root.$data.os.api('channels/posts', {
+ this.$root.$data.os.api('channels/notes', {
channelId: this.id
- }).then(posts => {
+ }).then(notes => {
if (fetched) {
Progress.done();
} else {
@@ -106,26 +106,26 @@
}
this.update({
- postsFetching: false,
- posts: posts
+ notesFetching: false,
+ notes: notes
});
});
- this.connection.on('post', this.onPost);
+ this.connection.on('note', this.onNote);
document.addEventListener('visibilitychange', this.onVisibilitychange, false);
});
this.on('unmount', () => {
- this.connection.off('post', this.onPost);
+ this.connection.off('note', this.onNote);
this.connection.close();
document.removeEventListener('visibilitychange', this.onVisibilitychange);
});
- this.onPost = post => {
- this.posts.unshift(post);
+ this.onNote = note => {
+ this.notes.unshift(note);
this.update();
- if (document.hidden && this.$root.$data.os.isSignedIn && post.userId !== this.$root.$data.os.i.id) {
+ if (document.hidden && this.$root.$data.os.isSignedIn && note.userId !== this.$root.$data.os.i.id) {
this.unreadCount++;
document.title = `(${this.unreadCount}) ${this.channel.title} | Misskey`;
}
@@ -162,19 +162,19 @@
</script>
</mk-channel>
-<mk-channel-post>
+<mk-channel-note>
<header>
- <a class="index" @click="reply">{ post.index }:</a>
- <a class="name" href={ _URL_ + '/@' + acct }><b>{ getUserName(post.user) }</b></a>
- <mk-time time={ post.createdAt }/>
- <mk-time time={ post.createdAt } mode="detail"/>
+ <a class="index" @click="reply">{ note.index }:</a>
+ <a class="name" href={ _URL_ + '/@' + acct }><b>{ getUserName(note.user) }</b></a>
+ <mk-time time={ note.createdAt }/>
+ <mk-time time={ note.createdAt } mode="detail"/>
<span>ID:<i>{ acct }</i></span>
</header>
<div>
- <a v-if="post.reply">&gt;&gt;{ post.reply.index }</a>
- { post.text }
- <div class="media" v-if="post.media">
- <template each={ file in post.media }>
+ <a v-if="note.reply">&gt;&gt;{ note.reply.index }</a>
+ { note.text }
+ <div class="media" v-if="note.media">
+ <template each={ file in note.media }>
<a href={ file.url } target="_blank">
<img src={ file.url + '?thumbnail&size=512' } alt={ file.name } title={ file.name }/>
</a>
@@ -232,18 +232,18 @@
import getAcct from '../../../../acct/render';
import getUserName from '../../../../renderers/get-user-name';
- this.post = this.opts.post;
+ this.note = this.opts.note;
this.form = this.opts.form;
- this.acct = getAcct(this.post.user);
- this.name = getUserName(this.post.user);
+ this.acct = getAcct(this.note.user);
+ this.name = getUserName(this.note.user);
this.reply = () => {
this.form.update({
- reply: this.post
+ reply: this.note
});
};
</script>
-</mk-channel-post>
+</mk-channel-note>
<mk-channel-form>
<p v-if="reply"><b>&gt;&gt;{ reply.index }</b> ({ getUserName(reply.user) }): <a @click="clearReply">[x]</a></p>
@@ -251,8 +251,8 @@
<div class="actions">
<button @click="selectFile">%fa:upload%%i18n:ch.tags.mk-channel-form.upload%</button>
<button @click="drive">%fa:cloud%%i18n:ch.tags.mk-channel-form.drive%</button>
- <button :class="{ wait: wait }" ref="submit" disabled={ wait || (refs.text.value.length == 0) } @click="post">
- <template v-if="!wait">%fa:paper-plane%</template>{ wait ? '%i18n:ch.tags.mk-channel-form.posting%' : '%i18n:ch.tags.mk-channel-form.post%' }<mk-ellipsis v-if="wait"/>
+ <button :class="{ wait: wait }" ref="submit" disabled={ wait || (refs.text.value.length == 0) } @click="note">
+ <template v-if="!wait">%fa:paper-plane%</template>{ wait ? '%i18n:ch.tags.mk-channel-form.posting%' : '%i18n:ch.tags.mk-channel-form.note%' }<mk-ellipsis v-if="wait"/>
</button>
</div>
<mk-uploader ref="uploader"/>
@@ -321,7 +321,7 @@
this.$refs.text.value = '';
};
- this.post = () => {
+ this.note = () => {
this.update({
wait: true
});
@@ -330,7 +330,7 @@
? this.files.map(f => f.id)
: undefined;
- this.$root.$data.os.api('posts/create', {
+ this.$root.$data.os.api('notes/create', {
text: this.$refs.text.value == '' ? undefined : this.$refs.text.value,
mediaIds: files,
replyId: this.reply ? this.reply.id : undefined,
diff --git a/src/client/app/common/mios.ts b/src/client/app/common/mios.ts
index bcb8b60678..48e830810c 100644
--- a/src/client/app/common/mios.ts
+++ b/src/client/app/common/mios.ts
@@ -49,7 +49,7 @@ export type API = {
post: (opts?: {
reply?: any;
- repost?: any;
+ renote?: any;
}) => void;
notify: (message: string) => void;
@@ -312,7 +312,7 @@ export default class MiOS extends EventEmitter {
// Finish init
callback();
- //#region Post
+ //#region Note
// Init service worker
if (this.shouldRegisterSw) this.registerSw();
diff --git a/src/client/app/common/scripts/compose-notification.ts b/src/client/app/common/scripts/compose-notification.ts
index e99d502960..c19b1c5ad0 100644
--- a/src/client/app/common/scripts/compose-notification.ts
+++ b/src/client/app/common/scripts/compose-notification.ts
@@ -1,4 +1,4 @@
-import getPostSummary from '../../../../renderers/get-post-summary';
+import getNoteSummary from '../../../../renderers/get-note-summary';
import getReactionEmoji from '../../../../renderers/get-reaction-emoji';
import getUserName from '../../../../renderers/get-user-name';
@@ -23,28 +23,28 @@ export default function(type, data): Notification {
case 'mention':
return {
title: `${getUserName(data.user)}さんから:`,
- body: getPostSummary(data),
+ body: getNoteSummary(data),
icon: data.user.avatarUrl + '?thumbnail&size=64'
};
case 'reply':
return {
title: `${getUserName(data.user)}さんから返信:`,
- body: getPostSummary(data),
+ body: getNoteSummary(data),
icon: data.user.avatarUrl + '?thumbnail&size=64'
};
case 'quote':
return {
title: `${getUserName(data.user)}さんが引用:`,
- body: getPostSummary(data),
+ body: getNoteSummary(data),
icon: data.user.avatarUrl + '?thumbnail&size=64'
};
case 'reaction':
return {
title: `${getUserName(data.user)}: ${getReactionEmoji(data.reaction)}:`,
- body: getPostSummary(data.post),
+ body: getNoteSummary(data.note),
icon: data.user.avatarUrl + '?thumbnail&size=64'
};
diff --git a/src/client/app/common/scripts/parse-search-query.ts b/src/client/app/common/scripts/parse-search-query.ts
index 4f09d2b93f..5f6ae3320a 100644
--- a/src/client/app/common/scripts/parse-search-query.ts
+++ b/src/client/app/common/scripts/parse-search-query.ts
@@ -19,8 +19,8 @@ export default function(qs: string) {
case 'reply':
q['reply'] = value == 'null' ? null : value == 'true';
break;
- case 'repost':
- q['repost'] = value == 'null' ? null : value == 'true';
+ case 'renote':
+ q['renote'] = value == 'null' ? null : value == 'true';
break;
case 'media':
q['media'] = value == 'null' ? null : value == 'true';
diff --git a/src/client/app/common/views/components/index.ts b/src/client/app/common/views/components/index.ts
index b58ba37ecb..6bfe43a800 100644
--- a/src/client/app/common/views/components/index.ts
+++ b/src/client/app/common/views/components/index.ts
@@ -4,7 +4,7 @@ import signin from './signin.vue';
import signup from './signup.vue';
import forkit from './forkit.vue';
import nav from './nav.vue';
-import postHtml from './post-html';
+import noteHtml from './note-html';
import poll from './poll.vue';
import pollEditor from './poll-editor.vue';
import reactionIcon from './reaction-icon.vue';
@@ -29,7 +29,7 @@ Vue.component('mk-signin', signin);
Vue.component('mk-signup', signup);
Vue.component('mk-forkit', forkit);
Vue.component('mk-nav', nav);
-Vue.component('mk-post-html', postHtml);
+Vue.component('mk-note-html', noteHtml);
Vue.component('mk-poll', poll);
Vue.component('mk-poll-editor', pollEditor);
Vue.component('mk-reaction-icon', reactionIcon);
diff --git a/src/client/app/common/views/components/messaging-room.message.vue b/src/client/app/common/views/components/messaging-room.message.vue
index 1518602c63..7200b59bb2 100644
--- a/src/client/app/common/views/components/messaging-room.message.vue
+++ b/src/client/app/common/views/components/messaging-room.message.vue
@@ -10,7 +10,7 @@
<img src="/assets/desktop/messaging/delete.png" alt="Delete"/>
</button>
<div class="content" v-if="!message.isDeleted">
- <mk-post-html class="text" v-if="message.text" ref="text" :text="message.text" :i="os.i"/>
+ <mk-note-html class="text" v-if="message.text" ref="text" :text="message.text" :i="os.i"/>
<div class="file" v-if="message.file">
<a :href="message.file.url" target="_blank" :title="message.file.name">
<img v-if="message.file.type.split('/')[0] == 'image'" :src="message.file.url" :alt="message.file.name"/>
diff --git a/src/client/app/common/views/components/post-html.ts b/src/client/app/common/views/components/note-html.ts
index 8d85316523..24e750a671 100644
--- a/src/client/app/common/views/components/post-html.ts
+++ b/src/client/app/common/views/components/note-html.ts
@@ -9,7 +9,7 @@ const flatten = list => list.reduce(
(a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []
);
-export default Vue.component('mk-post-html', {
+export default Vue.component('mk-note-html', {
props: {
text: {
type: String,
diff --git a/src/client/app/common/views/components/post-menu.vue b/src/client/app/common/views/components/note-menu.vue
index 35116db7e2..d053748728 100644
--- a/src/client/app/common/views/components/post-menu.vue
+++ b/src/client/app/common/views/components/note-menu.vue
@@ -1,8 +1,8 @@
<template>
-<div class="mk-post-menu">
+<div class="mk-note-menu">
<div class="backdrop" ref="backdrop" @click="close"></div>
<div class="popover" :class="{ compact }" ref="popover">
- <button v-if="post.userId == os.i.id" @click="pin">%i18n:common.tags.mk-post-menu.pin%</button>
+ <button v-if="note.userId == os.i.id" @click="pin">%i18n:common.tags.mk-note-menu.pin%</button>
</div>
</div>
</template>
@@ -12,7 +12,7 @@ import Vue from 'vue';
import * as anime from 'animejs';
export default Vue.extend({
- props: ['post', 'source', 'compact'],
+ props: ['note', 'source', 'compact'],
mounted() {
this.$nextTick(() => {
const popover = this.$refs.popover as any;
@@ -51,7 +51,7 @@ export default Vue.extend({
methods: {
pin() {
(this as any).api('i/pin', {
- postId: this.post.id
+ noteId: this.note.id
}).then(() => {
this.$destroy();
});
@@ -83,7 +83,7 @@ export default Vue.extend({
<style lang="stylus" scoped>
$border-color = rgba(27, 31, 35, 0.15)
-.mk-post-menu
+.mk-note-menu
position initial
> .backdrop
diff --git a/src/client/app/common/views/components/poll.vue b/src/client/app/common/views/components/poll.vue
index 711d89720e..eb29aa8837 100644
--- a/src/client/app/common/views/components/poll.vue
+++ b/src/client/app/common/views/components/poll.vue
@@ -22,7 +22,7 @@
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
- props: ['post'],
+ props: ['note'],
data() {
return {
showResult: false
@@ -30,7 +30,7 @@ export default Vue.extend({
},
computed: {
poll(): any {
- return this.post.poll;
+ return this.note.poll;
},
total(): number {
return this.poll.choices.reduce((a, b) => a + b.votes, 0);
@@ -48,8 +48,8 @@ export default Vue.extend({
},
vote(id) {
if (this.poll.choices.some(c => c.isVoted)) return;
- (this as any).api('posts/polls/vote', {
- postId: this.post.id,
+ (this as any).api('notes/polls/vote', {
+ noteId: this.note.id,
choice: id
}).then(() => {
this.poll.choices.forEach(c => {
diff --git a/src/client/app/common/views/components/reaction-picker.vue b/src/client/app/common/views/components/reaction-picker.vue
index bcb6b2b965..fa1998dca9 100644
--- a/src/client/app/common/views/components/reaction-picker.vue
+++ b/src/client/app/common/views/components/reaction-picker.vue
@@ -25,7 +25,7 @@ import * as anime from 'animejs';
const placeholder = '%i18n:common.tags.mk-reaction-picker.choose-reaction%';
export default Vue.extend({
- props: ['post', 'source', 'compact', 'cb'],
+ props: ['note', 'source', 'compact', 'cb'],
data() {
return {
title: placeholder
@@ -68,8 +68,8 @@ export default Vue.extend({
},
methods: {
react(reaction) {
- (this as any).api('posts/reactions/create', {
- postId: this.post.id,
+ (this as any).api('notes/reactions/create', {
+ noteId: this.note.id,
reaction: reaction
}).then(() => {
if (this.cb) this.cb();
diff --git a/src/client/app/common/views/components/reactions-viewer.vue b/src/client/app/common/views/components/reactions-viewer.vue
index 246451008f..1afcf525d2 100644
--- a/src/client/app/common/views/components/reactions-viewer.vue
+++ b/src/client/app/common/views/components/reactions-viewer.vue
@@ -17,10 +17,10 @@
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
- props: ['post'],
+ props: ['note'],
computed: {
reactions(): number {
- return this.post.reactionCounts;
+ return this.note.reactionCounts;
}
}
});
diff --git a/src/client/app/common/views/components/welcome-timeline.vue b/src/client/app/common/views/components/welcome-timeline.vue
index bfb4b2bbe0..61616da14c 100644
--- a/src/client/app/common/views/components/welcome-timeline.vue
+++ b/src/client/app/common/views/components/welcome-timeline.vue
@@ -1,21 +1,21 @@
<template>
<div class="mk-welcome-timeline">
- <div v-for="post in posts">
- <router-link class="avatar-anchor" :to="`/@${getAcct(post.user)}`" v-user-preview="post.user.id">
- <img class="avatar" :src="`${post.user.avatarUrl}?thumbnail&size=96`" alt="avatar"/>
+ <div v-for="note in notes">
+ <router-link class="avatar-anchor" :to="`/@${getAcct(note.user)}`" v-user-preview="note.user.id">
+ <img class="avatar" :src="`${note.user.avatarUrl}?thumbnail&size=96`" alt="avatar"/>
</router-link>
<div class="body">
<header>
- <router-link class="name" :to="`/@${getAcct(post.user)}`" v-user-preview="post.user.id">{{ getUserName(post.user) }}</router-link>
- <span class="username">@{{ getAcct(post.user) }}</span>
+ <router-link class="name" :to="`/@${getAcct(note.user)}`" v-user-preview="note.user.id">{{ getUserName(note.user) }}</router-link>
+ <span class="username">@{{ getAcct(note.user) }}</span>
<div class="info">
- <router-link class="created-at" :to="`/@${getAcct(post.user)}/${post.id}`">
- <mk-time :time="post.createdAt"/>
+ <router-link class="created-at" :to="`/@${getAcct(note.user)}/${note.id}`">
+ <mk-time :time="note.createdAt"/>
</router-link>
</div>
</header>
<div class="text">
- <mk-post-html :text="post.text"/>
+ <mk-note-html :text="note.text"/>
</div>
</div>
</div>
@@ -31,7 +31,7 @@ export default Vue.extend({
data() {
return {
fetching: true,
- posts: []
+ notes: []
};
},
mounted() {
@@ -42,14 +42,14 @@ export default Vue.extend({
getUserName,
fetch(cb?) {
this.fetching = true;
- (this as any).api('posts', {
+ (this as any).api('notes', {
reply: false,
- repost: false,
+ renote: false,
media: false,
poll: false,
bot: false
- }).then(posts => {
- this.posts = posts;
+ }).then(notes => {
+ this.notes = notes;
this.fetching = false;
});
}
diff --git a/src/client/app/desktop/api/post.ts b/src/client/app/desktop/api/post.ts
index cf49615df3..b569610e1d 100644
--- a/src/client/app/desktop/api/post.ts
+++ b/src/client/app/desktop/api/post.ts
@@ -1,12 +1,12 @@
import PostFormWindow from '../views/components/post-form-window.vue';
-import RepostFormWindow from '../views/components/repost-form-window.vue';
+import RenoteFormWindow from '../views/components/renote-form-window.vue';
export default function(opts) {
const o = opts || {};
- if (o.repost) {
- const vm = new RepostFormWindow({
+ if (o.renote) {
+ const vm = new RenoteFormWindow({
propsData: {
- repost: o.repost
+ renote: o.renote
}
}).$mount();
document.body.appendChild(vm.$el);
diff --git a/src/client/app/desktop/script.ts b/src/client/app/desktop/script.ts
index b95e168544..f57d42aa6f 100644
--- a/src/client/app/desktop/script.ts
+++ b/src/client/app/desktop/script.ts
@@ -28,7 +28,7 @@ import MkSelectDrive from './views/pages/selectdrive.vue';
import MkDrive from './views/pages/drive.vue';
import MkHomeCustomize from './views/pages/home-customize.vue';
import MkMessagingRoom from './views/pages/messaging-room.vue';
-import MkPost from './views/pages/post.vue';
+import MkNote from './views/pages/note.vue';
import MkSearch from './views/pages/search.vue';
import MkOthello from './views/pages/othello.vue';
@@ -57,7 +57,7 @@ init(async (launch) => {
{ path: '/othello', component: MkOthello },
{ path: '/othello/:game', component: MkOthello },
{ path: '/@:user', component: MkUser },
- { path: '/@:user/:post', component: MkPost }
+ { path: '/@:user/:note', component: MkNote }
]
});
@@ -114,8 +114,8 @@ function registerNotifications(stream: HomeStreamManager) {
setTimeout(n.close.bind(n), 5000);
});
- connection.on('mention', post => {
- const _n = composeNotification('mention', post);
+ connection.on('mention', note => {
+ const _n = composeNotification('mention', note);
const n = new Notification(_n.title, {
body: _n.body,
icon: _n.icon
@@ -123,8 +123,8 @@ function registerNotifications(stream: HomeStreamManager) {
setTimeout(n.close.bind(n), 6000);
});
- connection.on('reply', post => {
- const _n = composeNotification('reply', post);
+ connection.on('reply', note => {
+ const _n = composeNotification('reply', note);
const n = new Notification(_n.title, {
body: _n.body,
icon: _n.icon
@@ -132,8 +132,8 @@ function registerNotifications(stream: HomeStreamManager) {
setTimeout(n.close.bind(n), 6000);
});
- connection.on('quote', post => {
- const _n = composeNotification('quote', post);
+ connection.on('quote', note => {
+ const _n = composeNotification('quote', note);
const n = new Notification(_n.title, {
body: _n.body,
icon: _n.icon
diff --git a/src/client/app/desktop/views/components/activity.calendar.vue b/src/client/app/desktop/views/components/activity.calendar.vue
index 72233e9aca..8b43536c2b 100644
--- a/src/client/app/desktop/views/components/activity.calendar.vue
+++ b/src/client/app/desktop/views/components/activity.calendar.vue
@@ -29,7 +29,7 @@ import Vue from 'vue';
export default Vue.extend({
props: ['data'],
created() {
- this.data.forEach(d => d.total = d.posts + d.replies + d.reposts);
+ this.data.forEach(d => d.total = d.notes + d.replies + d.renotes);
const peak = Math.max.apply(null, this.data.map(d => d.total));
let x = 0;
diff --git a/src/client/app/desktop/views/components/activity.chart.vue b/src/client/app/desktop/views/components/activity.chart.vue
index 5057786ed4..175c5d37ed 100644
--- a/src/client/app/desktop/views/components/activity.chart.vue
+++ b/src/client/app/desktop/views/components/activity.chart.vue
@@ -1,8 +1,8 @@
<template>
<svg :viewBox="`0 0 ${ viewBoxX } ${ viewBoxY }`" preserveAspectRatio="none" @mousedown.prevent="onMousedown">
- <title>Black ... Total<br/>Blue ... Posts<br/>Red ... Replies<br/>Green ... Reposts</title>
+ <title>Black ... Total<br/>Blue ... Notes<br/>Red ... Replies<br/>Green ... Renotes</title>
<polyline
- :points="pointsPost"
+ :points="pointsNote"
fill="none"
stroke-width="1"
stroke="#41ddde"/>
@@ -12,7 +12,7 @@
stroke-width="1"
stroke="#f7796c"/>
<polyline
- :points="pointsRepost"
+ :points="pointsRenote"
fill="none"
stroke-width="1"
stroke="#a1de41"/>
@@ -48,24 +48,24 @@ export default Vue.extend({
viewBoxY: 60,
zoom: 1,
pos: 0,
- pointsPost: null,
+ pointsNote: null,
pointsReply: null,
- pointsRepost: null,
+ pointsRenote: null,
pointsTotal: null
};
},
created() {
this.data.reverse();
- this.data.forEach(d => d.total = d.posts + d.replies + d.reposts);
+ this.data.forEach(d => d.total = d.notes + d.replies + d.renotes);
this.render();
},
methods: {
render() {
const peak = Math.max.apply(null, this.data.map(d => d.total));
if (peak != 0) {
- this.pointsPost = this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.posts / peak)) * this.viewBoxY}`).join(' ');
+ this.pointsNote = this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.notes / peak)) * this.viewBoxY}`).join(' ');
this.pointsReply = this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.replies / peak)) * this.viewBoxY}`).join(' ');
- this.pointsRepost = this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.reposts / peak)) * this.viewBoxY}`).join(' ');
+ this.pointsRenote = this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.renotes / peak)) * this.viewBoxY}`).join(' ');
this.pointsTotal = this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.total / peak)) * this.viewBoxY}`).join(' ');
}
},
diff --git a/src/client/app/desktop/views/components/index.ts b/src/client/app/desktop/views/components/index.ts
index 3798bf6d2d..4f61f43692 100644
--- a/src/client/app/desktop/views/components/index.ts
+++ b/src/client/app/desktop/views/components/index.ts
@@ -4,23 +4,23 @@ import ui from './ui.vue';
import uiNotification from './ui-notification.vue';
import home from './home.vue';
import timeline from './timeline.vue';
-import posts from './posts.vue';
-import subPostContent from './sub-post-content.vue';
+import notes from './notes.vue';
+import subNoteContent from './sub-note-content.vue';
import window from './window.vue';
-import postFormWindow from './post-form-window.vue';
-import repostFormWindow from './repost-form-window.vue';
+import noteFormWindow from './post-form-window.vue';
+import renoteFormWindow from './renote-form-window.vue';
import analogClock from './analog-clock.vue';
import ellipsisIcon from './ellipsis-icon.vue';
import mediaImage from './media-image.vue';
import mediaImageDialog from './media-image-dialog.vue';
import mediaVideo from './media-video.vue';
import notifications from './notifications.vue';
-import postForm from './post-form.vue';
-import repostForm from './repost-form.vue';
+import noteForm from './post-form.vue';
+import renoteForm from './renote-form.vue';
import followButton from './follow-button.vue';
-import postPreview from './post-preview.vue';
+import notePreview from './note-preview.vue';
import drive from './drive.vue';
-import postDetail from './post-detail.vue';
+import noteDetail from './note-detail.vue';
import settings from './settings.vue';
import calendar from './calendar.vue';
import activity from './activity.vue';
@@ -34,23 +34,23 @@ Vue.component('mk-ui', ui);
Vue.component('mk-ui-notification', uiNotification);
Vue.component('mk-home', home);
Vue.component('mk-timeline', timeline);
-Vue.component('mk-posts', posts);
-Vue.component('mk-sub-post-content', subPostContent);
+Vue.component('mk-notes', notes);
+Vue.component('mk-sub-note-content', subNoteContent);
Vue.component('mk-window', window);
-Vue.component('mk-post-form-window', postFormWindow);
-Vue.component('mk-repost-form-window', repostFormWindow);
+Vue.component('mk-post-form-window', noteFormWindow);
+Vue.component('mk-renote-form-window', renoteFormWindow);
Vue.component('mk-analog-clock', analogClock);
Vue.component('mk-ellipsis-icon', ellipsisIcon);
Vue.component('mk-media-image', mediaImage);
Vue.component('mk-media-image-dialog', mediaImageDialog);
Vue.component('mk-media-video', mediaVideo);
Vue.component('mk-notifications', notifications);
-Vue.component('mk-post-form', postForm);
-Vue.component('mk-repost-form', repostForm);
+Vue.component('mk-post-form', noteForm);
+Vue.component('mk-renote-form', renoteForm);
Vue.component('mk-follow-button', followButton);
-Vue.component('mk-post-preview', postPreview);
+Vue.component('mk-note-preview', notePreview);
Vue.component('mk-drive', drive);
-Vue.component('mk-post-detail', postDetail);
+Vue.component('mk-note-detail', noteDetail);
Vue.component('mk-settings', settings);
Vue.component('mk-calendar', calendar);
Vue.component('mk-activity', activity);
diff --git a/src/client/app/desktop/views/components/mentions.vue b/src/client/app/desktop/views/components/mentions.vue
index 90a92495b7..fc3a7af75d 100644
--- a/src/client/app/desktop/views/components/mentions.vue
+++ b/src/client/app/desktop/views/components/mentions.vue
@@ -7,12 +7,12 @@
<div class="fetching" v-if="fetching">
<mk-ellipsis-icon/>
</div>
- <p class="empty" v-if="posts.length == 0 && !fetching">
+ <p class="empty" v-if="notes.length == 0 && !fetching">
%fa:R comments%
<span v-if="mode == 'all'">あなた宛ての投稿はありません。</span>
<span v-if="mode == 'following'">あなたがフォローしているユーザーからの言及はありません。</span>
</p>
- <mk-posts :posts="posts" ref="timeline"/>
+ <mk-notes :notes="notes" ref="timeline"/>
</div>
</template>
@@ -24,7 +24,7 @@ export default Vue.extend({
fetching: true,
moreFetching: false,
mode: 'all',
- posts: []
+ notes: []
};
},
watch: {
@@ -56,23 +56,23 @@ export default Vue.extend({
},
fetch(cb?) {
this.fetching = true;
- this.posts = [];
- (this as any).api('posts/mentions', {
+ this.notes = [];
+ (this as any).api('notes/mentions', {
following: this.mode == 'following'
- }).then(posts => {
- this.posts = posts;
+ }).then(notes => {
+ this.notes = notes;
this.fetching = false;
if (cb) cb();
});
},
more() {
- if (this.moreFetching || this.fetching || this.posts.length == 0) return;
+ if (this.moreFetching || this.fetching || this.notes.length == 0) return;
this.moreFetching = true;
- (this as any).api('posts/mentions', {
+ (this as any).api('notes/mentions', {
following: this.mode == 'following',
- untilId: this.posts[this.posts.length - 1].id
- }).then(posts => {
- this.posts = this.posts.concat(posts);
+ untilId: this.notes[this.notes.length - 1].id
+ }).then(notes => {
+ this.notes = this.notes.concat(notes);
this.moreFetching = false;
});
}
diff --git a/src/client/app/desktop/views/components/post-detail.sub.vue b/src/client/app/desktop/views/components/note-detail.sub.vue
index 496003eb8b..0159d1ad47 100644
--- a/src/client/app/desktop/views/components/post-detail.sub.vue
+++ b/src/client/app/desktop/views/components/note-detail.sub.vue
@@ -1,24 +1,24 @@
<template>
<div class="sub" :title="title">
<router-link class="avatar-anchor" :to="`/@${acct}`">
- <img class="avatar" :src="`${post.user.avatarUrl}?thumbnail&size=64`" alt="avatar" v-user-preview="post.userId"/>
+ <img class="avatar" :src="`${note.user.avatarUrl}?thumbnail&size=64`" alt="avatar" v-user-preview="note.userId"/>
</router-link>
<div class="main">
<header>
<div class="left">
- <router-link class="name" :to="`/@${acct}`" v-user-preview="post.userId">{{ getUserName(post.user) }}</router-link>
+ <router-link class="name" :to="`/@${acct}`" v-user-preview="note.userId">{{ getUserName(note.user) }}</router-link>
<span class="username">@{{ acct }}</span>
</div>
<div class="right">
- <router-link class="time" :to="`/@${acct}/${post.id}`">
- <mk-time :time="post.createdAt"/>
+ <router-link class="time" :to="`/@${acct}/${note.id}`">
+ <mk-time :time="note.createdAt"/>
</router-link>
</div>
</header>
<div class="body">
- <mk-post-html v-if="post.text" :text="post.text" :i="os.i" :class="$style.text"/>
- <div class="media" v-if="post.media > 0">
- <mk-media-list :media-list="post.media"/>
+ <mk-note-html v-if="note.text" :text="note.text" :i="os.i" :class="$style.text"/>
+ <div class="media" v-if="note.media > 0">
+ <mk-media-list :media-list="note.media"/>
</div>
</div>
</div>
@@ -32,16 +32,16 @@ import getAcct from '../../../../../acct/render';
import getUserName from '../../../../../renderers/get-user-name';
export default Vue.extend({
- props: ['post'],
+ props: ['note'],
computed: {
acct() {
- return getAcct(this.post.user);
+ return getAcct(this.note.user);
},
name() {
- return getUserName(this.post.user);
+ return getUserName(this.note.user);
},
title(): string {
- return dateStringify(this.post.createdAt);
+ return dateStringify(this.note.createdAt);
}
}
});
diff --git a/src/client/app/desktop/views/components/note-detail.vue b/src/client/app/desktop/views/components/note-detail.vue
new file mode 100644
index 0000000000..790f797ad6
--- /dev/null
+++ b/src/client/app/desktop/views/components/note-detail.vue
@@ -0,0 +1,448 @@
+<template>
+<div class="mk-note-detail" :title="title">
+ <button
+ class="read-more"
+ v-if="p.reply && p.reply.replyId && context == null"
+ title="会話をもっと読み込む"
+ @click="fetchContext"
+ :disabled="contextFetching"
+ >
+ <template v-if="!contextFetching">%fa:ellipsis-v%</template>
+ <template v-if="contextFetching">%fa:spinner .pulse%</template>
+ </button>
+ <div class="context">
+ <x-sub v-for="note in context" :key="note.id" :note="note"/>
+ </div>
+ <div class="reply-to" v-if="p.reply">
+ <x-sub :note="p.reply"/>
+ </div>
+ <div class="renote" v-if="isRenote">
+ <p>
+ <router-link class="avatar-anchor" :to="`/@${acct}`" v-user-preview="note.userId">
+ <img class="avatar" :src="`${note.user.avatarUrl}?thumbnail&size=32`" alt="avatar"/>
+ </router-link>
+ %fa:retweet%
+ <router-link class="name" :href="`/@${acct}`">{{ getUserName(note.user) }}</router-link>
+ がRenote
+ </p>
+ </div>
+ <article>
+ <router-link class="avatar-anchor" :to="`/@${pAcct}`">
+ <img class="avatar" :src="`${p.user.avatarUrl}?thumbnail&size=64`" alt="avatar" v-user-preview="p.user.id"/>
+ </router-link>
+ <header>
+ <router-link class="name" :to="`/@${pAcct}`" v-user-preview="p.user.id">{{ getUserName(p.user) }}</router-link>
+ <span class="username">@{{ pAcct }}</span>
+ <router-link class="time" :to="`/@${pAcct}/${p.id}`">
+ <mk-time :time="p.createdAt"/>
+ </router-link>
+ </header>
+ <div class="body">
+ <mk-note-html :class="$style.text" v-if="p.text" :text="p.text" :i="os.i"/>
+ <div class="media" v-if="p.media.length > 0">
+ <mk-media-list :media-list="p.media"/>
+ </div>
+ <mk-poll v-if="p.poll" :note="p"/>
+ <mk-url-preview v-for="url in urls" :url="url" :key="url"/>
+ <div class="tags" v-if="p.tags && p.tags.length > 0">
+ <router-link v-for="tag in p.tags" :key="tag" :to="`/search?q=#${tag}`">{{ tag }}</router-link>
+ </div>
+ <a class="location" v-if="p.geo" :href="`http://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% 位置情報</a>
+ <div class="map" v-if="p.geo" ref="map"></div>
+ <div class="renote" v-if="p.renote">
+ <mk-note-preview :note="p.renote"/>
+ </div>
+ </div>
+ <footer>
+ <mk-reactions-viewer :note="p"/>
+ <button @click="reply" title="返信">
+ %fa:reply%<p class="count" v-if="p.repliesCount > 0">{{ p.repliesCount }}</p>
+ </button>
+ <button @click="renote" title="Renote">
+ %fa:retweet%<p class="count" v-if="p.renoteCount > 0">{{ p.renoteCount }}</p>
+ </button>
+ <button :class="{ reacted: p.myReaction != null }" @click="react" ref="reactButton" title="リアクション">
+ %fa:plus%<p class="count" v-if="p.reactions_count > 0">{{ p.reactions_count }}</p>
+ </button>
+ <button @click="menu" ref="menuButton">
+ %fa:ellipsis-h%
+ </button>
+ </footer>
+ </article>
+ <div class="replies" v-if="!compact">
+ <x-sub v-for="note in replies" :key="note.id" :note="note"/>
+ </div>
+</div>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+import dateStringify from '../../../common/scripts/date-stringify';
+import getAcct from '../../../../../acct/render';
+import getUserName from '../../../../../renderers/get-user-name';
+import parse from '../../../../../text/parse';
+
+import MkPostFormWindow from './post-form-window.vue';
+import MkRenoteFormWindow from './renote-form-window.vue';
+import MkNoteMenu from '../../../common/views/components/note-menu.vue';
+import MkReactionPicker from '../../../common/views/components/reaction-picker.vue';
+import XSub from './note-detail.sub.vue';
+
+export default Vue.extend({
+ components: {
+ XSub
+ },
+
+ props: {
+ note: {
+ type: Object,
+ required: true
+ },
+ compact: {
+ default: false
+ }
+ },
+
+ data() {
+ return {
+ context: [],
+ contextFetching: false,
+ replies: []
+ };
+ },
+
+ computed: {
+ isRenote(): boolean {
+ return (this.note.renote &&
+ this.note.text == null &&
+ this.note.mediaIds == null &&
+ this.note.poll == null);
+ },
+ p(): any {
+ return this.isRenote ? this.note.renote : this.note;
+ },
+ reactionsCount(): number {
+ return this.p.reactionCounts
+ ? Object.keys(this.p.reactionCounts)
+ .map(key => this.p.reactionCounts[key])
+ .reduce((a, b) => a + b)
+ : 0;
+ },
+ title(): string {
+ return dateStringify(this.p.createdAt);
+ },
+ acct(): string {
+ return getAcct(this.note.user);
+ },
+ name(): string {
+ return getUserName(this.note.user);
+ },
+ pAcct(): string {
+ return getAcct(this.p.user);
+ },
+ pName(): string {
+ return getUserName(this.p.user);
+ },
+ urls(): string[] {
+ if (this.p.text) {
+ const ast = parse(this.p.text);
+ return ast
+ .filter(t => (t.type == 'url' || t.type == 'link') && !t.silent)
+ .map(t => t.url);
+ } else {
+ return null;
+ }
+ }
+ },
+
+ mounted() {
+ // Get replies
+ if (!this.compact) {
+ (this as any).api('notes/replies', {
+ noteId: this.p.id,
+ limit: 8
+ }).then(replies => {
+ this.replies = replies;
+ });
+ }
+
+ // Draw map
+ if (this.p.geo) {
+ const shouldShowMap = (this as any).os.isSignedIn ? (this as any).os.i.account.clientSettings.showMaps : true;
+ if (shouldShowMap) {
+ (this as any).os.getGoogleMaps().then(maps => {
+ const uluru = new maps.LatLng(this.p.geo.coordinates[1], this.p.geo.coordinates[0]);
+ const map = new maps.Map(this.$refs.map, {
+ center: uluru,
+ zoom: 15
+ });
+ new maps.Marker({
+ position: uluru,
+ map: map
+ });
+ });
+ }
+ }
+ },
+
+ methods: {
+ fetchContext() {
+ this.contextFetching = true;
+
+ // Fetch context
+ (this as any).api('notes/context', {
+ noteId: this.p.replyId
+ }).then(context => {
+ this.contextFetching = false;
+ this.context = context.reverse();
+ });
+ },
+ reply() {
+ (this as any).os.new(MkPostFormWindow, {
+ reply: this.p
+ });
+ },
+ renote() {
+ (this as any).os.new(MkRenoteFormWindow, {
+ note: this.p
+ });
+ },
+ react() {
+ (this as any).os.new(MkReactionPicker, {
+ source: this.$refs.reactButton,
+ note: this.p
+ });
+ },
+ menu() {
+ (this as any).os.new(MkNoteMenu, {
+ source: this.$refs.menuButton,
+ note: this.p
+ });
+ }
+ }
+});
+</script>
+
+<style lang="stylus" scoped>
+@import '~const.styl'
+
+.mk-note-detail
+ margin 0
+ padding 0
+ overflow hidden
+ text-align left
+ background #fff
+ border solid 1px rgba(0, 0, 0, 0.1)
+ border-radius 8px
+
+ > .read-more
+ display block
+ margin 0
+ padding 10px 0
+ width 100%
+ font-size 1em
+ text-align center
+ color #999
+ cursor pointer
+ background #fafafa
+ outline none
+ border none
+ border-bottom solid 1px #eef0f2
+ border-radius 6px 6px 0 0
+
+ &:hover
+ background #f6f6f6
+
+ &:active
+ background #f0f0f0
+
+ &:disabled
+ color #ccc
+
+ > .context
+ > *
+ border-bottom 1px solid #eef0f2
+
+ > .renote
+ color #9dbb00
+ background linear-gradient(to bottom, #edfde2 0%, #fff 100%)
+
+ > p
+ margin 0
+ padding 16px 32px
+
+ .avatar-anchor
+ display inline-block
+
+ .avatar
+ vertical-align bottom
+ min-width 28px
+ min-height 28px
+ max-width 28px
+ max-height 28px
+ margin 0 8px 0 0
+ border-radius 6px
+
+ [data-fa]
+ margin-right 4px
+
+ .name
+ font-weight bold
+
+ & + article
+ padding-top 8px
+
+ > .reply-to
+ border-bottom 1px solid #eef0f2
+
+ > article
+ padding 28px 32px 18px 32px
+
+ &:after
+ content ""
+ display block
+ clear both
+
+ &:hover
+ > .main > footer > button
+ color #888
+
+ > .avatar-anchor
+ display block
+ width 60px
+ height 60px
+
+ > .avatar
+ display block
+ width 60px
+ height 60px
+ margin 0
+ border-radius 8px
+ vertical-align bottom
+
+ > header
+ position absolute
+ top 28px
+ left 108px
+ width calc(100% - 108px)
+
+ > .name
+ display inline-block
+ margin 0
+ line-height 24px
+ color #777
+ font-size 18px
+ font-weight 700
+ text-align left
+ text-decoration none
+
+ &:hover
+ text-decoration underline
+
+ > .username
+ display block
+ text-align left
+ margin 0
+ color #ccc
+
+ > .time
+ position absolute
+ top 0
+ right 32px
+ font-size 1em
+ color #c0c0c0
+
+ > .body
+ padding 8px 0
+
+ > .renote
+ margin 8px 0
+
+ > .mk-note-preview
+ padding 16px
+ border dashed 1px #c0dac6
+ border-radius 8px
+
+ > .location
+ margin 4px 0
+ font-size 12px
+ color #ccc
+
+ > .map
+ width 100%
+ height 300px
+
+ &:empty
+ display none
+
+ > .mk-url-preview
+ margin-top 8px
+
+ > .tags
+ margin 4px 0 0 0
+
+ > *
+ display inline-block
+ margin 0 8px 0 0
+ padding 2px 8px 2px 16px
+ font-size 90%
+ color #8d969e
+ background #edf0f3
+ border-radius 4px
+
+ &:before
+ content ""
+ display block
+ position absolute
+ top 0
+ bottom 0
+ left 4px
+ width 8px
+ height 8px
+ margin auto 0
+ background #fff
+ border-radius 100%
+
+ &:hover
+ text-decoration none
+ background #e2e7ec
+
+ > footer
+ font-size 1.2em
+
+ > button
+ margin 0 28px 0 0
+ padding 8px
+ background transparent
+ border none
+ font-size 1em
+ color #ddd
+ cursor pointer
+
+ &:hover
+ color #666
+
+ > .count
+ display inline
+ margin 0 0 0 8px
+ color #999
+
+ &.reacted
+ color $theme-color
+
+ > .replies
+ > *
+ border-top 1px solid #eef0f2
+
+</style>
+
+<style lang="stylus" module>
+.text
+ cursor default
+ display block
+ margin 0
+ padding 0
+ overflow-wrap break-word
+ font-size 1.5em
+ color #717171
+</style>
diff --git a/src/client/app/desktop/views/components/post-preview.vue b/src/client/app/desktop/views/components/note-preview.vue
index 99d9442d93..bff199c09d 100644
--- a/src/client/app/desktop/views/components/post-preview.vue
+++ b/src/client/app/desktop/views/components/note-preview.vue
@@ -1,18 +1,18 @@
<template>
-<div class="mk-post-preview" :title="title">
+<div class="mk-note-preview" :title="title">
<router-link class="avatar-anchor" :to="`/@${acct}`">
- <img class="avatar" :src="`${post.user.avatarUrl}?thumbnail&size=64`" alt="avatar" v-user-preview="post.userId"/>
+ <img class="avatar" :src="`${note.user.avatarUrl}?thumbnail&size=64`" alt="avatar" v-user-preview="note.userId"/>
</router-link>
<div class="main">
<header>
- <router-link class="name" :to="`/@${acct}`" v-user-preview="post.userId">{{ name }}</router-link>
+ <router-link class="name" :to="`/@${acct}`" v-user-preview="note.userId">{{ name }}</router-link>
<span class="username">@{{ acct }}</span>
- <router-link class="time" :to="`/@${acct}/${post.id}`">
- <mk-time :time="post.createdAt"/>
+ <router-link class="time" :to="`/@${acct}/${note.id}`">
+ <mk-time :time="note.createdAt"/>
</router-link>
</header>
<div class="body">
- <mk-sub-post-content class="text" :post="post"/>
+ <mk-sub-note-content class="text" :note="note"/>
</div>
</div>
</div>
@@ -25,23 +25,23 @@ import getAcct from '../../../../../acct/render';
import getUserName from '../../../../../renderers/get-user-name';
export default Vue.extend({
- props: ['post'],
+ props: ['note'],
computed: {
acct() {
- return getAcct(this.post.user);
+ return getAcct(this.note.user);
},
name() {
- return getUserName(this.post.user);
+ return getUserName(this.note.user);
},
title(): string {
- return dateStringify(this.post.createdAt);
+ return dateStringify(this.note.createdAt);
}
}
});
</script>
<style lang="stylus" scoped>
-.mk-post-preview
+.mk-note-preview
font-size 0.9em
background #fff
diff --git a/src/client/app/desktop/views/components/posts.post.sub.vue b/src/client/app/desktop/views/components/notes.note.sub.vue
index a9cd0a9279..b49d12b92e 100644
--- a/src/client/app/desktop/views/components/posts.post.sub.vue
+++ b/src/client/app/desktop/views/components/notes.note.sub.vue
@@ -1,18 +1,18 @@
<template>
<div class="sub" :title="title">
<router-link class="avatar-anchor" :to="`/@${acct}`">
- <img class="avatar" :src="`${post.user.avatarUrl}?thumbnail&size=64`" alt="avatar" v-user-preview="post.userId"/>
+ <img class="avatar" :src="`${note.user.avatarUrl}?thumbnail&size=64`" alt="avatar" v-user-preview="note.userId"/>
</router-link>
<div class="main">
<header>
- <router-link class="name" :to="`/@${acct}`" v-user-preview="post.userId">{{ name }}</router-link>
+ <router-link class="name" :to="`/@${acct}`" v-user-preview="note.userId">{{ name }}</router-link>
<span class="username">@{{ acct }}</span>
- <router-link class="created-at" :to="`/@${acct}/${post.id}`">
- <mk-time :time="post.createdAt"/>
+ <router-link class="created-at" :to="`/@${acct}/${note.id}`">
+ <mk-time :time="note.createdAt"/>
</router-link>
</header>
<div class="body">
- <mk-sub-post-content class="text" :post="post"/>
+ <mk-sub-note-content class="text" :note="note"/>
</div>
</div>
</div>
@@ -25,16 +25,16 @@ import getAcct from '../../../../../acct/render';
import getUserName from '../../../../../renderers/get-user-name';
export default Vue.extend({
- props: ['post'],
+ props: ['note'],
computed: {
acct() {
- return getAcct(this.post.user);
+ return getAcct(this.note.user);
},
name(): string {
- return getUserName(this.post.user);
+ return getUserName(this.note.user);
},
title(): string {
- return dateStringify(this.post.createdAt);
+ return dateStringify(this.note.createdAt);
}
}
});
diff --git a/src/client/app/desktop/views/components/notes.note.vue b/src/client/app/desktop/views/components/notes.note.vue
new file mode 100644
index 0000000000..924642c01a
--- /dev/null
+++ b/src/client/app/desktop/views/components/notes.note.vue
@@ -0,0 +1,596 @@
+<template>
+<div class="note" tabindex="-1" :title="title" @keydown="onKeydown">
+ <div class="reply-to" v-if="p.reply">
+ <x-sub :note="p.reply"/>
+ </div>
+ <div class="renote" v-if="isRenote">
+ <p>
+ <router-link class="avatar-anchor" :to="`/@${acct}`" v-user-preview="note.userId">
+ <img class="avatar" :src="`${note.user.avatarUrl}?thumbnail&size=32`" alt="avatar"/>
+ </router-link>
+ %fa:retweet%
+ <span>{{ '%i18n:desktop.tags.mk-timeline-note.reposted-by%'.substr(0, '%i18n:desktop.tags.mk-timeline-note.reposted-by%'.indexOf('{')) }}</span>
+ <a class="name" :href="`/@${acct}`" v-user-preview="note.userId">{{ getUserName(note.user) }}</a>
+ <span>{{ '%i18n:desktop.tags.mk-timeline-note.reposted-by%'.substr('%i18n:desktop.tags.mk-timeline-note.reposted-by%'.indexOf('}') + 1) }}</span>
+ </p>
+ <mk-time :time="note.createdAt"/>
+ </div>
+ <article>
+ <router-link class="avatar-anchor" :to="`/@${acct}`">
+ <img class="avatar" :src="`${p.user.avatarUrl}?thumbnail&size=64`" alt="avatar" v-user-preview="p.user.id"/>
+ </router-link>
+ <div class="main">
+ <header>
+ <router-link class="name" :to="`/@${acct}`" v-user-preview="p.user.id">{{ acct }}</router-link>
+ <span class="is-bot" v-if="p.user.host === null && p.user.account.isBot">bot</span>
+ <span class="username">@{{ acct }}</span>
+ <div class="info">
+ <span class="app" v-if="p.app">via <b>{{ p.app.name }}</b></span>
+ <span class="mobile" v-if="p.viaMobile">%fa:mobile-alt%</span>
+ <router-link class="created-at" :to="url">
+ <mk-time :time="p.createdAt"/>
+ </router-link>
+ </div>
+ </header>
+ <div class="body">
+ <p class="channel" v-if="p.channel">
+ <a :href="`${_CH_URL_}/${p.channel.id}`" target="_blank">{{ p.channel.title }}</a>:
+ </p>
+ <div class="text">
+ <a class="reply" v-if="p.reply">%fa:reply%</a>
+ <mk-note-html v-if="p.textHtml" :text="p.text" :i="os.i" :class="$style.text"/>
+ <a class="rp" v-if="p.renote">RP:</a>
+ </div>
+ <div class="media" v-if="p.media.length > 0">
+ <mk-media-list :media-list="p.media"/>
+ </div>
+ <mk-poll v-if="p.poll" :note="p" ref="pollViewer"/>
+ <div class="tags" v-if="p.tags && p.tags.length > 0">
+ <router-link v-for="tag in p.tags" :key="tag" :to="`/search?q=#${tag}`">{{ tag }}</router-link>
+ </div>
+ <a class="location" v-if="p.geo" :href="`http://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% 位置情報</a>
+ <div class="map" v-if="p.geo" ref="map"></div>
+ <div class="renote" v-if="p.renote">
+ <mk-note-preview :note="p.renote"/>
+ </div>
+ <mk-url-preview v-for="url in urls" :url="url" :key="url"/>
+ </div>
+ <footer>
+ <mk-reactions-viewer :note="p" ref="reactionsViewer"/>
+ <button @click="reply" title="%i18n:desktop.tags.mk-timeline-note.reply%">
+ %fa:reply%<p class="count" v-if="p.repliesCount > 0">{{ p.repliesCount }}</p>
+ </button>
+ <button @click="renote" title="%i18n:desktop.tags.mk-timeline-note.renote%">
+ %fa:retweet%<p class="count" v-if="p.renoteCount > 0">{{ p.renoteCount }}</p>
+ </button>
+ <button :class="{ reacted: p.myReaction != null }" @click="react" ref="reactButton" title="%i18n:desktop.tags.mk-timeline-note.add-reaction%">
+ %fa:plus%<p class="count" v-if="p.reactions_count > 0">{{ p.reactions_count }}</p>
+ </button>
+ <button @click="menu" ref="menuButton">
+ %fa:ellipsis-h%
+ </button>
+ <button title="%i18n:desktop.tags.mk-timeline-note.detail">
+ <template v-if="!isDetailOpened">%fa:caret-down%</template>
+ <template v-if="isDetailOpened">%fa:caret-up%</template>
+ </button>
+ </footer>
+ </div>
+ </article>
+ <div class="detail" v-if="isDetailOpened">
+ <mk-note-status-graph width="462" height="130" :note="p"/>
+ </div>
+</div>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+import dateStringify from '../../../common/scripts/date-stringify';
+import getAcct from '../../../../../acct/render';
+import getUserName from '../../../../../renderers/get-user-name';
+import parse from '../../../../../text/parse';
+
+import MkPostFormWindow from './post-form-window.vue';
+import MkRenoteFormWindow from './renote-form-window.vue';
+import MkNoteMenu from '../../../common/views/components/note-menu.vue';
+import MkReactionPicker from '../../../common/views/components/reaction-picker.vue';
+import XSub from './notes.note.sub.vue';
+
+function focus(el, fn) {
+ const target = fn(el);
+ if (target) {
+ if (target.hasAttribute('tabindex')) {
+ target.focus();
+ } else {
+ focus(target, fn);
+ }
+ }
+}
+
+export default Vue.extend({
+ components: {
+ XSub
+ },
+
+ props: ['note'],
+
+ data() {
+ return {
+ isDetailOpened: false,
+ connection: null,
+ connectionId: null
+ };
+ },
+
+ computed: {
+ acct(): string {
+ return getAcct(this.p.user);
+ },
+ name(): string {
+ return getUserName(this.p.user);
+ },
+ isRenote(): boolean {
+ return (this.note.renote &&
+ this.note.text == null &&
+ this.note.mediaIds == null &&
+ this.note.poll == null);
+ },
+ p(): any {
+ return this.isRenote ? this.note.renote : this.note;
+ },
+ reactionsCount(): number {
+ return this.p.reactionCounts
+ ? Object.keys(this.p.reactionCounts)
+ .map(key => this.p.reactionCounts[key])
+ .reduce((a, b) => a + b)
+ : 0;
+ },
+ title(): string {
+ return dateStringify(this.p.createdAt);
+ },
+ url(): string {
+ return `/@${this.acct}/${this.p.id}`;
+ },
+ urls(): string[] {
+ if (this.p.text) {
+ const ast = parse(this.p.text);
+ return ast
+ .filter(t => (t.type == 'url' || t.type == 'link') && !t.silent)
+ .map(t => t.url);
+ } else {
+ return null;
+ }
+ }
+ },
+
+ created() {
+ if ((this as any).os.isSignedIn) {
+ this.connection = (this as any).os.stream.getConnection();
+ this.connectionId = (this as any).os.stream.use();
+ }
+ },
+
+ mounted() {
+ this.capture(true);
+
+ if ((this as any).os.isSignedIn) {
+ this.connection.on('_connected_', this.onStreamConnected);
+ }
+
+ // Draw map
+ if (this.p.geo) {
+ const shouldShowMap = (this as any).os.isSignedIn ? (this as any).os.i.account.clientSettings.showMaps : true;
+ if (shouldShowMap) {
+ (this as any).os.getGoogleMaps().then(maps => {
+ const uluru = new maps.LatLng(this.p.geo.coordinates[1], this.p.geo.coordinates[0]);
+ const map = new maps.Map(this.$refs.map, {
+ center: uluru,
+ zoom: 15
+ });
+ new maps.Marker({
+ position: uluru,
+ map: map
+ });
+ });
+ }
+ }
+ },
+
+ beforeDestroy() {
+ this.decapture(true);
+
+ if ((this as any).os.isSignedIn) {
+ this.connection.off('_connected_', this.onStreamConnected);
+ (this as any).os.stream.dispose(this.connectionId);
+ }
+ },
+
+ methods: {
+ capture(withHandler = false) {
+ if ((this as any).os.isSignedIn) {
+ this.connection.send({
+ type: 'capture',
+ id: this.p.id
+ });
+ if (withHandler) this.connection.on('note-updated', this.onStreamNoteUpdated);
+ }
+ },
+ decapture(withHandler = false) {
+ if ((this as any).os.isSignedIn) {
+ this.connection.send({
+ type: 'decapture',
+ id: this.p.id
+ });
+ if (withHandler) this.connection.off('note-updated', this.onStreamNoteUpdated);
+ }
+ },
+ onStreamConnected() {
+ this.capture();
+ },
+ onStreamNoteUpdated(data) {
+ const note = data.note;
+ if (note.id == this.note.id) {
+ this.$emit('update:note', note);
+ } else if (note.id == this.note.renoteId) {
+ this.note.renote = note;
+ }
+ },
+ reply() {
+ (this as any).os.new(MkPostFormWindow, {
+ reply: this.p
+ });
+ },
+ renote() {
+ (this as any).os.new(MkRenoteFormWindow, {
+ note: this.p
+ });
+ },
+ react() {
+ (this as any).os.new(MkReactionPicker, {
+ source: this.$refs.reactButton,
+ note: this.p
+ });
+ },
+ menu() {
+ (this as any).os.new(MkNoteMenu, {
+ source: this.$refs.menuButton,
+ note: this.p
+ });
+ },
+ onKeydown(e) {
+ let shouldBeCancel = true;
+
+ switch (true) {
+ case e.which == 38: // [↑]
+ case e.which == 74: // [j]
+ case e.which == 9 && e.shiftKey: // [Shift] + [Tab]
+ focus(this.$el, e => e.previousElementSibling);
+ break;
+
+ case e.which == 40: // [↓]
+ case e.which == 75: // [k]
+ case e.which == 9: // [Tab]
+ focus(this.$el, e => e.nextElementSibling);
+ break;
+
+ case e.which == 81: // [q]
+ case e.which == 69: // [e]
+ this.renote();
+ break;
+
+ case e.which == 70: // [f]
+ case e.which == 76: // [l]
+ //this.like();
+ break;
+
+ case e.which == 82: // [r]
+ this.reply();
+ break;
+
+ default:
+ shouldBeCancel = false;
+ }
+
+ if (shouldBeCancel) e.preventDefault();
+ }
+ }
+});
+</script>
+
+<style lang="stylus" scoped>
+@import '~const.styl'
+
+.note
+ margin 0
+ padding 0
+ background #fff
+ border-bottom solid 1px #eaeaea
+
+ &:first-child
+ border-top-left-radius 6px
+ border-top-right-radius 6px
+
+ > .renote
+ border-top-left-radius 6px
+ border-top-right-radius 6px
+
+ &:last-of-type
+ border-bottom none
+
+ &:focus
+ z-index 1
+
+ &:after
+ content ""
+ pointer-events none
+ position absolute
+ top 2px
+ right 2px
+ bottom 2px
+ left 2px
+ border 2px solid rgba($theme-color, 0.3)
+ border-radius 4px
+
+ > .renote
+ color #9dbb00
+ background linear-gradient(to bottom, #edfde2 0%, #fff 100%)
+
+ > p
+ margin 0
+ padding 16px 32px
+ line-height 28px
+
+ .avatar-anchor
+ display inline-block
+
+ .avatar
+ vertical-align bottom
+ width 28px
+ height 28px
+ margin 0 8px 0 0
+ border-radius 6px
+
+ [data-fa]
+ margin-right 4px
+
+ .name
+ font-weight bold
+
+ > .mk-time
+ position absolute
+ top 16px
+ right 32px
+ font-size 0.9em
+ line-height 28px
+
+ & + article
+ padding-top 8px
+
+ > .reply-to
+ padding 0 16px
+ background rgba(0, 0, 0, 0.0125)
+
+ > .mk-note-preview
+ background transparent
+
+ > article
+ padding 28px 32px 18px 32px
+
+ &:after
+ content ""
+ display block
+ clear both
+
+ &:hover
+ > .main > footer > button
+ color #888
+
+ > .avatar-anchor
+ display block
+ float left
+ margin 0 16px 10px 0
+ //position -webkit-sticky
+ //position sticky
+ //top 74px
+
+ > .avatar
+ display block
+ width 58px
+ height 58px
+ margin 0
+ border-radius 8px
+ vertical-align bottom
+
+ > .main
+ float left
+ width calc(100% - 74px)
+
+ > header
+ display flex
+ align-items center
+ margin-bottom 4px
+ white-space nowrap
+
+ > .name
+ display block
+ margin 0 .5em 0 0
+ padding 0
+ overflow hidden
+ color #627079
+ font-size 1em
+ font-weight bold
+ text-decoration none
+ text-overflow ellipsis
+
+ &:hover
+ text-decoration underline
+
+ > .is-bot
+ margin 0 .5em 0 0
+ padding 1px 6px
+ font-size 12px
+ color #aaa
+ border solid 1px #ddd
+ border-radius 3px
+
+ > .username
+ margin 0 .5em 0 0
+ color #ccc
+
+ > .info
+ margin-left auto
+ font-size 0.9em
+
+ > .mobile
+ margin-right 8px
+ color #ccc
+
+ > .app
+ margin-right 8px
+ padding-right 8px
+ color #ccc
+ border-right solid 1px #eaeaea
+
+ > .created-at
+ color #c0c0c0
+
+ > .body
+
+ > .text
+ cursor default
+ display block
+ margin 0
+ padding 0
+ overflow-wrap break-word
+ font-size 1.1em
+ color #717171
+
+ >>> .quote
+ margin 8px
+ padding 6px 12px
+ color #aaa
+ border-left solid 3px #eee
+
+ > .reply
+ margin-right 8px
+ color #717171
+
+ > .rp
+ margin-left 4px
+ font-style oblique
+ color #a0bf46
+
+ > .location
+ margin 4px 0
+ font-size 12px
+ color #ccc
+
+ > .map
+ width 100%
+ height 300px
+
+ &:empty
+ display none
+
+ > .tags
+ margin 4px 0 0 0
+
+ > *
+ display inline-block
+ margin 0 8px 0 0
+ padding 2px 8px 2px 16px
+ font-size 90%
+ color #8d969e
+ background #edf0f3
+ border-radius 4px
+
+ &:before
+ content ""
+ display block
+ position absolute
+ top 0
+ bottom 0
+ left 4px
+ width 8px
+ height 8px
+ margin auto 0
+ background #fff
+ border-radius 100%
+
+ &:hover
+ text-decoration none
+ background #e2e7ec
+
+ .mk-url-preview
+ margin-top 8px
+
+ > .channel
+ margin 0
+
+ > .mk-poll
+ font-size 80%
+
+ > .renote
+ margin 8px 0
+
+ > .mk-note-preview
+ padding 16px
+ border dashed 1px #c0dac6
+ border-radius 8px
+
+ > footer
+ > button
+ margin 0 28px 0 0
+ padding 0 8px
+ line-height 32px
+ font-size 1em
+ color #ddd
+ background transparent
+ border none
+ cursor pointer
+
+ &:hover
+ color #666
+
+ > .count
+ display inline
+ margin 0 0 0 8px
+ color #999
+
+ &.reacted
+ color $theme-color
+
+ &:last-child
+ position absolute
+ right 0
+ margin 0
+
+ > .detail
+ padding-top 4px
+ background rgba(0, 0, 0, 0.0125)
+
+</style>
+
+<style lang="stylus" module>
+.text
+
+ code
+ padding 4px 8px
+ margin 0 0.5em
+ font-size 80%
+ color #525252
+ background #f8f8f8
+ border-radius 2px
+
+ pre > code
+ padding 16px
+ margin 0
+
+ [data-is-me]:after
+ content "you"
+ padding 0 4px
+ margin-left 4px
+ font-size 80%
+ color $theme-color-foreground
+ background $theme-color
+ border-radius 4px
+</style>
diff --git a/src/client/app/desktop/views/components/posts.vue b/src/client/app/desktop/views/components/notes.vue
index 5031667c7c..b5f6957a16 100644
--- a/src/client/app/desktop/views/components/posts.vue
+++ b/src/client/app/desktop/views/components/notes.vue
@@ -1,10 +1,10 @@
<template>
-<div class="mk-posts">
- <template v-for="(post, i) in _posts">
- <x-post :post="post" :key="post.id" @update:post="onPostUpdated(i, $event)"/>
- <p class="date" v-if="i != posts.length - 1 && post._date != _posts[i + 1]._date">
- <span>%fa:angle-up%{{ post._datetext }}</span>
- <span>%fa:angle-down%{{ _posts[i + 1]._datetext }}</span>
+<div class="mk-notes">
+ <template v-for="(note, i) in _notes">
+ <x-note :note="note" :key="note.id" @update:note="onNoteUpdated(i, $event)"/>
+ <p class="date" v-if="i != notes.length - 1 && note._date != _notes[i + 1]._date">
+ <span>%fa:angle-up%{{ note._datetext }}</span>
+ <span>%fa:angle-down%{{ _notes[i + 1]._datetext }}</span>
</p>
</template>
<footer>
@@ -15,26 +15,26 @@
<script lang="ts">
import Vue from 'vue';
-import XPost from './posts.post.vue';
+import XNote from './notes.note.vue';
export default Vue.extend({
components: {
- XPost
+ XNote
},
props: {
- posts: {
+ notes: {
type: Array,
default: () => []
}
},
computed: {
- _posts(): any[] {
- return (this.posts as any).map(post => {
- const date = new Date(post.createdAt).getDate();
- const month = new Date(post.createdAt).getMonth() + 1;
- post._date = date;
- post._datetext = `${month}月 ${date}日`;
- return post;
+ _notes(): any[] {
+ return (this.notes as any).map(note => {
+ const date = new Date(note.createdAt).getDate();
+ const month = new Date(note.createdAt).getMonth() + 1;
+ note._date = date;
+ note._datetext = `${month}月 ${date}日`;
+ return note;
});
}
},
@@ -42,15 +42,15 @@ export default Vue.extend({
focus() {
(this.$el as any).children[0].focus();
},
- onPostUpdated(i, post) {
- Vue.set((this as any).posts, i, post);
+ onNoteUpdated(i, note) {
+ Vue.set((this as any).notes, i, note);
}
}
});
</script>
<style lang="stylus" scoped>
-.mk-posts
+.mk-notes
> .date
display block
diff --git a/src/client/app/desktop/views/components/notifications.vue b/src/client/app/desktop/views/components/notifications.vue
index d8b8eab212..100a803cc2 100644
--- a/src/client/app/desktop/views/components/notifications.vue
+++ b/src/client/app/desktop/views/components/notifications.vue
@@ -13,33 +13,33 @@
<mk-reaction-icon :reaction="notification.reaction"/>
<router-link :to="`/@${getAcct(notification.user)}`" v-user-preview="notification.user.id">{{ getUserName(notification.user) }}</router-link>
</p>
- <router-link class="post-ref" :to="`/@${getAcct(notification.post.user)}/${notification.post.id}`">
- %fa:quote-left%{{ getPostSummary(notification.post) }}%fa:quote-right%
+ <router-link class="note-ref" :to="`/@${getAcct(notification.note.user)}/${notification.note.id}`">
+ %fa:quote-left%{{ getNoteSummary(notification.note) }}%fa:quote-right%
</router-link>
</div>
</template>
- <template v-if="notification.type == 'repost'">
- <router-link class="avatar-anchor" :to="`/@${getAcct(notification.post.user)}`" v-user-preview="notification.post.userId">
- <img class="avatar" :src="`${notification.post.user.avatarUrl}?thumbnail&size=48`" alt="avatar"/>
+ <template v-if="notification.type == 'renote'">
+ <router-link class="avatar-anchor" :to="`/@${getAcct(notification.note.user)}`" v-user-preview="notification.note.userId">
+ <img class="avatar" :src="`${notification.note.user.avatarUrl}?thumbnail&size=48`" alt="avatar"/>
</router-link>
<div class="text">
<p>%fa:retweet%
- <router-link :to="`/@${getAcct(notification.post.user)}`" v-user-preview="notification.post.userId">{{ getUserName(notification.post.user) }}</router-link>
+ <router-link :to="`/@${getAcct(notification.note.user)}`" v-user-preview="notification.note.userId">{{ getUserName(notification.note.user) }}</router-link>
</p>
- <router-link class="post-ref" :to="`/@${getAcct(notification.post.user)}/${notification.post.id}`">
- %fa:quote-left%{{ getPostSummary(notification.post.repost) }}%fa:quote-right%
+ <router-link class="note-ref" :to="`/@${getAcct(notification.note.user)}/${notification.note.id}`">
+ %fa:quote-left%{{ getNoteSummary(notification.note.renote) }}%fa:quote-right%
</router-link>
</div>
</template>
<template v-if="notification.type == 'quote'">
- <router-link class="avatar-anchor" :to="`/@${getAcct(notification.post.user)}`" v-user-preview="notification.post.userId">
- <img class="avatar" :src="`${notification.post.user.avatarUrl}?thumbnail&size=48`" alt="avatar"/>
+ <router-link class="avatar-anchor" :to="`/@${getAcct(notification.note.user)}`" v-user-preview="notification.note.userId">
+ <img class="avatar" :src="`${notification.note.user.avatarUrl}?thumbnail&size=48`" alt="avatar"/>
</router-link>
<div class="text">
<p>%fa:quote-left%
- <router-link :to="`/@${getAcct(notification.post.user)}`" v-user-preview="notification.post.userId">{{ getUserName(notification.post.user) }}</router-link>
+ <router-link :to="`/@${getAcct(notification.note.user)}`" v-user-preview="notification.note.userId">{{ getUserName(notification.note.user) }}</router-link>
</p>
- <router-link class="post-preview" :to="`/@${getAcct(notification.post.user)}/${notification.post.id}`">{{ getPostSummary(notification.post) }}</router-link>
+ <router-link class="note-preview" :to="`/@${getAcct(notification.note.user)}/${notification.note.id}`">{{ getNoteSummary(notification.note) }}</router-link>
</div>
</template>
<template v-if="notification.type == 'follow'">
@@ -53,25 +53,25 @@
</div>
</template>
<template v-if="notification.type == 'reply'">
- <router-link class="avatar-anchor" :to="`/@${getAcct(notification.post.user)}`" v-user-preview="notification.post.userId">
- <img class="avatar" :src="`${notification.post.user.avatarUrl}?thumbnail&size=48`" alt="avatar"/>
+ <router-link class="avatar-anchor" :to="`/@${getAcct(notification.note.user)}`" v-user-preview="notification.note.userId">
+ <img class="avatar" :src="`${notification.note.user.avatarUrl}?thumbnail&size=48`" alt="avatar"/>
</router-link>
<div class="text">
<p>%fa:reply%
- <router-link :to="`/@${getAcct(notification.post.user)}`" v-user-preview="notification.post.userId">{{ getUserName(notification.post.user) }}</router-link>
+ <router-link :to="`/@${getAcct(notification.note.user)}`" v-user-preview="notification.note.userId">{{ getUserName(notification.note.user) }}</router-link>
</p>
- <router-link class="post-preview" :to="`/@${getAcct(notification.post.user)}/${notification.post.id}`">{{ getPostSummary(notification.post) }}</router-link>
+ <router-link class="note-preview" :to="`/@${getAcct(notification.note.user)}/${notification.note.id}`">{{ getNoteSummary(notification.note) }}</router-link>
</div>
</template>
<template v-if="notification.type == 'mention'">
- <router-link class="avatar-anchor" :to="`/@${getAcct(notification.post.user)}`" v-user-preview="notification.post.userId">
- <img class="avatar" :src="`${notification.post.user.avatarUrl}?thumbnail&size=48`" alt="avatar"/>
+ <router-link class="avatar-anchor" :to="`/@${getAcct(notification.note.user)}`" v-user-preview="notification.note.userId">
+ <img class="avatar" :src="`${notification.note.user.avatarUrl}?thumbnail&size=48`" alt="avatar"/>
</router-link>
<div class="text">
<p>%fa:at%
- <router-link :to="`/@${getAcct(notification.post.user)}`" v-user-preview="notification.post.userId">{{ getUserName(notification.post.user) }}</router-link>
+ <router-link :to="`/@${getAcct(notification.note.user)}`" v-user-preview="notification.note.userId">{{ getUserName(notification.note.user) }}</router-link>
</p>
- <a class="post-preview" :href="`/@${getAcct(notification.post.user)}/${notification.post.id}`">{{ getPostSummary(notification.post) }}</a>
+ <a class="note-preview" :href="`/@${getAcct(notification.note.user)}/${notification.note.id}`">{{ getNoteSummary(notification.note) }}</a>
</div>
</template>
<template v-if="notification.type == 'poll_vote'">
@@ -80,8 +80,8 @@
</router-link>
<div class="text">
<p>%fa:chart-pie%<a :href="`/@${getAcct(notification.user)}`" v-user-preview="notification.user.id">{{ getUserName(notification.user) }}</a></p>
- <router-link class="post-ref" :to="`/@${getAcct(notification.post.user)}/${notification.post.id}`">
- %fa:quote-left%{{ getPostSummary(notification.post) }}%fa:quote-right%
+ <router-link class="note-ref" :to="`/@${getAcct(notification.note.user)}/${notification.note.id}`">
+ %fa:quote-left%{{ getNoteSummary(notification.note) }}%fa:quote-right%
</router-link>
</div>
</template>
@@ -103,7 +103,7 @@
<script lang="ts">
import Vue from 'vue';
import getAcct from '../../../../../acct/render';
-import getPostSummary from '../../../../../renderers/get-post-summary';
+import getNoteSummary from '../../../../../renderers/get-note-summary';
import getUserName from '../../../../../renderers/get-user-name';
export default Vue.extend({
@@ -115,7 +115,7 @@ export default Vue.extend({
moreNotifications: false,
connection: null,
connectionId: null,
- getPostSummary
+ getNoteSummary
};
},
computed: {
@@ -241,10 +241,10 @@ export default Vue.extend({
i, .mk-reaction-icon
margin-right 4px
- .post-preview
+ .note-preview
color rgba(0, 0, 0, 0.7)
- .post-ref
+ .note-ref
color rgba(0, 0, 0, 0.7)
[data-fa]
@@ -254,7 +254,7 @@ export default Vue.extend({
display inline-block
margin-right 3px
- &.repost, &.quote
+ &.renote, &.quote
.text p i
color #77B255
diff --git a/src/client/app/desktop/views/components/post-detail.vue b/src/client/app/desktop/views/components/post-detail.vue
index 1a3c0d1b68..790f797ad6 100644
--- a/src/client/app/desktop/views/components/post-detail.vue
+++ b/src/client/app/desktop/views/components/post-detail.vue
@@ -1,5 +1,5 @@
<template>
-<div class="mk-post-detail" :title="title">
+<div class="mk-note-detail" :title="title">
<button
class="read-more"
v-if="p.reply && p.reply.replyId && context == null"
@@ -11,19 +11,19 @@
<template v-if="contextFetching">%fa:spinner .pulse%</template>
</button>
<div class="context">
- <x-sub v-for="post in context" :key="post.id" :post="post"/>
+ <x-sub v-for="note in context" :key="note.id" :note="note"/>
</div>
<div class="reply-to" v-if="p.reply">
- <x-sub :post="p.reply"/>
+ <x-sub :note="p.reply"/>
</div>
- <div class="repost" v-if="isRepost">
+ <div class="renote" v-if="isRenote">
<p>
- <router-link class="avatar-anchor" :to="`/@${acct}`" v-user-preview="post.userId">
- <img class="avatar" :src="`${post.user.avatarUrl}?thumbnail&size=32`" alt="avatar"/>
+ <router-link class="avatar-anchor" :to="`/@${acct}`" v-user-preview="note.userId">
+ <img class="avatar" :src="`${note.user.avatarUrl}?thumbnail&size=32`" alt="avatar"/>
</router-link>
%fa:retweet%
- <router-link class="name" :href="`/@${acct}`">{{ getUserName(post.user) }}</router-link>
- がRepost
+ <router-link class="name" :href="`/@${acct}`">{{ getUserName(note.user) }}</router-link>
+ がRenote
</p>
</div>
<article>
@@ -38,28 +38,28 @@
</router-link>
</header>
<div class="body">
- <mk-post-html :class="$style.text" v-if="p.text" :text="p.text" :i="os.i"/>
+ <mk-note-html :class="$style.text" v-if="p.text" :text="p.text" :i="os.i"/>
<div class="media" v-if="p.media.length > 0">
<mk-media-list :media-list="p.media"/>
</div>
- <mk-poll v-if="p.poll" :post="p"/>
+ <mk-poll v-if="p.poll" :note="p"/>
<mk-url-preview v-for="url in urls" :url="url" :key="url"/>
<div class="tags" v-if="p.tags && p.tags.length > 0">
<router-link v-for="tag in p.tags" :key="tag" :to="`/search?q=#${tag}`">{{ tag }}</router-link>
</div>
<a class="location" v-if="p.geo" :href="`http://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% 位置情報</a>
<div class="map" v-if="p.geo" ref="map"></div>
- <div class="repost" v-if="p.repost">
- <mk-post-preview :post="p.repost"/>
+ <div class="renote" v-if="p.renote">
+ <mk-note-preview :note="p.renote"/>
</div>
</div>
<footer>
- <mk-reactions-viewer :post="p"/>
+ <mk-reactions-viewer :note="p"/>
<button @click="reply" title="返信">
%fa:reply%<p class="count" v-if="p.repliesCount > 0">{{ p.repliesCount }}</p>
</button>
- <button @click="repost" title="Repost">
- %fa:retweet%<p class="count" v-if="p.repostCount > 0">{{ p.repostCount }}</p>
+ <button @click="renote" title="Renote">
+ %fa:retweet%<p class="count" v-if="p.renoteCount > 0">{{ p.renoteCount }}</p>
</button>
<button :class="{ reacted: p.myReaction != null }" @click="react" ref="reactButton" title="リアクション">
%fa:plus%<p class="count" v-if="p.reactions_count > 0">{{ p.reactions_count }}</p>
@@ -70,7 +70,7 @@
</footer>
</article>
<div class="replies" v-if="!compact">
- <x-sub v-for="post in replies" :key="post.id" :post="post"/>
+ <x-sub v-for="note in replies" :key="note.id" :note="note"/>
</div>
</div>
</template>
@@ -83,10 +83,10 @@ import getUserName from '../../../../../renderers/get-user-name';
import parse from '../../../../../text/parse';
import MkPostFormWindow from './post-form-window.vue';
-import MkRepostFormWindow from './repost-form-window.vue';
-import MkPostMenu from '../../../common/views/components/post-menu.vue';
+import MkRenoteFormWindow from './renote-form-window.vue';
+import MkNoteMenu from '../../../common/views/components/note-menu.vue';
import MkReactionPicker from '../../../common/views/components/reaction-picker.vue';
-import XSub from './post-detail.sub.vue';
+import XSub from './note-detail.sub.vue';
export default Vue.extend({
components: {
@@ -94,7 +94,7 @@ export default Vue.extend({
},
props: {
- post: {
+ note: {
type: Object,
required: true
},
@@ -112,14 +112,14 @@ export default Vue.extend({
},
computed: {
- isRepost(): boolean {
- return (this.post.repost &&
- this.post.text == null &&
- this.post.mediaIds == null &&
- this.post.poll == null);
+ isRenote(): boolean {
+ return (this.note.renote &&
+ this.note.text == null &&
+ this.note.mediaIds == null &&
+ this.note.poll == null);
},
p(): any {
- return this.isRepost ? this.post.repost : this.post;
+ return this.isRenote ? this.note.renote : this.note;
},
reactionsCount(): number {
return this.p.reactionCounts
@@ -132,10 +132,10 @@ export default Vue.extend({
return dateStringify(this.p.createdAt);
},
acct(): string {
- return getAcct(this.post.user);
+ return getAcct(this.note.user);
},
name(): string {
- return getUserName(this.post.user);
+ return getUserName(this.note.user);
},
pAcct(): string {
return getAcct(this.p.user);
@@ -158,8 +158,8 @@ export default Vue.extend({
mounted() {
// Get replies
if (!this.compact) {
- (this as any).api('posts/replies', {
- postId: this.p.id,
+ (this as any).api('notes/replies', {
+ noteId: this.p.id,
limit: 8
}).then(replies => {
this.replies = replies;
@@ -190,8 +190,8 @@ export default Vue.extend({
this.contextFetching = true;
// Fetch context
- (this as any).api('posts/context', {
- postId: this.p.replyId
+ (this as any).api('notes/context', {
+ noteId: this.p.replyId
}).then(context => {
this.contextFetching = false;
this.context = context.reverse();
@@ -202,21 +202,21 @@ export default Vue.extend({
reply: this.p
});
},
- repost() {
- (this as any).os.new(MkRepostFormWindow, {
- post: this.p
+ renote() {
+ (this as any).os.new(MkRenoteFormWindow, {
+ note: this.p
});
},
react() {
(this as any).os.new(MkReactionPicker, {
source: this.$refs.reactButton,
- post: this.p
+ note: this.p
});
},
menu() {
- (this as any).os.new(MkPostMenu, {
+ (this as any).os.new(MkNoteMenu, {
source: this.$refs.menuButton,
- post: this.p
+ note: this.p
});
}
}
@@ -226,7 +226,7 @@ export default Vue.extend({
<style lang="stylus" scoped>
@import '~const.styl'
-.mk-post-detail
+.mk-note-detail
margin 0
padding 0
overflow hidden
@@ -263,7 +263,7 @@ export default Vue.extend({
> *
border-bottom 1px solid #eef0f2
- > .repost
+ > .renote
color #9dbb00
background linear-gradient(to bottom, #edfde2 0%, #fff 100%)
@@ -355,10 +355,10 @@ export default Vue.extend({
> .body
padding 8px 0
- > .repost
+ > .renote
margin 8px 0
- > .mk-post-preview
+ > .mk-note-preview
padding 16px
border dashed 1px #c0dac6
border-radius 8px
diff --git a/src/client/app/desktop/views/components/post-form-window.vue b/src/client/app/desktop/views/components/post-form-window.vue
index d0b115e852..c890592a5e 100644
--- a/src/client/app/desktop/views/components/post-form-window.vue
+++ b/src/client/app/desktop/views/components/post-form-window.vue
@@ -2,13 +2,13 @@
<mk-window ref="window" is-modal @closed="$destroy">
<span slot="header">
<span :class="$style.icon" v-if="geo">%fa:map-marker-alt%</span>
- <span v-if="!reply">%i18n:desktop.tags.mk-post-form-window.post%</span>
+ <span v-if="!reply">%i18n:desktop.tags.mk-post-form-window.note%</span>
<span v-if="reply">%i18n:desktop.tags.mk-post-form-window.reply%</span>
<span :class="$style.count" v-if="media.length != 0">{{ '%i18n:desktop.tags.mk-post-form-window.attaches%'.replace('{}', media.length) }}</span>
<span :class="$style.count" v-if="uploadings.length != 0">{{ '%i18n:desktop.tags.mk-post-form-window.uploading-media%'.replace('{}', uploadings.length) }}<mk-ellipsis/></span>
</span>
- <mk-post-preview v-if="reply" :class="$style.postPreview" :post="reply"/>
+ <mk-note-preview v-if="reply" :class="$style.notePreview" :note="reply"/>
<mk-post-form ref="form"
:reply="reply"
@posted="onPosted"
@@ -70,7 +70,7 @@ export default Vue.extend({
&:after
content ')'
-.postPreview
+.notePreview
margin 16px 22px
</style>
diff --git a/src/client/app/desktop/views/components/post-form.vue b/src/client/app/desktop/views/components/post-form.vue
index 1c83a38b64..8e3ec24bc8 100644
--- a/src/client/app/desktop/views/components/post-form.vue
+++ b/src/client/app/desktop/views/components/post-form.vue
@@ -46,7 +46,7 @@ export default Vue.extend({
components: {
XDraggable
},
- props: ['reply', 'repost'],
+ props: ['reply', 'renote'],
data() {
return {
posting: false,
@@ -61,28 +61,28 @@ export default Vue.extend({
},
computed: {
draftId(): string {
- return this.repost
- ? 'repost:' + this.repost.id
+ return this.renote
+ ? 'renote:' + this.renote.id
: this.reply
? 'reply:' + this.reply.id
- : 'post';
+ : 'note';
},
placeholder(): string {
- return this.repost
+ return this.renote
? '%i18n:desktop.tags.mk-post-form.quote-placeholder%'
: this.reply
? '%i18n:desktop.tags.mk-post-form.reply-placeholder%'
- : '%i18n:desktop.tags.mk-post-form.post-placeholder%';
+ : '%i18n:desktop.tags.mk-post-form.note-placeholder%';
},
submitText(): string {
- return this.repost
- ? '%i18n:desktop.tags.mk-post-form.repost%'
+ return this.renote
+ ? '%i18n:desktop.tags.mk-post-form.renote%'
: this.reply
? '%i18n:desktop.tags.mk-post-form.reply%'
- : '%i18n:desktop.tags.mk-post-form.post%';
+ : '%i18n:desktop.tags.mk-post-form.note%';
},
canPost(): boolean {
- return !this.posting && (this.text.length != 0 || this.files.length != 0 || this.poll || this.repost);
+ return !this.posting && (this.text.length != 0 || this.files.length != 0 || this.poll || this.renote);
}
},
watch: {
@@ -217,11 +217,11 @@ export default Vue.extend({
post() {
this.posting = true;
- (this as any).api('posts/create', {
+ (this as any).api('notes/create', {
text: this.text == '' ? undefined : this.text,
mediaIds: this.files.length > 0 ? this.files.map(f => f.id) : undefined,
replyId: this.reply ? this.reply.id : undefined,
- repostId: this.repost ? this.repost.id : undefined,
+ renoteId: this.renote ? this.renote.id : undefined,
poll: this.poll ? (this.$refs.poll as any).get() : undefined,
geo: this.geo ? {
coordinates: [this.geo.longitude, this.geo.latitude],
@@ -235,17 +235,17 @@ export default Vue.extend({
this.clear();
this.deleteDraft();
this.$emit('posted');
- (this as any).apis.notify(this.repost
+ (this as any).apis.notify(this.renote
? '%i18n:desktop.tags.mk-post-form.reposted%'
: this.reply
? '%i18n:desktop.tags.mk-post-form.replied%'
: '%i18n:desktop.tags.mk-post-form.posted%');
}).catch(err => {
- (this as any).apis.notify(this.repost
- ? '%i18n:desktop.tags.mk-post-form.repost-failed%'
+ (this as any).apis.notify(this.renote
+ ? '%i18n:desktop.tags.mk-post-form.renote-failed%'
: this.reply
? '%i18n:desktop.tags.mk-post-form.reply-failed%'
- : '%i18n:desktop.tags.mk-post-form.post-failed%');
+ : '%i18n:desktop.tags.mk-post-form.note-failed%');
}).then(() => {
this.posting = false;
});
diff --git a/src/client/app/desktop/views/components/posts.post.vue b/src/client/app/desktop/views/components/posts.post.vue
index 17fe330420..924642c01a 100644
--- a/src/client/app/desktop/views/components/posts.post.vue
+++ b/src/client/app/desktop/views/components/posts.post.vue
@@ -1,19 +1,19 @@
<template>
-<div class="post" tabindex="-1" :title="title" @keydown="onKeydown">
+<div class="note" tabindex="-1" :title="title" @keydown="onKeydown">
<div class="reply-to" v-if="p.reply">
- <x-sub :post="p.reply"/>
+ <x-sub :note="p.reply"/>
</div>
- <div class="repost" v-if="isRepost">
+ <div class="renote" v-if="isRenote">
<p>
- <router-link class="avatar-anchor" :to="`/@${acct}`" v-user-preview="post.userId">
- <img class="avatar" :src="`${post.user.avatarUrl}?thumbnail&size=32`" alt="avatar"/>
+ <router-link class="avatar-anchor" :to="`/@${acct}`" v-user-preview="note.userId">
+ <img class="avatar" :src="`${note.user.avatarUrl}?thumbnail&size=32`" alt="avatar"/>
</router-link>
%fa:retweet%
- <span>{{ '%i18n:desktop.tags.mk-timeline-post.reposted-by%'.substr(0, '%i18n:desktop.tags.mk-timeline-post.reposted-by%'.indexOf('{')) }}</span>
- <a class="name" :href="`/@${acct}`" v-user-preview="post.userId">{{ getUserName(post.user) }}</a>
- <span>{{ '%i18n:desktop.tags.mk-timeline-post.reposted-by%'.substr('%i18n:desktop.tags.mk-timeline-post.reposted-by%'.indexOf('}') + 1) }}</span>
+ <span>{{ '%i18n:desktop.tags.mk-timeline-note.reposted-by%'.substr(0, '%i18n:desktop.tags.mk-timeline-note.reposted-by%'.indexOf('{')) }}</span>
+ <a class="name" :href="`/@${acct}`" v-user-preview="note.userId">{{ getUserName(note.user) }}</a>
+ <span>{{ '%i18n:desktop.tags.mk-timeline-note.reposted-by%'.substr('%i18n:desktop.tags.mk-timeline-note.reposted-by%'.indexOf('}') + 1) }}</span>
</p>
- <mk-time :time="post.createdAt"/>
+ <mk-time :time="note.createdAt"/>
</div>
<article>
<router-link class="avatar-anchor" :to="`/@${acct}`">
@@ -38,38 +38,38 @@
</p>
<div class="text">
<a class="reply" v-if="p.reply">%fa:reply%</a>
- <mk-post-html v-if="p.textHtml" :text="p.text" :i="os.i" :class="$style.text"/>
- <a class="rp" v-if="p.repost">RP:</a>
+ <mk-note-html v-if="p.textHtml" :text="p.text" :i="os.i" :class="$style.text"/>
+ <a class="rp" v-if="p.renote">RP:</a>
</div>
<div class="media" v-if="p.media.length > 0">
<mk-media-list :media-list="p.media"/>
</div>
- <mk-poll v-if="p.poll" :post="p" ref="pollViewer"/>
+ <mk-poll v-if="p.poll" :note="p" ref="pollViewer"/>
<div class="tags" v-if="p.tags && p.tags.length > 0">
<router-link v-for="tag in p.tags" :key="tag" :to="`/search?q=#${tag}`">{{ tag }}</router-link>
</div>
<a class="location" v-if="p.geo" :href="`http://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% 位置情報</a>
<div class="map" v-if="p.geo" ref="map"></div>
- <div class="repost" v-if="p.repost">
- <mk-post-preview :post="p.repost"/>
+ <div class="renote" v-if="p.renote">
+ <mk-note-preview :note="p.renote"/>
</div>
<mk-url-preview v-for="url in urls" :url="url" :key="url"/>
</div>
<footer>
- <mk-reactions-viewer :post="p" ref="reactionsViewer"/>
- <button @click="reply" title="%i18n:desktop.tags.mk-timeline-post.reply%">
+ <mk-reactions-viewer :note="p" ref="reactionsViewer"/>
+ <button @click="reply" title="%i18n:desktop.tags.mk-timeline-note.reply%">
%fa:reply%<p class="count" v-if="p.repliesCount > 0">{{ p.repliesCount }}</p>
</button>
- <button @click="repost" title="%i18n:desktop.tags.mk-timeline-post.repost%">
- %fa:retweet%<p class="count" v-if="p.repostCount > 0">{{ p.repostCount }}</p>
+ <button @click="renote" title="%i18n:desktop.tags.mk-timeline-note.renote%">
+ %fa:retweet%<p class="count" v-if="p.renoteCount > 0">{{ p.renoteCount }}</p>
</button>
- <button :class="{ reacted: p.myReaction != null }" @click="react" ref="reactButton" title="%i18n:desktop.tags.mk-timeline-post.add-reaction%">
+ <button :class="{ reacted: p.myReaction != null }" @click="react" ref="reactButton" title="%i18n:desktop.tags.mk-timeline-note.add-reaction%">
%fa:plus%<p class="count" v-if="p.reactions_count > 0">{{ p.reactions_count }}</p>
</button>
<button @click="menu" ref="menuButton">
%fa:ellipsis-h%
</button>
- <button title="%i18n:desktop.tags.mk-timeline-post.detail">
+ <button title="%i18n:desktop.tags.mk-timeline-note.detail">
<template v-if="!isDetailOpened">%fa:caret-down%</template>
<template v-if="isDetailOpened">%fa:caret-up%</template>
</button>
@@ -77,7 +77,7 @@
</div>
</article>
<div class="detail" v-if="isDetailOpened">
- <mk-post-status-graph width="462" height="130" :post="p"/>
+ <mk-note-status-graph width="462" height="130" :note="p"/>
</div>
</div>
</template>
@@ -90,10 +90,10 @@ import getUserName from '../../../../../renderers/get-user-name';
import parse from '../../../../../text/parse';
import MkPostFormWindow from './post-form-window.vue';
-import MkRepostFormWindow from './repost-form-window.vue';
-import MkPostMenu from '../../../common/views/components/post-menu.vue';
+import MkRenoteFormWindow from './renote-form-window.vue';
+import MkNoteMenu from '../../../common/views/components/note-menu.vue';
import MkReactionPicker from '../../../common/views/components/reaction-picker.vue';
-import XSub from './posts.post.sub.vue';
+import XSub from './notes.note.sub.vue';
function focus(el, fn) {
const target = fn(el);
@@ -111,7 +111,7 @@ export default Vue.extend({
XSub
},
- props: ['post'],
+ props: ['note'],
data() {
return {
@@ -128,14 +128,14 @@ export default Vue.extend({
name(): string {
return getUserName(this.p.user);
},
- isRepost(): boolean {
- return (this.post.repost &&
- this.post.text == null &&
- this.post.mediaIds == null &&
- this.post.poll == null);
+ isRenote(): boolean {
+ return (this.note.renote &&
+ this.note.text == null &&
+ this.note.mediaIds == null &&
+ this.note.poll == null);
},
p(): any {
- return this.isRepost ? this.post.repost : this.post;
+ return this.isRenote ? this.note.renote : this.note;
},
reactionsCount(): number {
return this.p.reactionCounts
@@ -211,7 +211,7 @@ export default Vue.extend({
type: 'capture',
id: this.p.id
});
- if (withHandler) this.connection.on('post-updated', this.onStreamPostUpdated);
+ if (withHandler) this.connection.on('note-updated', this.onStreamNoteUpdated);
}
},
decapture(withHandler = false) {
@@ -220,18 +220,18 @@ export default Vue.extend({
type: 'decapture',
id: this.p.id
});
- if (withHandler) this.connection.off('post-updated', this.onStreamPostUpdated);
+ if (withHandler) this.connection.off('note-updated', this.onStreamNoteUpdated);
}
},
onStreamConnected() {
this.capture();
},
- onStreamPostUpdated(data) {
- const post = data.post;
- if (post.id == this.post.id) {
- this.$emit('update:post', post);
- } else if (post.id == this.post.repostId) {
- this.post.repost = post;
+ onStreamNoteUpdated(data) {
+ const note = data.note;
+ if (note.id == this.note.id) {
+ this.$emit('update:note', note);
+ } else if (note.id == this.note.renoteId) {
+ this.note.renote = note;
}
},
reply() {
@@ -239,21 +239,21 @@ export default Vue.extend({
reply: this.p
});
},
- repost() {
- (this as any).os.new(MkRepostFormWindow, {
- post: this.p
+ renote() {
+ (this as any).os.new(MkRenoteFormWindow, {
+ note: this.p
});
},
react() {
(this as any).os.new(MkReactionPicker, {
source: this.$refs.reactButton,
- post: this.p
+ note: this.p
});
},
menu() {
- (this as any).os.new(MkPostMenu, {
+ (this as any).os.new(MkNoteMenu, {
source: this.$refs.menuButton,
- post: this.p
+ note: this.p
});
},
onKeydown(e) {
@@ -274,7 +274,7 @@ export default Vue.extend({
case e.which == 81: // [q]
case e.which == 69: // [e]
- this.repost();
+ this.renote();
break;
case e.which == 70: // [f]
@@ -299,7 +299,7 @@ export default Vue.extend({
<style lang="stylus" scoped>
@import '~const.styl'
-.post
+.note
margin 0
padding 0
background #fff
@@ -309,7 +309,7 @@ export default Vue.extend({
border-top-left-radius 6px
border-top-right-radius 6px
- > .repost
+ > .renote
border-top-left-radius 6px
border-top-right-radius 6px
@@ -330,7 +330,7 @@ export default Vue.extend({
border 2px solid rgba($theme-color, 0.3)
border-radius 4px
- > .repost
+ > .renote
color #9dbb00
background linear-gradient(to bottom, #edfde2 0%, #fff 100%)
@@ -369,7 +369,7 @@ export default Vue.extend({
padding 0 16px
background rgba(0, 0, 0, 0.0125)
- > .mk-post-preview
+ > .mk-note-preview
background transparent
> article
@@ -529,10 +529,10 @@ export default Vue.extend({
> .mk-poll
font-size 80%
- > .repost
+ > .renote
margin 8px 0
- > .mk-post-preview
+ > .mk-note-preview
padding 16px
border dashed 1px #c0dac6
border-radius 8px
diff --git a/src/client/app/desktop/views/components/renote-form-window.vue b/src/client/app/desktop/views/components/renote-form-window.vue
new file mode 100644
index 0000000000..09176b5ba7
--- /dev/null
+++ b/src/client/app/desktop/views/components/renote-form-window.vue
@@ -0,0 +1,42 @@
+<template>
+<mk-window ref="window" is-modal @closed="$destroy">
+ <span slot="header" :class="$style.header">%fa:retweet%%i18n:desktop.tags.mk-renote-form-window.title%</span>
+ <mk-renote-form ref="form" :note="note" @posted="onPosted" @canceled="onCanceled"/>
+</mk-window>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+
+export default Vue.extend({
+ props: ['note'],
+ mounted() {
+ document.addEventListener('keydown', this.onDocumentKeydown);
+ },
+ beforeDestroy() {
+ document.removeEventListener('keydown', this.onDocumentKeydown);
+ },
+ methods: {
+ onDocumentKeydown(e) {
+ if (e.target.tagName != 'INPUT' && e.target.tagName != 'TEXTAREA') {
+ if (e.which == 27) { // Esc
+ (this.$refs.window as any).close();
+ }
+ }
+ },
+ onPosted() {
+ (this.$refs.window as any).close();
+ },
+ onCanceled() {
+ (this.$refs.window as any).close();
+ }
+ }
+});
+</script>
+
+<style lang="stylus" module>
+.header
+ > [data-fa]
+ margin-right 4px
+
+</style>
diff --git a/src/client/app/desktop/views/components/renote-form.vue b/src/client/app/desktop/views/components/renote-form.vue
new file mode 100644
index 0000000000..c6b9074156
--- /dev/null
+++ b/src/client/app/desktop/views/components/renote-form.vue
@@ -0,0 +1,131 @@
+<template>
+<div class="mk-renote-form">
+ <mk-note-preview :note="note"/>
+ <template v-if="!quote">
+ <footer>
+ <a class="quote" v-if="!quote" @click="onQuote">%i18n:desktop.tags.mk-renote-form.quote%</a>
+ <button class="cancel" @click="cancel">%i18n:desktop.tags.mk-renote-form.cancel%</button>
+ <button class="ok" @click="ok" :disabled="wait">{{ wait ? '%i18n:desktop.tags.mk-renote-form.reposting%' : '%i18n:desktop.tags.mk-renote-form.renote%' }}</button>
+ </footer>
+ </template>
+ <template v-if="quote">
+ <mk-post-form ref="form" :renote="note" @posted="onChildFormPosted"/>
+ </template>
+</div>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+
+export default Vue.extend({
+ props: ['note'],
+ data() {
+ return {
+ wait: false,
+ quote: false
+ };
+ },
+ methods: {
+ ok() {
+ this.wait = true;
+ (this as any).api('notes/create', {
+ renoteId: this.note.id
+ }).then(data => {
+ this.$emit('posted');
+ (this as any).apis.notify('%i18n:desktop.tags.mk-renote-form.success%');
+ }).catch(err => {
+ (this as any).apis.notify('%i18n:desktop.tags.mk-renote-form.failure%');
+ }).then(() => {
+ this.wait = false;
+ });
+ },
+ cancel() {
+ this.$emit('canceled');
+ },
+ onQuote() {
+ this.quote = true;
+
+ this.$nextTick(() => {
+ (this.$refs.form as any).focus();
+ });
+ },
+ onChildFormPosted() {
+ this.$emit('posted');
+ }
+ }
+});
+</script>
+
+<style lang="stylus" scoped>
+@import '~const.styl'
+
+.mk-renote-form
+
+ > .mk-note-preview
+ margin 16px 22px
+
+ > footer
+ height 72px
+ background lighten($theme-color, 95%)
+
+ > .quote
+ position absolute
+ bottom 16px
+ left 28px
+ line-height 40px
+
+ button
+ display block
+ position absolute
+ bottom 16px
+ cursor pointer
+ padding 0
+ margin 0
+ width 120px
+ height 40px
+ font-size 1em
+ outline none
+ border-radius 4px
+
+ &:focus
+ &:after
+ content ""
+ pointer-events none
+ position absolute
+ top -5px
+ right -5px
+ bottom -5px
+ left -5px
+ border 2px solid rgba($theme-color, 0.3)
+ border-radius 8px
+
+ > .cancel
+ right 148px
+ color #888
+ background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%)
+ border solid 1px #e2e2e2
+
+ &:hover
+ background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%)
+ border-color #dcdcdc
+
+ &:active
+ background #ececec
+ border-color #dcdcdc
+
+ > .ok
+ right 16px
+ font-weight bold
+ color $theme-color-foreground
+ background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
+ border solid 1px lighten($theme-color, 15%)
+
+ &:hover
+ background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%)
+ border-color $theme-color
+
+ &:active
+ background $theme-color
+ border-color $theme-color
+
+</style>
diff --git a/src/client/app/desktop/views/components/repost-form-window.vue b/src/client/app/desktop/views/components/repost-form-window.vue
index 7db5adbff3..09176b5ba7 100644
--- a/src/client/app/desktop/views/components/repost-form-window.vue
+++ b/src/client/app/desktop/views/components/repost-form-window.vue
@@ -1,7 +1,7 @@
<template>
<mk-window ref="window" is-modal @closed="$destroy">
- <span slot="header" :class="$style.header">%fa:retweet%%i18n:desktop.tags.mk-repost-form-window.title%</span>
- <mk-repost-form ref="form" :post="post" @posted="onPosted" @canceled="onCanceled"/>
+ <span slot="header" :class="$style.header">%fa:retweet%%i18n:desktop.tags.mk-renote-form-window.title%</span>
+ <mk-renote-form ref="form" :note="note" @posted="onPosted" @canceled="onCanceled"/>
</mk-window>
</template>
@@ -9,7 +9,7 @@
import Vue from 'vue';
export default Vue.extend({
- props: ['post'],
+ props: ['note'],
mounted() {
document.addEventListener('keydown', this.onDocumentKeydown);
},
diff --git a/src/client/app/desktop/views/components/repost-form.vue b/src/client/app/desktop/views/components/repost-form.vue
index 3a5e3a7c56..c6b9074156 100644
--- a/src/client/app/desktop/views/components/repost-form.vue
+++ b/src/client/app/desktop/views/components/repost-form.vue
@@ -1,15 +1,15 @@
<template>
-<div class="mk-repost-form">
- <mk-post-preview :post="post"/>
+<div class="mk-renote-form">
+ <mk-note-preview :note="note"/>
<template v-if="!quote">
<footer>
- <a class="quote" v-if="!quote" @click="onQuote">%i18n:desktop.tags.mk-repost-form.quote%</a>
- <button class="cancel" @click="cancel">%i18n:desktop.tags.mk-repost-form.cancel%</button>
- <button class="ok" @click="ok" :disabled="wait">{{ wait ? '%i18n:desktop.tags.mk-repost-form.reposting%' : '%i18n:desktop.tags.mk-repost-form.repost%' }}</button>
+ <a class="quote" v-if="!quote" @click="onQuote">%i18n:desktop.tags.mk-renote-form.quote%</a>
+ <button class="cancel" @click="cancel">%i18n:desktop.tags.mk-renote-form.cancel%</button>
+ <button class="ok" @click="ok" :disabled="wait">{{ wait ? '%i18n:desktop.tags.mk-renote-form.reposting%' : '%i18n:desktop.tags.mk-renote-form.renote%' }}</button>
</footer>
</template>
<template v-if="quote">
- <mk-post-form ref="form" :repost="post" @posted="onChildFormPosted"/>
+ <mk-post-form ref="form" :renote="note" @posted="onChildFormPosted"/>
</template>
</div>
</template>
@@ -18,7 +18,7 @@
import Vue from 'vue';
export default Vue.extend({
- props: ['post'],
+ props: ['note'],
data() {
return {
wait: false,
@@ -28,13 +28,13 @@ export default Vue.extend({
methods: {
ok() {
this.wait = true;
- (this as any).api('posts/create', {
- repostId: this.post.id
+ (this as any).api('notes/create', {
+ renoteId: this.note.id
}).then(data => {
this.$emit('posted');
- (this as any).apis.notify('%i18n:desktop.tags.mk-repost-form.success%');
+ (this as any).apis.notify('%i18n:desktop.tags.mk-renote-form.success%');
}).catch(err => {
- (this as any).apis.notify('%i18n:desktop.tags.mk-repost-form.failure%');
+ (this as any).apis.notify('%i18n:desktop.tags.mk-renote-form.failure%');
}).then(() => {
this.wait = false;
});
@@ -59,9 +59,9 @@ export default Vue.extend({
<style lang="stylus" scoped>
@import '~const.styl'
-.mk-repost-form
+.mk-renote-form
- > .mk-post-preview
+ > .mk-note-preview
margin 16px 22px
> footer
diff --git a/src/client/app/desktop/views/components/sub-note-content.vue b/src/client/app/desktop/views/components/sub-note-content.vue
new file mode 100644
index 0000000000..51ee93cba6
--- /dev/null
+++ b/src/client/app/desktop/views/components/sub-note-content.vue
@@ -0,0 +1,44 @@
+<template>
+<div class="mk-sub-note-content">
+ <div class="body">
+ <a class="reply" v-if="note.replyId">%fa:reply%</a>
+ <mk-note-html :text="note.text" :i="os.i"/>
+ <a class="rp" v-if="note.renoteId" :href="`/note:${note.renoteId}`">RP: ...</a>
+ </div>
+ <details v-if="note.media.length > 0">
+ <summary>({{ note.media.length }}つのメディア)</summary>
+ <mk-media-list :media-list="note.media"/>
+ </details>
+ <details v-if="note.poll">
+ <summary>投票</summary>
+ <mk-poll :note="note"/>
+ </details>
+</div>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+
+export default Vue.extend({
+ props: ['note']
+});
+</script>
+
+<style lang="stylus" scoped>
+.mk-sub-note-content
+ overflow-wrap break-word
+
+ > .body
+ > .reply
+ margin-right 6px
+ color #717171
+
+ > .rp
+ margin-left 4px
+ font-style oblique
+ color #a0bf46
+
+ mk-poll
+ font-size 80%
+
+</style>
diff --git a/src/client/app/desktop/views/components/sub-post-content.vue b/src/client/app/desktop/views/components/sub-post-content.vue
deleted file mode 100644
index 17899af280..0000000000
--- a/src/client/app/desktop/views/components/sub-post-content.vue
+++ /dev/null
@@ -1,44 +0,0 @@
-<template>
-<div class="mk-sub-post-content">
- <div class="body">
- <a class="reply" v-if="post.replyId">%fa:reply%</a>
- <mk-post-html :text="post.text" :i="os.i"/>
- <a class="rp" v-if="post.repostId" :href="`/post:${post.repostId}`">RP: ...</a>
- </div>
- <details v-if="post.media.length > 0">
- <summary>({{ post.media.length }}つのメディア)</summary>
- <mk-media-list :media-list="post.media"/>
- </details>
- <details v-if="post.poll">
- <summary>投票</summary>
- <mk-poll :post="post"/>
- </details>
-</div>
-</template>
-
-<script lang="ts">
-import Vue from 'vue';
-
-export default Vue.extend({
- props: ['post']
-});
-</script>
-
-<style lang="stylus" scoped>
-.mk-sub-post-content
- overflow-wrap break-word
-
- > .body
- > .reply
- margin-right 6px
- color #717171
-
- > .rp
- margin-left 4px
- font-style oblique
- color #a0bf46
-
- mk-poll
- font-size 80%
-
-</style>
diff --git a/src/client/app/desktop/views/components/timeline.vue b/src/client/app/desktop/views/components/timeline.vue
index 65b4bd1c7a..6d049eee9c 100644
--- a/src/client/app/desktop/views/components/timeline.vue
+++ b/src/client/app/desktop/views/components/timeline.vue
@@ -4,15 +4,15 @@
<div class="fetching" v-if="fetching">
<mk-ellipsis-icon/>
</div>
- <p class="empty" v-if="posts.length == 0 && !fetching">
+ <p class="empty" v-if="notes.length == 0 && !fetching">
%fa:R comments%自分の投稿や、自分がフォローしているユーザーの投稿が表示されます。
</p>
- <mk-posts :posts="posts" ref="timeline">
+ <mk-notes :notes="notes" ref="timeline">
<button slot="footer" @click="more" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
<template v-if="!moreFetching">もっと見る</template>
<template v-if="moreFetching">%fa:spinner .pulse .fw%</template>
</button>
- </mk-posts>
+ </mk-notes>
</div>
</template>
@@ -26,7 +26,7 @@ export default Vue.extend({
fetching: true,
moreFetching: false,
existMore: false,
- posts: [],
+ notes: [],
connection: null,
connectionId: null,
date: null
@@ -41,7 +41,7 @@ export default Vue.extend({
this.connection = (this as any).os.stream.getConnection();
this.connectionId = (this as any).os.stream.use();
- this.connection.on('post', this.onPost);
+ this.connection.on('note', this.onNote);
this.connection.on('follow', this.onChangeFollowing);
this.connection.on('unfollow', this.onChangeFollowing);
@@ -51,7 +51,7 @@ export default Vue.extend({
this.fetch();
},
beforeDestroy() {
- this.connection.off('post', this.onPost);
+ this.connection.off('note', this.onNote);
this.connection.off('follow', this.onChangeFollowing);
this.connection.off('unfollow', this.onChangeFollowing);
(this as any).os.stream.dispose(this.connectionId);
@@ -63,45 +63,45 @@ export default Vue.extend({
fetch(cb?) {
this.fetching = true;
- (this as any).api('posts/timeline', {
+ (this as any).api('notes/timeline', {
limit: 11,
untilDate: this.date ? this.date.getTime() : undefined
- }).then(posts => {
- if (posts.length == 11) {
- posts.pop();
+ }).then(notes => {
+ if (notes.length == 11) {
+ notes.pop();
this.existMore = true;
}
- this.posts = posts;
+ this.notes = notes;
this.fetching = false;
this.$emit('loaded');
if (cb) cb();
});
},
more() {
- if (this.moreFetching || this.fetching || this.posts.length == 0 || !this.existMore) return;
+ if (this.moreFetching || this.fetching || this.notes.length == 0 || !this.existMore) return;
this.moreFetching = true;
- (this as any).api('posts/timeline', {
+ (this as any).api('notes/timeline', {
limit: 11,
- untilId: this.posts[this.posts.length - 1].id
- }).then(posts => {
- if (posts.length == 11) {
- posts.pop();
+ untilId: this.notes[this.notes.length - 1].id
+ }).then(notes => {
+ if (notes.length == 11) {
+ notes.pop();
} else {
this.existMore = false;
}
- this.posts = this.posts.concat(posts);
+ this.notes = this.notes.concat(notes);
this.moreFetching = false;
});
},
- onPost(post) {
+ onNote(note) {
// サウンドを再生する
if ((this as any).os.isEnableSounds) {
- const sound = new Audio(`${url}/assets/post.mp3`);
+ const sound = new Audio(`${url}/assets/note.mp3`);
sound.volume = localStorage.getItem('soundVolume') ? parseInt(localStorage.getItem('soundVolume'), 10) / 100 : 1;
sound.play();
}
- this.posts.unshift(post);
+ this.notes.unshift(note);
},
onChangeFollowing() {
this.fetch();
diff --git a/src/client/app/desktop/views/components/ui.header.post.vue b/src/client/app/desktop/views/components/ui.header.post.vue
index c2f0e07dd3..5c1756b756 100644
--- a/src/client/app/desktop/views/components/ui.header.post.vue
+++ b/src/client/app/desktop/views/components/ui.header.post.vue
@@ -1,6 +1,6 @@
<template>
-<div class="post">
- <button @click="post" title="%i18n:desktop.tags.mk-ui-header-post-button.post%">%fa:pencil-alt%</button>
+<div class="note">
+ <button @click="post" title="%i18n:desktop.tags.mk-ui-header-note-button.note%">%fa:pencil-alt%</button>
</div>
</template>
@@ -19,7 +19,7 @@ export default Vue.extend({
<style lang="stylus" scoped>
@import '~const.styl'
-.post
+.note
display inline-block
padding 8px
height 100%
diff --git a/src/client/app/desktop/views/components/user-preview.vue b/src/client/app/desktop/views/components/user-preview.vue
index 2f2e78ec6d..3cbaa2816e 100644
--- a/src/client/app/desktop/views/components/user-preview.vue
+++ b/src/client/app/desktop/views/components/user-preview.vue
@@ -12,7 +12,7 @@
<div class="description">{{ u.description }}</div>
<div class="status">
<div>
- <p>投稿</p><a>{{ u.postsCount }}</a>
+ <p>投稿</p><a>{{ u.notesCount }}</a>
</div>
<div>
<p>フォロー</p><a>{{ u.followingCount }}</a>
diff --git a/src/client/app/desktop/views/pages/home.vue b/src/client/app/desktop/views/pages/home.vue
index c209af4e43..e4caa2022e 100644
--- a/src/client/app/desktop/views/pages/home.vue
+++ b/src/client/app/desktop/views/pages/home.vue
@@ -7,7 +7,7 @@
<script lang="ts">
import Vue from 'vue';
import Progress from '../../../common/scripts/loading';
-import getPostSummary from '../../../../../renderers/get-post-summary';
+import getNoteSummary from '../../../../../renderers/get-note-summary';
export default Vue.extend({
props: {
@@ -29,13 +29,13 @@ export default Vue.extend({
this.connection = (this as any).os.stream.getConnection();
this.connectionId = (this as any).os.stream.use();
- this.connection.on('post', this.onStreamPost);
+ this.connection.on('note', this.onStreamNote);
document.addEventListener('visibilitychange', this.onVisibilitychange, false);
Progress.start();
},
beforeDestroy() {
- this.connection.off('post', this.onStreamPost);
+ this.connection.off('note', this.onStreamNote);
(this as any).os.stream.dispose(this.connectionId);
document.removeEventListener('visibilitychange', this.onVisibilitychange);
},
@@ -44,10 +44,10 @@ export default Vue.extend({
Progress.done();
},
- onStreamPost(post) {
- if (document.hidden && post.userId != (this as any).os.i.id) {
+ onStreamNote(note) {
+ if (document.hidden && note.userId != (this as any).os.i.id) {
this.unreadCount++;
- document.title = `(${this.unreadCount}) ${getPostSummary(post)}`;
+ document.title = `(${this.unreadCount}) ${getNoteSummary(note)}`;
}
},
diff --git a/src/client/app/desktop/views/pages/post.vue b/src/client/app/desktop/views/pages/note.vue
index dbd707e049..17c2b1e954 100644
--- a/src/client/app/desktop/views/pages/post.vue
+++ b/src/client/app/desktop/views/pages/note.vue
@@ -1,9 +1,9 @@
<template>
<mk-ui>
<main v-if="!fetching">
- <a v-if="post.next" :href="post.next">%fa:angle-up%%i18n:desktop.tags.mk-post-page.next%</a>
- <mk-post-detail :post="post"/>
- <a v-if="post.prev" :href="post.prev">%fa:angle-down%%i18n:desktop.tags.mk-post-page.prev%</a>
+ <a v-if="note.next" :href="note.next">%fa:angle-up%%i18n:desktop.tags.mk-note-page.next%</a>
+ <mk-note-detail :note="note"/>
+ <a v-if="note.prev" :href="note.prev">%fa:angle-down%%i18n:desktop.tags.mk-note-page.prev%</a>
</main>
</mk-ui>
</template>
@@ -16,7 +16,7 @@ export default Vue.extend({
data() {
return {
fetching: true,
- post: null
+ note: null
};
},
watch: {
@@ -30,10 +30,10 @@ export default Vue.extend({
Progress.start();
this.fetching = true;
- (this as any).api('posts/show', {
- postId: this.$route.params.post
- }).then(post => {
- this.post = post;
+ (this as any).api('notes/show', {
+ noteId: this.$route.params.note
+ }).then(note => {
+ this.note = note;
this.fetching = false;
Progress.done();
@@ -60,7 +60,7 @@ main
> [data-fa]
margin-right 4px
- > .mk-post-detail
+ > .mk-note-detail
margin 0 auto
width 640px
diff --git a/src/client/app/desktop/views/pages/search.vue b/src/client/app/desktop/views/pages/search.vue
index afd37c8cee..698154e667 100644
--- a/src/client/app/desktop/views/pages/search.vue
+++ b/src/client/app/desktop/views/pages/search.vue
@@ -7,12 +7,12 @@
<mk-ellipsis-icon/>
</div>
<p :class="$style.empty" v-if="!fetching && empty">%fa:search%「{{ q }}」に関する投稿は見つかりませんでした。</p>
- <mk-posts ref="timeline" :class="$style.posts" :posts="posts">
+ <mk-notes ref="timeline" :class="$style.notes" :notes="notes">
<div slot="footer">
<template v-if="!moreFetching">%fa:search%</template>
<template v-if="moreFetching">%fa:spinner .pulse .fw%</template>
</div>
- </mk-posts>
+ </mk-notes>
</mk-ui>
</template>
@@ -30,7 +30,7 @@ export default Vue.extend({
moreFetching: false,
existMore: false,
offset: 0,
- posts: []
+ notes: []
};
},
watch: {
@@ -38,7 +38,7 @@ export default Vue.extend({
},
computed: {
empty(): boolean {
- return this.posts.length == 0;
+ return this.notes.length == 0;
},
q(): string {
return this.$route.query.q;
@@ -66,33 +66,33 @@ export default Vue.extend({
this.fetching = true;
Progress.start();
- (this as any).api('posts/search', Object.assign({
+ (this as any).api('notes/search', Object.assign({
limit: limit + 1,
offset: this.offset
- }, parse(this.q))).then(posts => {
- if (posts.length == limit + 1) {
- posts.pop();
+ }, parse(this.q))).then(notes => {
+ if (notes.length == limit + 1) {
+ notes.pop();
this.existMore = true;
}
- this.posts = posts;
+ this.notes = notes;
this.fetching = false;
Progress.done();
});
},
more() {
- if (this.moreFetching || this.fetching || this.posts.length == 0 || !this.existMore) return;
+ if (this.moreFetching || this.fetching || this.notes.length == 0 || !this.existMore) return;
this.offset += limit;
this.moreFetching = true;
- return (this as any).api('posts/search', Object.assign({
+ return (this as any).api('notes/search', Object.assign({
limit: limit + 1,
offset: this.offset
- }, parse(this.q))).then(posts => {
- if (posts.length == limit + 1) {
- posts.pop();
+ }, parse(this.q))).then(notes => {
+ if (notes.length == limit + 1) {
+ notes.pop();
} else {
this.existMore = false;
}
- this.posts = this.posts.concat(posts);
+ this.notes = this.notes.concat(notes);
this.moreFetching = false;
});
},
@@ -111,7 +111,7 @@ export default Vue.extend({
margin 0 auto
color #555
-.posts
+.notes
max-width 600px
margin 0 auto
border solid 1px rgba(0, 0, 0, 0.075)
diff --git a/src/client/app/desktop/views/pages/user/user.home.vue b/src/client/app/desktop/views/pages/user/user.home.vue
index 071c9bb61c..ed3b1c7104 100644
--- a/src/client/app/desktop/views/pages/user/user.home.vue
+++ b/src/client/app/desktop/views/pages/user/user.home.vue
@@ -9,7 +9,7 @@
</div>
</div>
<main>
- <mk-post-detail v-if="user.pinnedPost" :post="user.pinnedPost" :compact="true"/>
+ <mk-note-detail v-if="user.pinnedNote" :note="user.pinnedNote" :compact="true"/>
<x-timeline class="timeline" ref="tl" :user="user"/>
</main>
<div>
diff --git a/src/client/app/desktop/views/pages/user/user.photos.vue b/src/client/app/desktop/views/pages/user/user.photos.vue
index 1ff79b4aee..99a1a8d707 100644
--- a/src/client/app/desktop/views/pages/user/user.photos.vue
+++ b/src/client/app/desktop/views/pages/user/user.photos.vue
@@ -22,13 +22,13 @@ export default Vue.extend({
};
},
mounted() {
- (this as any).api('users/posts', {
+ (this as any).api('users/notes', {
userId: this.user.id,
withMedia: true,
limit: 9
- }).then(posts => {
- posts.forEach(post => {
- post.media.forEach(media => {
+ }).then(notes => {
+ notes.forEach(note => {
+ note.media.forEach(media => {
if (this.images.length < 9) this.images.push(media);
});
});
diff --git a/src/client/app/desktop/views/pages/user/user.profile.vue b/src/client/app/desktop/views/pages/user/user.profile.vue
index f5562d0915..2a82ba7861 100644
--- a/src/client/app/desktop/views/pages/user/user.profile.vue
+++ b/src/client/app/desktop/views/pages/user/user.profile.vue
@@ -14,7 +14,7 @@
<p>%fa:B twitter%<a :href="`https://twitter.com/${user.account.twitter.screenName}`" target="_blank">@{{ user.account.twitter.screenName }}</a></p>
</div>
<div class="status">
- <p class="posts-count">%fa:angle-right%<a>{{ user.postsCount }}</a><b>投稿</b></p>
+ <p class="notes-count">%fa:angle-right%<a>{{ user.notesCount }}</a><b>投稿</b></p>
<p class="following">%fa:angle-right%<a @click="showFollowing">{{ user.followingCount }}</a>人を<b>フォロー</b></p>
<p class="followers">%fa:angle-right%<a @click="showFollowers">{{ user.followersCount }}</a>人の<b>フォロワー</b></p>
</div>
diff --git a/src/client/app/desktop/views/pages/user/user.timeline.vue b/src/client/app/desktop/views/pages/user/user.timeline.vue
index 134ad423ce..87d133174b 100644
--- a/src/client/app/desktop/views/pages/user/user.timeline.vue
+++ b/src/client/app/desktop/views/pages/user/user.timeline.vue
@@ -8,12 +8,12 @@
<mk-ellipsis-icon/>
</div>
<p class="empty" v-if="empty">%fa:R comments%このユーザーはまだ何も投稿していないようです。</p>
- <mk-posts ref="timeline" :posts="posts">
+ <mk-notes ref="timeline" :notes="notes">
<div slot="footer">
<template v-if="!moreFetching">%fa:moon%</template>
<template v-if="moreFetching">%fa:spinner .pulse .fw%</template>
</div>
- </mk-posts>
+ </mk-notes>
</div>
</template>
@@ -27,7 +27,7 @@ export default Vue.extend({
moreFetching: false,
mode: 'default',
unreadCount: 0,
- posts: [],
+ notes: [],
date: null
};
},
@@ -38,7 +38,7 @@ export default Vue.extend({
},
computed: {
empty(): boolean {
- return this.posts.length == 0;
+ return this.notes.length == 0;
}
},
mounted() {
@@ -60,26 +60,26 @@ export default Vue.extend({
}
},
fetch(cb?) {
- (this as any).api('users/posts', {
+ (this as any).api('users/notes', {
userId: this.user.id,
untilDate: this.date ? this.date.getTime() : undefined,
with_replies: this.mode == 'with-replies'
- }).then(posts => {
- this.posts = posts;
+ }).then(notes => {
+ this.notes = notes;
this.fetching = false;
if (cb) cb();
});
},
more() {
- if (this.moreFetching || this.fetching || this.posts.length == 0) return;
+ if (this.moreFetching || this.fetching || this.notes.length == 0) return;
this.moreFetching = true;
- (this as any).api('users/posts', {
+ (this as any).api('users/notes', {
userId: this.user.id,
with_replies: this.mode == 'with-replies',
- untilId: this.posts[this.posts.length - 1].id
- }).then(posts => {
+ untilId: this.notes[this.notes.length - 1].id
+ }).then(notes => {
this.moreFetching = false;
- this.posts = this.posts.concat(posts);
+ this.notes = this.notes.concat(notes);
});
},
onScroll() {
diff --git a/src/client/app/desktop/views/widgets/channel.channel.form.vue b/src/client/app/desktop/views/widgets/channel.channel.form.vue
index aaf327f1ef..f2744268bb 100644
--- a/src/client/app/desktop/views/widgets/channel.channel.form.vue
+++ b/src/client/app/desktop/views/widgets/channel.channel.form.vue
@@ -24,11 +24,11 @@ export default Vue.extend({
if (/^>>([0-9]+) /.test(this.text)) {
const index = this.text.match(/^>>([0-9]+) /)[1];
- reply = (this.$parent as any).posts.find(p => p.index.toString() == index);
+ reply = (this.$parent as any).notes.find(p => p.index.toString() == index);
this.text = this.text.replace(/^>>([0-9]+) /, '');
}
- (this as any).api('posts/create', {
+ (this as any).api('notes/create', {
text: this.text,
replyId: reply ? reply.id : undefined,
channelId: (this.$parent as any).channel.id
diff --git a/src/client/app/desktop/views/widgets/channel.channel.post.vue b/src/client/app/desktop/views/widgets/channel.channel.note.vue
index fa6d8c34a5..313a2e3f4f 100644
--- a/src/client/app/desktop/views/widgets/channel.channel.post.vue
+++ b/src/client/app/desktop/views/widgets/channel.channel.note.vue
@@ -1,15 +1,15 @@
<template>
-<div class="post">
+<div class="note">
<header>
- <a class="index" @click="reply">{{ post.index }}:</a>
- <router-link class="name" :to="`/@${acct}`" v-user-preview="post.user.id"><b>{{ name }}</b></router-link>
+ <a class="index" @click="reply">{{ note.index }}:</a>
+ <router-link class="name" :to="`/@${acct}`" v-user-preview="note.user.id"><b>{{ name }}</b></router-link>
<span>ID:<i>{{ acct }}</i></span>
</header>
<div>
- <a v-if="post.reply">&gt;&gt;{{ post.reply.index }}</a>
- {{ post.text }}
- <div class="media" v-if="post.media">
- <a v-for="file in post.media" :href="file.url" target="_blank">
+ <a v-if="note.reply">&gt;&gt;{{ note.reply.index }}</a>
+ {{ note.text }}
+ <div class="media" v-if="note.media">
+ <a v-for="file in note.media" :href="file.url" target="_blank">
<img :src="`${file.url}?thumbnail&size=512`" :alt="file.name" :title="file.name"/>
</a>
</div>
@@ -23,25 +23,25 @@ import getAcct from '../../../../../acct/render';
import getUserName from '../../../../../renderers/get-user-name';
export default Vue.extend({
- props: ['post'],
+ props: ['note'],
computed: {
acct() {
- return getAcct(this.post.user);
+ return getAcct(this.note.user);
},
name() {
- return getUserName(this.post.user);
+ return getUserName(this.note.user);
}
},
methods: {
reply() {
- this.$emit('reply', this.post);
+ this.$emit('reply', this.note);
}
}
});
</script>
<style lang="stylus" scoped>
-.post
+.note
margin 0
padding 0
color #444
diff --git a/src/client/app/desktop/views/widgets/channel.channel.vue b/src/client/app/desktop/views/widgets/channel.channel.vue
index e9fb9e3fd7..ea4d8f8454 100644
--- a/src/client/app/desktop/views/widgets/channel.channel.vue
+++ b/src/client/app/desktop/views/widgets/channel.channel.vue
@@ -1,9 +1,9 @@
<template>
<div class="channel">
<p v-if="fetching">読み込み中<mk-ellipsis/></p>
- <div v-if="!fetching" ref="posts" class="posts">
- <p v-if="posts.length == 0">まだ投稿がありません</p>
- <x-post class="post" v-for="post in posts.slice().reverse()" :post="post" :key="post.id" @reply="reply"/>
+ <div v-if="!fetching" ref="notes" class="notes">
+ <p v-if="notes.length == 0">まだ投稿がありません</p>
+ <x-note class="note" v-for="note in notes.slice().reverse()" :note="note" :key="note.id" @reply="reply"/>
</div>
<x-form class="form" ref="form"/>
</div>
@@ -13,18 +13,18 @@
import Vue from 'vue';
import ChannelStream from '../../../common/scripts/streaming/channel';
import XForm from './channel.channel.form.vue';
-import XPost from './channel.channel.post.vue';
+import XNote from './channel.channel.note.vue';
export default Vue.extend({
components: {
XForm,
- XPost
+ XNote
},
props: ['channel'],
data() {
return {
fetching: true,
- posts: [],
+ notes: [],
connection: null
};
},
@@ -43,10 +43,10 @@ export default Vue.extend({
zap() {
this.fetching = true;
- (this as any).api('channels/posts', {
+ (this as any).api('channels/notes', {
channelId: this.channel.id
- }).then(posts => {
- this.posts = posts;
+ }).then(notes => {
+ this.notes = notes;
this.fetching = false;
this.$nextTick(() => {
@@ -55,24 +55,24 @@ export default Vue.extend({
this.disconnect();
this.connection = new ChannelStream((this as any).os, this.channel.id);
- this.connection.on('post', this.onPost);
+ this.connection.on('note', this.onNote);
});
},
disconnect() {
if (this.connection) {
- this.connection.off('post', this.onPost);
+ this.connection.off('note', this.onNote);
this.connection.close();
}
},
- onPost(post) {
- this.posts.unshift(post);
+ onNote(note) {
+ this.notes.unshift(note);
this.scrollToBottom();
},
scrollToBottom() {
- (this.$refs.posts as any).scrollTop = (this.$refs.posts as any).scrollHeight;
+ (this.$refs.notes as any).scrollTop = (this.$refs.notes as any).scrollHeight;
},
- reply(post) {
- (this.$refs.form as any).text = `>>${ post.index } `;
+ reply(note) {
+ (this.$refs.form as any).text = `>>${ note.index } `;
}
}
});
@@ -87,12 +87,12 @@ export default Vue.extend({
text-align center
color #aaa
- > .posts
+ > .notes
height calc(100% - 38px)
overflow auto
font-size 0.9em
- > .post
+ > .note
border-bottom solid 1px #eee
&:last-child
diff --git a/src/client/app/desktop/views/widgets/polls.vue b/src/client/app/desktop/views/widgets/polls.vue
index c8ba17bd4b..eb49a4cd5c 100644
--- a/src/client/app/desktop/views/widgets/polls.vue
+++ b/src/client/app/desktop/views/widgets/polls.vue
@@ -7,7 +7,7 @@
<div class="poll" v-if="!fetching && poll != null">
<p v-if="poll.text"><router-link to="`/@${ acct }/${ poll.id }`">{{ poll.text }}</router-link></p>
<p v-if="!poll.text"><router-link to="`/@${ acct }/${ poll.id }`">%fa:link%</router-link></p>
- <mk-poll :post="poll"/>
+ <mk-poll :note="poll"/>
</div>
<p class="empty" v-if="!fetching && poll == null">%i18n:desktop.tags.mk-recommended-polls-home-widget.nothing%</p>
<p class="fetching" v-if="fetching">%fa:spinner .pulse .fw%%i18n:common.loading%<mk-ellipsis/></p>
@@ -47,11 +47,11 @@ export default define({
this.fetching = true;
this.poll = null;
- (this as any).api('posts/polls/recommendation', {
+ (this as any).api('notes/polls/recommendation', {
limit: 1,
offset: this.offset
- }).then(posts => {
- const poll = posts ? posts[0] : null;
+ }).then(notes => {
+ const poll = notes ? notes[0] : null;
if (poll == null) {
this.offset = 0;
} else {
diff --git a/src/client/app/desktop/views/widgets/post-form.vue b/src/client/app/desktop/views/widgets/post-form.vue
index cf7fd1f2b2..5e59582a0f 100644
--- a/src/client/app/desktop/views/widgets/post-form.vue
+++ b/src/client/app/desktop/views/widgets/post-form.vue
@@ -4,7 +4,7 @@
<p class="title">%fa:pencil-alt%%i18n:desktop.tags.mk-post-form-home-widget.title%</p>
</template>
<textarea :disabled="posting" v-model="text" @keydown="onKeydown" placeholder="%i18n:desktop.tags.mk-post-form-home-widget.placeholder%"></textarea>
- <button @click="post" :disabled="posting">%i18n:desktop.tags.mk-post-form-home-widget.post%</button>
+ <button @click="post" :disabled="posting">%i18n:desktop.tags.mk-post-form-home-widget.note%</button>
</div>
</template>
@@ -36,7 +36,7 @@ export default define({
post() {
this.posting = true;
- (this as any).api('posts/create', {
+ (this as any).api('notes/create', {
text: this.text
}).then(data => {
this.clear();
diff --git a/src/client/app/desktop/views/widgets/trends.vue b/src/client/app/desktop/views/widgets/trends.vue
index 27c1860b32..c2c7636bb3 100644
--- a/src/client/app/desktop/views/widgets/trends.vue
+++ b/src/client/app/desktop/views/widgets/trends.vue
@@ -5,8 +5,8 @@
<button @click="fetch" title="%i18n:desktop.tags.mk-trends-home-widget.refresh%">%fa:sync%</button>
</template>
<p class="fetching" v-if="fetching">%fa:spinner .pulse .fw%%i18n:common.loading%<mk-ellipsis/></p>
- <div class="post" v-else-if="post != null">
- <p class="text"><router-link :to="`/@${ acct }/${ post.id }`">{{ post.text }}</router-link></p>
+ <div class="note" v-else-if="note != null">
+ <p class="text"><router-link :to="`/@${ acct }/${ note.id }`">{{ note.text }}</router-link></p>
<p class="author">―<router-link :to="`/@${ acct }`">@{{ acct }}</router-link></p>
</div>
<p class="empty" v-else>%i18n:desktop.tags.mk-trends-home-widget.nothing%</p>
@@ -25,12 +25,12 @@ export default define({
}).extend({
computed: {
acct() {
- return getAcct(this.post.user);
+ return getAcct(this.note.user);
},
},
data() {
return {
- post: null,
+ note: null,
fetching: true,
offset: 0
};
@@ -44,23 +44,23 @@ export default define({
},
fetch() {
this.fetching = true;
- this.post = null;
+ this.note = null;
- (this as any).api('posts/trend', {
+ (this as any).api('notes/trend', {
limit: 1,
offset: this.offset,
- repost: false,
+ renote: false,
reply: false,
media: false,
poll: false
- }).then(posts => {
- const post = posts ? posts[0] : null;
- if (post == null) {
+ }).then(notes => {
+ const note = notes ? notes[0] : null;
+ if (note == null) {
this.offset = 0;
} else {
this.offset++;
}
- this.post = post;
+ this.note = note;
this.fetching = false;
});
}
@@ -103,7 +103,7 @@ export default define({
&:active
color #999
- > .post
+ > .note
padding 16px
font-size 12px
font-style oblique
diff --git a/src/client/app/dev/views/new-app.vue b/src/client/app/dev/views/new-app.vue
index e407ca00d7..c9d5971395 100644
--- a/src/client/app/dev/views/new-app.vue
+++ b/src/client/app/dev/views/new-app.vue
@@ -27,7 +27,7 @@
<b-form-checkbox-group v-model="permission" stacked>
<b-form-checkbox value="account-read">アカウントの情報を見る。</b-form-checkbox>
<b-form-checkbox value="account-write">アカウントの情報を操作する。</b-form-checkbox>
- <b-form-checkbox value="post-write">投稿する。</b-form-checkbox>
+ <b-form-checkbox value="note-write">投稿する。</b-form-checkbox>
<b-form-checkbox value="reaction-write">リアクションしたりリアクションをキャンセルする。</b-form-checkbox>
<b-form-checkbox value="following-write">フォローしたりフォロー解除する。</b-form-checkbox>
<b-form-checkbox value="drive-read">ドライブを見る。</b-form-checkbox>
diff --git a/src/client/app/mobile/api/post.ts b/src/client/app/mobile/api/post.ts
index 98309ba8de..72919c6505 100644
--- a/src/client/app/mobile/api/post.ts
+++ b/src/client/app/mobile/api/post.ts
@@ -1,24 +1,24 @@
import PostForm from '../views/components/post-form.vue';
-//import RepostForm from '../views/components/repost-form.vue';
-import getPostSummary from '../../../../renderers/get-post-summary';
+//import RenoteForm from '../views/components/renote-form.vue';
+import getNoteSummary from '../../../../renderers/get-note-summary';
export default (os) => (opts) => {
const o = opts || {};
- if (o.repost) {
- /*const vm = new RepostForm({
+ if (o.renote) {
+ /*const vm = new RenoteForm({
propsData: {
- repost: o.repost
+ renote: o.renote
}
}).$mount();
vm.$once('cancel', recover);
- vm.$once('post', recover);
+ vm.$once('note', recover);
document.body.appendChild(vm.$el);*/
- const text = window.prompt(`「${getPostSummary(o.repost)}」をRepost`);
+ const text = window.prompt(`「${getNoteSummary(o.renote)}」をRenote`);
if (text == null) return;
- os.api('posts/create', {
- repostId: o.repost.id,
+ os.api('notes/create', {
+ renoteId: o.renote.id,
text: text == '' ? undefined : text
});
} else {
@@ -36,7 +36,7 @@ export default (os) => (opts) => {
}
}).$mount();
vm.$once('cancel', recover);
- vm.$once('post', recover);
+ vm.$once('note', recover);
document.body.appendChild(vm.$el);
(vm as any).focus();
}
diff --git a/src/client/app/mobile/script.ts b/src/client/app/mobile/script.ts
index 4776fccddb..6265d0d45f 100644
--- a/src/client/app/mobile/script.ts
+++ b/src/client/app/mobile/script.ts
@@ -25,7 +25,7 @@ import MkDrive from './views/pages/drive.vue';
import MkNotifications from './views/pages/notifications.vue';
import MkMessaging from './views/pages/messaging.vue';
import MkMessagingRoom from './views/pages/messaging-room.vue';
-import MkPost from './views/pages/post.vue';
+import MkNote from './views/pages/note.vue';
import MkSearch from './views/pages/search.vue';
import MkFollowers from './views/pages/followers.vue';
import MkFollowing from './views/pages/following.vue';
@@ -68,7 +68,7 @@ init((launch) => {
{ path: '/@:user', component: MkUser },
{ path: '/@:user/followers', component: MkFollowers },
{ path: '/@:user/following', component: MkFollowing },
- { path: '/@:user/:post', component: MkPost }
+ { path: '/@:user/:note', component: MkNote }
]
});
diff --git a/src/client/app/mobile/views/components/activity.vue b/src/client/app/mobile/views/components/activity.vue
index 2e44017e77..dcd319cb69 100644
--- a/src/client/app/mobile/views/components/activity.vue
+++ b/src/client/app/mobile/views/components/activity.vue
@@ -2,14 +2,14 @@
<div class="mk-activity">
<svg v-if="data" ref="canvas" viewBox="0 0 30 1" preserveAspectRatio="none">
<g v-for="(d, i) in data">
- <rect width="0.8" :height="d.postsH"
- :x="i + 0.1" :y="1 - d.postsH - d.repliesH - d.repostsH"
+ <rect width="0.8" :height="d.notesH"
+ :x="i + 0.1" :y="1 - d.notesH - d.repliesH - d.renotesH"
fill="#41ddde"/>
<rect width="0.8" :height="d.repliesH"
- :x="i + 0.1" :y="1 - d.repliesH - d.repostsH"
+ :x="i + 0.1" :y="1 - d.repliesH - d.renotesH"
fill="#f7796c"/>
- <rect width="0.8" :height="d.repostsH"
- :x="i + 0.1" :y="1 - d.repostsH"
+ <rect width="0.8" :height="d.renotesH"
+ :x="i + 0.1" :y="1 - d.renotesH"
fill="#a1de41"/>
</g>
</svg>
@@ -32,12 +32,12 @@ export default Vue.extend({
userId: this.user.id,
limit: 30
}).then(data => {
- data.forEach(d => d.total = d.posts + d.replies + d.reposts);
+ data.forEach(d => d.total = d.notes + d.replies + d.renotes);
this.peak = Math.max.apply(null, data.map(d => d.total));
data.forEach(d => {
- d.postsH = d.posts / this.peak;
+ d.notesH = d.notes / this.peak;
d.repliesH = d.replies / this.peak;
- d.repostsH = d.reposts / this.peak;
+ d.renotesH = d.renotes / this.peak;
});
data.reverse();
this.data = data;
diff --git a/src/client/app/mobile/views/components/index.ts b/src/client/app/mobile/views/components/index.ts
index fb8f65f47d..9346700304 100644
--- a/src/client/app/mobile/views/components/index.ts
+++ b/src/client/app/mobile/views/components/index.ts
@@ -2,16 +2,16 @@ import Vue from 'vue';
import ui from './ui.vue';
import timeline from './timeline.vue';
-import post from './post.vue';
-import posts from './posts.vue';
+import note from './note.vue';
+import notes from './notes.vue';
import mediaImage from './media-image.vue';
import mediaVideo from './media-video.vue';
import drive from './drive.vue';
-import postPreview from './post-preview.vue';
-import subPostContent from './sub-post-content.vue';
-import postCard from './post-card.vue';
+import notePreview from './note-preview.vue';
+import subNoteContent from './sub-note-content.vue';
+import noteCard from './note-card.vue';
import userCard from './user-card.vue';
-import postDetail from './post-detail.vue';
+import noteDetail from './note-detail.vue';
import followButton from './follow-button.vue';
import friendsMaker from './friends-maker.vue';
import notification from './notification.vue';
@@ -25,16 +25,16 @@ import widgetContainer from './widget-container.vue';
Vue.component('mk-ui', ui);
Vue.component('mk-timeline', timeline);
-Vue.component('mk-post', post);
-Vue.component('mk-posts', posts);
+Vue.component('mk-note', note);
+Vue.component('mk-notes', notes);
Vue.component('mk-media-image', mediaImage);
Vue.component('mk-media-video', mediaVideo);
Vue.component('mk-drive', drive);
-Vue.component('mk-post-preview', postPreview);
-Vue.component('mk-sub-post-content', subPostContent);
-Vue.component('mk-post-card', postCard);
+Vue.component('mk-note-preview', notePreview);
+Vue.component('mk-sub-note-content', subNoteContent);
+Vue.component('mk-note-card', noteCard);
Vue.component('mk-user-card', userCard);
-Vue.component('mk-post-detail', postDetail);
+Vue.component('mk-note-detail', noteDetail);
Vue.component('mk-follow-button', followButton);
Vue.component('mk-friends-maker', friendsMaker);
Vue.component('mk-notification', notification);
diff --git a/src/client/app/mobile/views/components/post-card.vue b/src/client/app/mobile/views/components/note-card.vue
index 68a42ef249..9ad0d3e294 100644
--- a/src/client/app/mobile/views/components/post-card.vue
+++ b/src/client/app/mobile/views/components/note-card.vue
@@ -1,41 +1,41 @@
<template>
-<div class="mk-post-card">
- <a :href="`/@${acct}/${post.id}`">
+<div class="mk-note-card">
+ <a :href="`/@${acct}/${note.id}`">
<header>
<img :src="`${acct}?thumbnail&size=64`" alt="avatar"/><h3>{{ name }}</h3>
</header>
<div>
{{ text }}
</div>
- <mk-time :time="post.createdAt"/>
+ <mk-time :time="note.createdAt"/>
</a>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
-import summary from '../../../../../renderers/get-post-summary';
+import summary from '../../../../../renderers/get-note-summary';
import getAcct from '../../../../../acct/render';
import getUserName from '../../../../../renderers/get-user-name';
export default Vue.extend({
- props: ['post'],
+ props: ['note'],
computed: {
acct() {
- return getAcct(this.post.user);
+ return getAcct(this.note.user);
},
name() {
- return getUserName(this.post.user);
+ return getUserName(this.note.user);
},
text(): string {
- return summary(this.post);
+ return summary(this.note);
}
}
});
</script>
<style lang="stylus" scoped>
-.mk-post-card
+.mk-note-card
display inline-block
width 150px
//height 120px
diff --git a/src/client/app/mobile/views/components/post-detail.sub.vue b/src/client/app/mobile/views/components/note-detail.sub.vue
index 98d6a14cac..38aea4ba20 100644
--- a/src/client/app/mobile/views/components/post-detail.sub.vue
+++ b/src/client/app/mobile/views/components/note-detail.sub.vue
@@ -1,18 +1,18 @@
<template>
<div class="root sub">
<router-link class="avatar-anchor" :to="`/@${acct}`">
- <img class="avatar" :src="`${post.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
+ <img class="avatar" :src="`${note.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
</router-link>
<div class="main">
<header>
- <router-link class="name" :to="`/@${acct}`">{{ getUserName(post.user) }}</router-link>
+ <router-link class="name" :to="`/@${acct}`">{{ getUserName(note.user) }}</router-link>
<span class="username">@{{ acct }}</span>
- <router-link class="time" :to="`/@${acct}/${post.id}`">
- <mk-time :time="post.createdAt"/>
+ <router-link class="time" :to="`/@${acct}/${note.id}`">
+ <mk-time :time="note.createdAt"/>
</router-link>
</header>
<div class="body">
- <mk-sub-post-content class="text" :post="post"/>
+ <mk-sub-note-content class="text" :note="note"/>
</div>
</div>
</div>
@@ -24,13 +24,13 @@ import getAcct from '../../../../../acct/render';
import getUserName from '../../../../../renderers/get-user-name';
export default Vue.extend({
- props: ['post'],
+ props: ['note'],
computed: {
acct() {
- return getAcct(this.post.user);
+ return getAcct(this.note.user);
},
name() {
- return getUserName(this.post.user);
+ return getUserName(this.note.user);
}
}
});
diff --git a/src/client/app/mobile/views/components/note-detail.vue b/src/client/app/mobile/views/components/note-detail.vue
new file mode 100644
index 0000000000..e1682e58ed
--- /dev/null
+++ b/src/client/app/mobile/views/components/note-detail.vue
@@ -0,0 +1,462 @@
+<template>
+<div class="mk-note-detail">
+ <button
+ class="more"
+ v-if="p.reply && p.reply.replyId && context == null"
+ @click="fetchContext"
+ :disabled="fetchingContext"
+ >
+ <template v-if="!contextFetching">%fa:ellipsis-v%</template>
+ <template v-if="contextFetching">%fa:spinner .pulse%</template>
+ </button>
+ <div class="context">
+ <x-sub v-for="note in context" :key="note.id" :note="note"/>
+ </div>
+ <div class="reply-to" v-if="p.reply">
+ <x-sub :note="p.reply"/>
+ </div>
+ <div class="renote" v-if="isRenote">
+ <p>
+ <router-link class="avatar-anchor" :to="`/@${acct}`">
+ <img class="avatar" :src="`${note.user.avatarUrl}?thumbnail&size=32`" alt="avatar"/>
+ </router-link>
+ %fa:retweet%
+ <router-link class="name" :to="`/@${acct}`">
+ {{ name }}
+ </router-link>
+ がRenote
+ </p>
+ </div>
+ <article>
+ <header>
+ <router-link class="avatar-anchor" :to="`/@${pAcct}`">
+ <img class="avatar" :src="`${p.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
+ </router-link>
+ <div>
+ <router-link class="name" :to="`/@${pAcct}`">{{ pName }}</router-link>
+ <span class="username">@{{ pAcct }}</span>
+ </div>
+ </header>
+ <div class="body">
+ <mk-note-html v-if="p.text" :ast="p.text" :i="os.i" :class="$style.text"/>
+ <div class="tags" v-if="p.tags && p.tags.length > 0">
+ <router-link v-for="tag in p.tags" :key="tag" :to="`/search?q=#${tag}`">{{ tag }}</router-link>
+ </div>
+ <div class="media" v-if="p.media.length > 0">
+ <mk-media-list :media-list="p.media"/>
+ </div>
+ <mk-poll v-if="p.poll" :note="p"/>
+ <mk-url-preview v-for="url in urls" :url="url" :key="url"/>
+ <a class="location" v-if="p.geo" :href="`http://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% 位置情報</a>
+ <div class="map" v-if="p.geo" ref="map"></div>
+ <div class="renote" v-if="p.renote">
+ <mk-note-preview :note="p.renote"/>
+ </div>
+ </div>
+ <router-link class="time" :to="`/@${pAcct}/${p.id}`">
+ <mk-time :time="p.createdAt" mode="detail"/>
+ </router-link>
+ <footer>
+ <mk-reactions-viewer :note="p"/>
+ <button @click="reply" title="%i18n:mobile.tags.mk-note-detail.reply%">
+ %fa:reply%<p class="count" v-if="p.repliesCount > 0">{{ p.repliesCount }}</p>
+ </button>
+ <button @click="renote" title="Renote">
+ %fa:retweet%<p class="count" v-if="p.renoteCount > 0">{{ p.renoteCount }}</p>
+ </button>
+ <button :class="{ reacted: p.myReaction != null }" @click="react" ref="reactButton" title="%i18n:mobile.tags.mk-note-detail.reaction%">
+ %fa:plus%<p class="count" v-if="p.reactions_count > 0">{{ p.reactions_count }}</p>
+ </button>
+ <button @click="menu" ref="menuButton">
+ %fa:ellipsis-h%
+ </button>
+ </footer>
+ </article>
+ <div class="replies" v-if="!compact">
+ <x-sub v-for="note in replies" :key="note.id" :note="note"/>
+ </div>
+</div>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+import getAcct from '../../../../../acct/render';
+import getUserName from '../../../../../renderers/get-user-name';
+import parse from '../../../../../text/parse';
+
+import MkNoteMenu from '../../../common/views/components/note-menu.vue';
+import MkReactionPicker from '../../../common/views/components/reaction-picker.vue';
+import XSub from './note-detail.sub.vue';
+
+export default Vue.extend({
+ components: {
+ XSub
+ },
+
+ props: {
+ note: {
+ type: Object,
+ required: true
+ },
+ compact: {
+ default: false
+ }
+ },
+
+ data() {
+ return {
+ context: [],
+ contextFetching: false,
+ replies: []
+ };
+ },
+
+ computed: {
+ acct(): string {
+ return getAcct(this.note.user);
+ },
+ name(): string {
+ return getUserName(this.note.user);
+ },
+ pAcct(): string {
+ return getAcct(this.p.user);
+ },
+ pName(): string {
+ return getUserName(this.p.user);
+ },
+ isRenote(): boolean {
+ return (this.note.renote &&
+ this.note.text == null &&
+ this.note.mediaIds == null &&
+ this.note.poll == null);
+ },
+ p(): any {
+ return this.isRenote ? this.note.renote : this.note;
+ },
+ reactionsCount(): number {
+ return this.p.reactionCounts
+ ? Object.keys(this.p.reactionCounts)
+ .map(key => this.p.reactionCounts[key])
+ .reduce((a, b) => a + b)
+ : 0;
+ },
+ urls(): string[] {
+ if (this.p.text) {
+ const ast = parse(this.p.text);
+ return ast
+ .filter(t => (t.type == 'url' || t.type == 'link') && !t.silent)
+ .map(t => t.url);
+ } else {
+ return null;
+ }
+ }
+ },
+
+ mounted() {
+ // Get replies
+ if (!this.compact) {
+ (this as any).api('notes/replies', {
+ noteId: this.p.id,
+ limit: 8
+ }).then(replies => {
+ this.replies = replies;
+ });
+ }
+
+ // Draw map
+ if (this.p.geo) {
+ const shouldShowMap = (this as any).os.isSignedIn ? (this as any).os.i.account.clientSettings.showMaps : true;
+ if (shouldShowMap) {
+ (this as any).os.getGoogleMaps().then(maps => {
+ const uluru = new maps.LatLng(this.p.geo.coordinates[1], this.p.geo.coordinates[0]);
+ const map = new maps.Map(this.$refs.map, {
+ center: uluru,
+ zoom: 15
+ });
+ new maps.Marker({
+ position: uluru,
+ map: map
+ });
+ });
+ }
+ }
+ },
+
+ methods: {
+ fetchContext() {
+ this.contextFetching = true;
+
+ // Fetch context
+ (this as any).api('notes/context', {
+ noteId: this.p.replyId
+ }).then(context => {
+ this.contextFetching = false;
+ this.context = context.reverse();
+ });
+ },
+ reply() {
+ (this as any).apis.post({
+ reply: this.p
+ });
+ },
+ renote() {
+ (this as any).apis.post({
+ renote: this.p
+ });
+ },
+ react() {
+ (this as any).os.new(MkReactionPicker, {
+ source: this.$refs.reactButton,
+ note: this.p,
+ compact: true
+ });
+ },
+ menu() {
+ (this as any).os.new(MkNoteMenu, {
+ source: this.$refs.menuButton,
+ note: this.p,
+ compact: true
+ });
+ }
+ }
+});
+</script>
+
+<style lang="stylus" scoped>
+@import '~const.styl'
+
+.mk-note-detail
+ overflow hidden
+ margin 0 auto
+ padding 0
+ width 100%
+ text-align left
+ background #fff
+ border-radius 8px
+ box-shadow 0 0 0 1px rgba(0, 0, 0, 0.2)
+
+ > .fetching
+ padding 64px 0
+
+ > .more
+ display block
+ margin 0
+ padding 10px 0
+ width 100%
+ font-size 1em
+ text-align center
+ color #999
+ cursor pointer
+ background #fafafa
+ outline none
+ border none
+ border-bottom solid 1px #eef0f2
+ border-radius 6px 6px 0 0
+ box-shadow none
+
+ &:hover
+ background #f6f6f6
+
+ &:active
+ background #f0f0f0
+
+ &:disabled
+ color #ccc
+
+ > .context
+ > *
+ border-bottom 1px solid #eef0f2
+
+ > .renote
+ color #9dbb00
+ background linear-gradient(to bottom, #edfde2 0%, #fff 100%)
+
+ > p
+ margin 0
+ padding 16px 32px
+
+ .avatar-anchor
+ display inline-block
+
+ .avatar
+ vertical-align bottom
+ min-width 28px
+ min-height 28px
+ max-width 28px
+ max-height 28px
+ margin 0 8px 0 0
+ border-radius 6px
+
+ [data-fa]
+ margin-right 4px
+
+ .name
+ font-weight bold
+
+ & + article
+ padding-top 8px
+
+ > .reply-to
+ border-bottom 1px solid #eef0f2
+
+ > article
+ padding 14px 16px 9px 16px
+
+ @media (min-width 500px)
+ padding 28px 32px 18px 32px
+
+ &:after
+ content ""
+ display block
+ clear both
+
+ &:hover
+ > .main > footer > button
+ color #888
+
+ > header
+ display flex
+ line-height 1.1
+
+ > .avatar-anchor
+ display block
+ padding 0 .5em 0 0
+
+ > .avatar
+ display block
+ width 54px
+ height 54px
+ margin 0
+ border-radius 8px
+ vertical-align bottom
+
+ @media (min-width 500px)
+ width 60px
+ height 60px
+
+ > div
+
+ > .name
+ display inline-block
+ margin .4em 0
+ color #777
+ font-size 16px
+ font-weight bold
+ text-align left
+ text-decoration none
+
+ &:hover
+ text-decoration underline
+
+ > .username
+ display block
+ text-align left
+ margin 0
+ color #ccc
+
+ > .body
+ padding 8px 0
+
+ > .renote
+ margin 8px 0
+
+ > .mk-note-preview
+ padding 16px
+ border dashed 1px #c0dac6
+ border-radius 8px
+
+ > .location
+ margin 4px 0
+ font-size 12px
+ color #ccc
+
+ > .map
+ width 100%
+ height 200px
+
+ &:empty
+ display none
+
+ > .mk-url-preview
+ margin-top 8px
+
+ > .media
+ > img
+ display block
+ max-width 100%
+
+ > .tags
+ margin 4px 0 0 0
+
+ > *
+ display inline-block
+ margin 0 8px 0 0
+ padding 2px 8px 2px 16px
+ font-size 90%
+ color #8d969e
+ background #edf0f3
+ border-radius 4px
+
+ &:before
+ content ""
+ display block
+ position absolute
+ top 0
+ bottom 0
+ left 4px
+ width 8px
+ height 8px
+ margin auto 0
+ background #fff
+ border-radius 100%
+
+ > .time
+ font-size 16px
+ color #c0c0c0
+
+ > footer
+ font-size 1.2em
+
+ > button
+ margin 0
+ padding 8px
+ background transparent
+ border none
+ box-shadow none
+ font-size 1em
+ color #ddd
+ cursor pointer
+
+ &:not(:last-child)
+ margin-right 28px
+
+ &:hover
+ color #666
+
+ > .count
+ display inline
+ margin 0 0 0 8px
+ color #999
+
+ &.reacted
+ color $theme-color
+
+ > .replies
+ > *
+ border-top 1px solid #eef0f2
+
+</style>
+
+<style lang="stylus" module>
+.text
+ display block
+ margin 0
+ padding 0
+ overflow-wrap break-word
+ font-size 16px
+ color #717171
+
+ @media (min-width 500px)
+ font-size 24px
+
+</style>
diff --git a/src/client/app/mobile/views/components/post-preview.vue b/src/client/app/mobile/views/components/note-preview.vue
index 96bd4d5c15..8c8d8645bb 100644
--- a/src/client/app/mobile/views/components/post-preview.vue
+++ b/src/client/app/mobile/views/components/note-preview.vue
@@ -1,18 +1,18 @@
<template>
-<div class="mk-post-preview">
+<div class="mk-note-preview">
<router-link class="avatar-anchor" :to="`/@${acct}`">
- <img class="avatar" :src="`${post.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
+ <img class="avatar" :src="`${note.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
</router-link>
<div class="main">
<header>
<router-link class="name" :to="`/@${acct}`">{{ name }}</router-link>
<span class="username">@{{ acct }}</span>
- <router-link class="time" :to="`/@${acct}/${post.id}`">
- <mk-time :time="post.createdAt"/>
+ <router-link class="time" :to="`/@${acct}/${note.id}`">
+ <mk-time :time="note.createdAt"/>
</router-link>
</header>
<div class="body">
- <mk-sub-post-content class="text" :post="post"/>
+ <mk-sub-note-content class="text" :note="note"/>
</div>
</div>
</div>
@@ -24,20 +24,20 @@ import getAcct from '../../../../../acct/render';
import getUserName from '../../../../../renderers/get-user-name';
export default Vue.extend({
- props: ['post'],
+ props: ['note'],
computed: {
acct() {
- return getAcct(this.post.user);
+ return getAcct(this.note.user);
},
name() {
- return getUserName(this.post.user);
+ return getUserName(this.note.user);
}
}
});
</script>
<style lang="stylus" scoped>
-.mk-post-preview
+.mk-note-preview
margin 0
padding 0
font-size 0.9em
diff --git a/src/client/app/mobile/views/components/post.sub.vue b/src/client/app/mobile/views/components/note.sub.vue
index 909d5cb597..a37d0dea08 100644
--- a/src/client/app/mobile/views/components/post.sub.vue
+++ b/src/client/app/mobile/views/components/note.sub.vue
@@ -1,18 +1,18 @@
<template>
<div class="sub">
<router-link class="avatar-anchor" :to="`/@${acct}`">
- <img class="avatar" :src="`${post.user.avatarUrl}?thumbnail&size=96`" alt="avatar"/>
+ <img class="avatar" :src="`${note.user.avatarUrl}?thumbnail&size=96`" alt="avatar"/>
</router-link>
<div class="main">
<header>
- <router-link class="name" :to="`/@${acct}`">{{ getUserName(post.user) }}</router-link>
+ <router-link class="name" :to="`/@${acct}`">{{ getUserName(note.user) }}</router-link>
<span class="username">@{{ acct }}</span>
- <router-link class="created-at" :to="`/@${acct}/${post.id}`">
- <mk-time :time="post.createdAt"/>
+ <router-link class="created-at" :to="`/@${acct}/${note.id}`">
+ <mk-time :time="note.createdAt"/>
</router-link>
</header>
<div class="body">
- <mk-sub-post-content class="text" :post="post"/>
+ <mk-sub-note-content class="text" :note="note"/>
</div>
</div>
</div>
@@ -24,13 +24,13 @@ import getAcct from '../../../../../acct/render';
import getUserName from '../../../../../renderers/get-user-name';
export default Vue.extend({
- props: ['post'],
+ props: ['note'],
computed: {
acct() {
- return getAcct(this.post.user);
+ return getAcct(this.note.user);
},
name() {
- return getUserName(this.post.user);
+ return getUserName(this.note.user);
}
}
});
diff --git a/src/client/app/mobile/views/components/note.vue b/src/client/app/mobile/views/components/note.vue
new file mode 100644
index 0000000000..4b33c6f071
--- /dev/null
+++ b/src/client/app/mobile/views/components/note.vue
@@ -0,0 +1,540 @@
+<template>
+<div class="note" :class="{ renote: isRenote }">
+ <div class="reply-to" v-if="p.reply">
+ <x-sub :note="p.reply"/>
+ </div>
+ <div class="renote" v-if="isRenote">
+ <p>
+ <router-link class="avatar-anchor" :to="`/@${acct}`">
+ <img class="avatar" :src="`${note.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
+ </router-link>
+ %fa:retweet%
+ <span>{{ '%i18n:mobile.tags.mk-timeline-note.reposted-by%'.substr(0, '%i18n:mobile.tags.mk-timeline-note.reposted-by%'.indexOf('{')) }}</span>
+ <router-link class="name" :to="`/@${acct}`">{{ name }}</router-link>
+ <span>{{ '%i18n:mobile.tags.mk-timeline-note.reposted-by%'.substr('%i18n:mobile.tags.mk-timeline-note.reposted-by%'.indexOf('}') + 1) }}</span>
+ </p>
+ <mk-time :time="note.createdAt"/>
+ </div>
+ <article>
+ <router-link class="avatar-anchor" :to="`/@${pAcct}`">
+ <img class="avatar" :src="`${p.user.avatarUrl}?thumbnail&size=96`" alt="avatar"/>
+ </router-link>
+ <div class="main">
+ <header>
+ <router-link class="name" :to="`/@${pAcct}`">{{ pName }}</router-link>
+ <span class="is-bot" v-if="p.user.host === null && p.user.account.isBot">bot</span>
+ <span class="username">@{{ pAcct }}</span>
+ <div class="info">
+ <span class="mobile" v-if="p.viaMobile">%fa:mobile-alt%</span>
+ <router-link class="created-at" :to="url">
+ <mk-time :time="p.createdAt"/>
+ </router-link>
+ </div>
+ </header>
+ <div class="body">
+ <p class="channel" v-if="p.channel != null"><a target="_blank">{{ p.channel.title }}</a>:</p>
+ <div class="text">
+ <a class="reply" v-if="p.reply">
+ %fa:reply%
+ </a>
+ <mk-note-html v-if="p.text" :text="p.text" :i="os.i" :class="$style.text"/>
+ <a class="rp" v-if="p.renote != null">RP:</a>
+ </div>
+ <div class="media" v-if="p.media.length > 0">
+ <mk-media-list :media-list="p.media"/>
+ </div>
+ <mk-poll v-if="p.poll" :note="p" ref="pollViewer"/>
+ <div class="tags" v-if="p.tags && p.tags.length > 0">
+ <router-link v-for="tag in p.tags" :key="tag" :to="`/search?q=#${tag}`">{{ tag }}</router-link>
+ </div>
+ <mk-url-preview v-for="url in urls" :url="url" :key="url"/>
+ <a class="location" v-if="p.geo" :href="`http://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% 位置情報</a>
+ <div class="map" v-if="p.geo" ref="map"></div>
+ <span class="app" v-if="p.app">via <b>{{ p.app.name }}</b></span>
+ <div class="renote" v-if="p.renote">
+ <mk-note-preview :note="p.renote"/>
+ </div>
+ </div>
+ <footer>
+ <mk-reactions-viewer :note="p" ref="reactionsViewer"/>
+ <button @click="reply">
+ %fa:reply%<p class="count" v-if="p.repliesCount > 0">{{ p.repliesCount }}</p>
+ </button>
+ <button @click="renote" title="Renote">
+ %fa:retweet%<p class="count" v-if="p.renoteCount > 0">{{ p.renoteCount }}</p>
+ </button>
+ <button :class="{ reacted: p.myReaction != null }" @click="react" ref="reactButton">
+ %fa:plus%<p class="count" v-if="p.reactions_count > 0">{{ p.reactions_count }}</p>
+ </button>
+ <button class="menu" @click="menu" ref="menuButton">
+ %fa:ellipsis-h%
+ </button>
+ </footer>
+ </div>
+ </article>
+</div>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+import getAcct from '../../../../../acct/render';
+import getUserName from '../../../../../renderers/get-user-name';
+import parse from '../../../../../text/parse';
+
+import MkNoteMenu from '../../../common/views/components/note-menu.vue';
+import MkReactionPicker from '../../../common/views/components/reaction-picker.vue';
+import XSub from './note.sub.vue';
+
+export default Vue.extend({
+ components: {
+ XSub
+ },
+
+ props: ['note'],
+
+ data() {
+ return {
+ connection: null,
+ connectionId: null
+ };
+ },
+
+ computed: {
+ acct(): string {
+ return getAcct(this.note.user);
+ },
+ name(): string {
+ return getUserName(this.note.user);
+ },
+ pAcct(): string {
+ return getAcct(this.p.user);
+ },
+ pName(): string {
+ return getUserName(this.p.user);
+ },
+ isRenote(): boolean {
+ return (this.note.renote &&
+ this.note.text == null &&
+ this.note.mediaIds == null &&
+ this.note.poll == null);
+ },
+ p(): any {
+ return this.isRenote ? this.note.renote : this.note;
+ },
+ reactionsCount(): number {
+ return this.p.reactionCounts
+ ? Object.keys(this.p.reactionCounts)
+ .map(key => this.p.reactionCounts[key])
+ .reduce((a, b) => a + b)
+ : 0;
+ },
+ url(): string {
+ return `/@${this.pAcct}/${this.p.id}`;
+ },
+ urls(): string[] {
+ if (this.p.text) {
+ const ast = parse(this.p.text);
+ return ast
+ .filter(t => (t.type == 'url' || t.type == 'link') && !t.silent)
+ .map(t => t.url);
+ } else {
+ return null;
+ }
+ }
+ },
+
+ created() {
+ if ((this as any).os.isSignedIn) {
+ this.connection = (this as any).os.stream.getConnection();
+ this.connectionId = (this as any).os.stream.use();
+ }
+ },
+
+ mounted() {
+ this.capture(true);
+
+ if ((this as any).os.isSignedIn) {
+ this.connection.on('_connected_', this.onStreamConnected);
+ }
+
+ // Draw map
+ if (this.p.geo) {
+ const shouldShowMap = (this as any).os.isSignedIn ? (this as any).os.i.account.clientSettings.showMaps : true;
+ if (shouldShowMap) {
+ (this as any).os.getGoogleMaps().then(maps => {
+ const uluru = new maps.LatLng(this.p.geo.coordinates[1], this.p.geo.coordinates[0]);
+ const map = new maps.Map(this.$refs.map, {
+ center: uluru,
+ zoom: 15
+ });
+ new maps.Marker({
+ position: uluru,
+ map: map
+ });
+ });
+ }
+ }
+ },
+
+ beforeDestroy() {
+ this.decapture(true);
+
+ if ((this as any).os.isSignedIn) {
+ this.connection.off('_connected_', this.onStreamConnected);
+ (this as any).os.stream.dispose(this.connectionId);
+ }
+ },
+
+ methods: {
+ capture(withHandler = false) {
+ if ((this as any).os.isSignedIn) {
+ this.connection.send({
+ type: 'capture',
+ id: this.p.id
+ });
+ if (withHandler) this.connection.on('note-updated', this.onStreamNoteUpdated);
+ }
+ },
+ decapture(withHandler = false) {
+ if ((this as any).os.isSignedIn) {
+ this.connection.send({
+ type: 'decapture',
+ id: this.p.id
+ });
+ if (withHandler) this.connection.off('note-updated', this.onStreamNoteUpdated);
+ }
+ },
+ onStreamConnected() {
+ this.capture();
+ },
+ onStreamNoteUpdated(data) {
+ const note = data.note;
+ if (note.id == this.note.id) {
+ this.$emit('update:note', note);
+ } else if (note.id == this.note.renoteId) {
+ this.note.renote = note;
+ }
+ },
+ reply() {
+ (this as any).apis.post({
+ reply: this.p
+ });
+ },
+ renote() {
+ (this as any).apis.post({
+ renote: this.p
+ });
+ },
+ react() {
+ (this as any).os.new(MkReactionPicker, {
+ source: this.$refs.reactButton,
+ note: this.p,
+ compact: true
+ });
+ },
+ menu() {
+ (this as any).os.new(MkNoteMenu, {
+ source: this.$refs.menuButton,
+ note: this.p,
+ compact: true
+ });
+ }
+ }
+});
+</script>
+
+<style lang="stylus" scoped>
+@import '~const.styl'
+
+.note
+ font-size 12px
+ border-bottom solid 1px #eaeaea
+
+ &:first-child
+ border-radius 8px 8px 0 0
+
+ > .renote
+ border-radius 8px 8px 0 0
+
+ &:last-of-type
+ border-bottom none
+
+ @media (min-width 350px)
+ font-size 14px
+
+ @media (min-width 500px)
+ font-size 16px
+
+ > .renote
+ color #9dbb00
+ background linear-gradient(to bottom, #edfde2 0%, #fff 100%)
+
+ > p
+ margin 0
+ padding 8px 16px
+ line-height 28px
+
+ @media (min-width 500px)
+ padding 16px
+
+ .avatar-anchor
+ display inline-block
+
+ .avatar
+ vertical-align bottom
+ width 28px
+ height 28px
+ margin 0 8px 0 0
+ border-radius 6px
+
+ [data-fa]
+ margin-right 4px
+
+ .name
+ font-weight bold
+
+ > .mk-time
+ position absolute
+ top 8px
+ right 16px
+ font-size 0.9em
+ line-height 28px
+
+ @media (min-width 500px)
+ top 16px
+
+ & + article
+ padding-top 8px
+
+ > .reply-to
+ background rgba(0, 0, 0, 0.0125)
+
+ > .mk-note-preview
+ background transparent
+
+ > article
+ padding 14px 16px 9px 16px
+
+ &:after
+ content ""
+ display block
+ clear both
+
+ > .avatar-anchor
+ display block
+ float left
+ margin 0 10px 8px 0
+ position -webkit-sticky
+ position sticky
+ top 62px
+
+ @media (min-width 500px)
+ margin-right 16px
+
+ > .avatar
+ display block
+ width 48px
+ height 48px
+ margin 0
+ border-radius 6px
+ vertical-align bottom
+
+ @media (min-width 500px)
+ width 58px
+ height 58px
+ border-radius 8px
+
+ > .main
+ float left
+ width calc(100% - 58px)
+
+ @media (min-width 500px)
+ width calc(100% - 74px)
+
+ > header
+ display flex
+ align-items center
+ white-space nowrap
+
+ @media (min-width 500px)
+ margin-bottom 2px
+
+ > .name
+ display block
+ margin 0 0.5em 0 0
+ padding 0
+ overflow hidden
+ color #627079
+ font-size 1em
+ font-weight bold
+ text-decoration none
+ text-overflow ellipsis
+
+ &:hover
+ text-decoration underline
+
+ > .is-bot
+ margin 0 0.5em 0 0
+ padding 1px 6px
+ font-size 12px
+ color #aaa
+ border solid 1px #ddd
+ border-radius 3px
+
+ > .username
+ margin 0 0.5em 0 0
+ color #ccc
+
+ > .info
+ margin-left auto
+ font-size 0.9em
+
+ > .mobile
+ margin-right 6px
+ color #c0c0c0
+
+ > .created-at
+ color #c0c0c0
+
+ > .body
+
+ > .text
+ display block
+ margin 0
+ padding 0
+ overflow-wrap break-word
+ font-size 1.1em
+ color #717171
+
+ >>> .quote
+ margin 8px
+ padding 6px 12px
+ color #aaa
+ border-left solid 3px #eee
+
+ > .reply
+ margin-right 8px
+ color #717171
+
+ > .rp
+ margin-left 4px
+ font-style oblique
+ color #a0bf46
+
+ [data-is-me]:after
+ content "you"
+ padding 0 4px
+ margin-left 4px
+ font-size 80%
+ color $theme-color-foreground
+ background $theme-color
+ border-radius 4px
+
+ .mk-url-preview
+ margin-top 8px
+
+ > .channel
+ margin 0
+
+ > .tags
+ margin 4px 0 0 0
+
+ > *
+ display inline-block
+ margin 0 8px 0 0
+ padding 2px 8px 2px 16px
+ font-size 90%
+ color #8d969e
+ background #edf0f3
+ border-radius 4px
+
+ &:before
+ content ""
+ display block
+ position absolute
+ top 0
+ bottom 0
+ left 4px
+ width 8px
+ height 8px
+ margin auto 0
+ background #fff
+ border-radius 100%
+
+ > .media
+ > img
+ display block
+ max-width 100%
+
+ > .location
+ margin 4px 0
+ font-size 12px
+ color #ccc
+
+ > .map
+ width 100%
+ height 200px
+
+ &:empty
+ display none
+
+ > .app
+ font-size 12px
+ color #ccc
+
+ > .mk-poll
+ font-size 80%
+
+ > .renote
+ margin 8px 0
+
+ > .mk-note-preview
+ padding 16px
+ border dashed 1px #c0dac6
+ border-radius 8px
+
+ > footer
+ > button
+ margin 0
+ padding 8px
+ background transparent
+ border none
+ box-shadow none
+ font-size 1em
+ color #ddd
+ cursor pointer
+
+ &:not(:last-child)
+ margin-right 28px
+
+ &:hover
+ color #666
+
+ > .count
+ display inline
+ margin 0 0 0 8px
+ color #999
+
+ &.reacted
+ color $theme-color
+
+ &.menu
+ @media (max-width 350px)
+ display none
+
+</style>
+
+<style lang="stylus" module>
+.text
+ code
+ padding 4px 8px
+ margin 0 0.5em
+ font-size 80%
+ color #525252
+ background #f8f8f8
+ border-radius 2px
+
+ pre > code
+ padding 16px
+ margin 0
+</style>
diff --git a/src/client/app/mobile/views/components/posts.vue b/src/client/app/mobile/views/components/notes.vue
index 4695f1beaa..573026d53e 100644
--- a/src/client/app/mobile/views/components/posts.vue
+++ b/src/client/app/mobile/views/components/notes.vue
@@ -1,12 +1,12 @@
<template>
-<div class="mk-posts">
+<div class="mk-notes">
<slot name="head"></slot>
<slot></slot>
- <template v-for="(post, i) in _posts">
- <mk-post :post="post" :key="post.id" @update:post="onPostUpdated(i, $event)"/>
- <p class="date" v-if="i != posts.length - 1 && post._date != _posts[i + 1]._date">
- <span>%fa:angle-up%{{ post._datetext }}</span>
- <span>%fa:angle-down%{{ _posts[i + 1]._datetext }}</span>
+ <template v-for="(note, i) in _notes">
+ <mk-note :note="note" :key="note.id" @update:note="onNoteUpdated(i, $event)"/>
+ <p class="date" v-if="i != notes.length - 1 && note._date != _notes[i + 1]._date">
+ <span>%fa:angle-up%{{ note._datetext }}</span>
+ <span>%fa:angle-down%{{ _notes[i + 1]._datetext }}</span>
</p>
</template>
<footer>
@@ -20,25 +20,25 @@ import Vue from 'vue';
export default Vue.extend({
props: {
- posts: {
+ notes: {
type: Array,
default: () => []
}
},
computed: {
- _posts(): any[] {
- return (this.posts as any).map(post => {
- const date = new Date(post.createdAt).getDate();
- const month = new Date(post.createdAt).getMonth() + 1;
- post._date = date;
- post._datetext = `${month}月 ${date}日`;
- return post;
+ _notes(): any[] {
+ return (this.notes as any).map(note => {
+ const date = new Date(note.createdAt).getDate();
+ const month = new Date(note.createdAt).getMonth() + 1;
+ note._date = date;
+ note._datetext = `${month}月 ${date}日`;
+ return note;
});
}
},
methods: {
- onPostUpdated(i, post) {
- Vue.set((this as any).posts, i, post);
+ onNoteUpdated(i, note) {
+ Vue.set((this as any).notes, i, note);
}
}
});
@@ -47,7 +47,7 @@ export default Vue.extend({
<style lang="stylus" scoped>
@import '~const.styl'
-.mk-posts
+.mk-notes
background #fff
border-radius 8px
box-shadow 0 0 0 1px rgba(0, 0, 0, 0.2)
diff --git a/src/client/app/mobile/views/components/notification-preview.vue b/src/client/app/mobile/views/components/notification-preview.vue
index 0492c5d86c..79ca3321e4 100644
--- a/src/client/app/mobile/views/components/notification-preview.vue
+++ b/src/client/app/mobile/views/components/notification-preview.vue
@@ -4,23 +4,23 @@
<img class="avatar" :src="`${notification.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
<div class="text">
<p><mk-reaction-icon :reaction="notification.reaction"/>{{ name }}</p>
- <p class="post-ref">%fa:quote-left%{{ getPostSummary(notification.post) }}%fa:quote-right%</p>
+ <p class="note-ref">%fa:quote-left%{{ getNoteSummary(notification.note) }}%fa:quote-right%</p>
</div>
</template>
- <template v-if="notification.type == 'repost'">
- <img class="avatar" :src="`${notification.post.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
+ <template v-if="notification.type == 'renote'">
+ <img class="avatar" :src="`${notification.note.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
<div class="text">
- <p>%fa:retweet%{{ posterName }}</p>
- <p class="post-ref">%fa:quote-left%{{ getPostSummary(notification.post.repost) }}%fa:quote-right%</p>
+ <p>%fa:retweet%{{ noteerName }}</p>
+ <p class="note-ref">%fa:quote-left%{{ getNoteSummary(notification.note.renote) }}%fa:quote-right%</p>
</div>
</template>
<template v-if="notification.type == 'quote'">
- <img class="avatar" :src="`${notification.post.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
+ <img class="avatar" :src="`${notification.note.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
<div class="text">
- <p>%fa:quote-left%{{ posterName }}</p>
- <p class="post-preview">{{ getPostSummary(notification.post) }}</p>
+ <p>%fa:quote-left%{{ noteerName }}</p>
+ <p class="note-preview">{{ getNoteSummary(notification.note) }}</p>
</div>
</template>
@@ -32,18 +32,18 @@
</template>
<template v-if="notification.type == 'reply'">
- <img class="avatar" :src="`${notification.post.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
+ <img class="avatar" :src="`${notification.note.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
<div class="text">
- <p>%fa:reply%{{ posterName }}</p>
- <p class="post-preview">{{ getPostSummary(notification.post) }}</p>
+ <p>%fa:reply%{{ noteerName }}</p>
+ <p class="note-preview">{{ getNoteSummary(notification.note) }}</p>
</div>
</template>
<template v-if="notification.type == 'mention'">
- <img class="avatar" :src="`${notification.post.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
+ <img class="avatar" :src="`${notification.note.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
<div class="text">
- <p>%fa:at%{{ posterName }}</p>
- <p class="post-preview">{{ getPostSummary(notification.post) }}</p>
+ <p>%fa:at%{{ noteerName }}</p>
+ <p class="note-preview">{{ getNoteSummary(notification.note) }}</p>
</div>
</template>
@@ -51,7 +51,7 @@
<img class="avatar" :src="`${notification.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
<div class="text">
<p>%fa:chart-pie%{{ name }}</p>
- <p class="post-ref">%fa:quote-left%{{ getPostSummary(notification.post) }}%fa:quote-right%</p>
+ <p class="note-ref">%fa:quote-left%{{ getNoteSummary(notification.note) }}%fa:quote-right%</p>
</div>
</template>
</div>
@@ -59,7 +59,7 @@
<script lang="ts">
import Vue from 'vue';
-import getPostSummary from '../../../../../renderers/get-post-summary';
+import getNoteSummary from '../../../../../renderers/get-note-summary';
import getUserName from '../../../../../renderers/get-user-name';
export default Vue.extend({
@@ -68,13 +68,13 @@ export default Vue.extend({
name() {
return getUserName(this.notification.user);
},
- posterName() {
- return getUserName(this.notification.post.user);
+ noteerName() {
+ return getUserName(this.notification.note.user);
}
},
data() {
return {
- getPostSummary
+ getNoteSummary
};
}
});
@@ -112,7 +112,7 @@ export default Vue.extend({
i, mk-reaction-icon
margin-right 4px
- .post-ref
+ .note-ref
[data-fa]
font-size 1em
@@ -121,7 +121,7 @@ export default Vue.extend({
display inline-block
margin-right 3px
- &.repost, &.quote
+ &.renote, &.quote
.text p i
color #77B255
diff --git a/src/client/app/mobile/views/components/notification.vue b/src/client/app/mobile/views/components/notification.vue
index 62a0e6425e..e1294a8778 100644
--- a/src/client/app/mobile/views/components/notification.vue
+++ b/src/client/app/mobile/views/components/notification.vue
@@ -10,31 +10,31 @@
<mk-reaction-icon :reaction="notification.reaction"/>
<router-link :to="`/@${acct}`">{{ getUserName(notification.user) }}</router-link>
</p>
- <router-link class="post-ref" :to="`/@${acct}/${notification.post.id}`">
- %fa:quote-left%{{ getPostSummary(notification.post) }}
+ <router-link class="note-ref" :to="`/@${acct}/${notification.note.id}`">
+ %fa:quote-left%{{ getNoteSummary(notification.note) }}
%fa:quote-right%
</router-link>
</div>
</div>
- <div class="notification repost" v-if="notification.type == 'repost'">
+ <div class="notification renote" v-if="notification.type == 'renote'">
<mk-time :time="notification.createdAt"/>
<router-link class="avatar-anchor" :to="`/@${acct}`">
- <img class="avatar" :src="`${notification.post.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
+ <img class="avatar" :src="`${notification.note.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
</router-link>
<div class="text">
<p>
%fa:retweet%
- <router-link :to="`/@${acct}`">{{ getUserName(notification.post.user) }}</router-link>
+ <router-link :to="`/@${acct}`">{{ getUserName(notification.note.user) }}</router-link>
</p>
- <router-link class="post-ref" :to="`/@${acct}/${notification.post.id}`">
- %fa:quote-left%{{ getPostSummary(notification.post.repost) }}%fa:quote-right%
+ <router-link class="note-ref" :to="`/@${acct}/${notification.note.id}`">
+ %fa:quote-left%{{ getNoteSummary(notification.note.renote) }}%fa:quote-right%
</router-link>
</div>
</div>
<template v-if="notification.type == 'quote'">
- <mk-post :post="notification.post"/>
+ <mk-note :note="notification.note"/>
</template>
<div class="notification follow" v-if="notification.type == 'follow'">
@@ -51,11 +51,11 @@
</div>
<template v-if="notification.type == 'reply'">
- <mk-post :post="notification.post"/>
+ <mk-note :note="notification.note"/>
</template>
<template v-if="notification.type == 'mention'">
- <mk-post :post="notification.post"/>
+ <mk-note :note="notification.note"/>
</template>
<div class="notification poll_vote" v-if="notification.type == 'poll_vote'">
@@ -68,8 +68,8 @@
%fa:chart-pie%
<router-link :to="`/@${acct}`">{{ getUserName(notification.user) }}</router-link>
</p>
- <router-link class="post-ref" :to="`/@${acct}/${notification.post.id}`">
- %fa:quote-left%{{ getPostSummary(notification.post) }}%fa:quote-right%
+ <router-link class="note-ref" :to="`/@${acct}/${notification.note.id}`">
+ %fa:quote-left%{{ getNoteSummary(notification.note) }}%fa:quote-right%
</router-link>
</div>
</div>
@@ -78,7 +78,7 @@
<script lang="ts">
import Vue from 'vue';
-import getPostSummary from '../../../../../renderers/get-post-summary';
+import getNoteSummary from '../../../../../renderers/get-note-summary';
import getAcct from '../../../../../acct/render';
import getUserName from '../../../../../renderers/get-user-name';
@@ -91,13 +91,13 @@ export default Vue.extend({
name() {
return getUserName(this.notification.user);
},
- posterName() {
- return getUserName(this.notification.post.user);
+ noteerName() {
+ return getUserName(this.notification.note.user);
}
},
data() {
return {
- getPostSummary
+ getNoteSummary
};
}
});
@@ -146,10 +146,10 @@ export default Vue.extend({
i, .mk-reaction-icon
margin-right 4px
- > .post-preview
+ > .note-preview
color rgba(0, 0, 0, 0.7)
- > .post-ref
+ > .note-ref
color rgba(0, 0, 0, 0.7)
[data-fa]
@@ -159,7 +159,7 @@ export default Vue.extend({
display inline-block
margin-right 3px
- &.repost
+ &.renote
.text p i
color #77B255
diff --git a/src/client/app/mobile/views/components/post-detail.vue b/src/client/app/mobile/views/components/post-detail.vue
index 0226ce081a..e1682e58ed 100644
--- a/src/client/app/mobile/views/components/post-detail.vue
+++ b/src/client/app/mobile/views/components/post-detail.vue
@@ -1,5 +1,5 @@
<template>
-<div class="mk-post-detail">
+<div class="mk-note-detail">
<button
class="more"
v-if="p.reply && p.reply.replyId && context == null"
@@ -10,21 +10,21 @@
<template v-if="contextFetching">%fa:spinner .pulse%</template>
</button>
<div class="context">
- <x-sub v-for="post in context" :key="post.id" :post="post"/>
+ <x-sub v-for="note in context" :key="note.id" :note="note"/>
</div>
<div class="reply-to" v-if="p.reply">
- <x-sub :post="p.reply"/>
+ <x-sub :note="p.reply"/>
</div>
- <div class="repost" v-if="isRepost">
+ <div class="renote" v-if="isRenote">
<p>
<router-link class="avatar-anchor" :to="`/@${acct}`">
- <img class="avatar" :src="`${post.user.avatarUrl}?thumbnail&size=32`" alt="avatar"/>
+ <img class="avatar" :src="`${note.user.avatarUrl}?thumbnail&size=32`" alt="avatar"/>
</router-link>
%fa:retweet%
<router-link class="name" :to="`/@${acct}`">
{{ name }}
</router-link>
- がRepost
+ がRenote
</p>
</div>
<article>
@@ -38,33 +38,33 @@
</div>
</header>
<div class="body">
- <mk-post-html v-if="p.text" :ast="p.text" :i="os.i" :class="$style.text"/>
+ <mk-note-html v-if="p.text" :ast="p.text" :i="os.i" :class="$style.text"/>
<div class="tags" v-if="p.tags && p.tags.length > 0">
<router-link v-for="tag in p.tags" :key="tag" :to="`/search?q=#${tag}`">{{ tag }}</router-link>
</div>
<div class="media" v-if="p.media.length > 0">
<mk-media-list :media-list="p.media"/>
</div>
- <mk-poll v-if="p.poll" :post="p"/>
+ <mk-poll v-if="p.poll" :note="p"/>
<mk-url-preview v-for="url in urls" :url="url" :key="url"/>
<a class="location" v-if="p.geo" :href="`http://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% 位置情報</a>
<div class="map" v-if="p.geo" ref="map"></div>
- <div class="repost" v-if="p.repost">
- <mk-post-preview :post="p.repost"/>
+ <div class="renote" v-if="p.renote">
+ <mk-note-preview :note="p.renote"/>
</div>
</div>
<router-link class="time" :to="`/@${pAcct}/${p.id}`">
<mk-time :time="p.createdAt" mode="detail"/>
</router-link>
<footer>
- <mk-reactions-viewer :post="p"/>
- <button @click="reply" title="%i18n:mobile.tags.mk-post-detail.reply%">
+ <mk-reactions-viewer :note="p"/>
+ <button @click="reply" title="%i18n:mobile.tags.mk-note-detail.reply%">
%fa:reply%<p class="count" v-if="p.repliesCount > 0">{{ p.repliesCount }}</p>
</button>
- <button @click="repost" title="Repost">
- %fa:retweet%<p class="count" v-if="p.repostCount > 0">{{ p.repostCount }}</p>
+ <button @click="renote" title="Renote">
+ %fa:retweet%<p class="count" v-if="p.renoteCount > 0">{{ p.renoteCount }}</p>
</button>
- <button :class="{ reacted: p.myReaction != null }" @click="react" ref="reactButton" title="%i18n:mobile.tags.mk-post-detail.reaction%">
+ <button :class="{ reacted: p.myReaction != null }" @click="react" ref="reactButton" title="%i18n:mobile.tags.mk-note-detail.reaction%">
%fa:plus%<p class="count" v-if="p.reactions_count > 0">{{ p.reactions_count }}</p>
</button>
<button @click="menu" ref="menuButton">
@@ -73,7 +73,7 @@
</footer>
</article>
<div class="replies" v-if="!compact">
- <x-sub v-for="post in replies" :key="post.id" :post="post"/>
+ <x-sub v-for="note in replies" :key="note.id" :note="note"/>
</div>
</div>
</template>
@@ -84,9 +84,9 @@ import getAcct from '../../../../../acct/render';
import getUserName from '../../../../../renderers/get-user-name';
import parse from '../../../../../text/parse';
-import MkPostMenu from '../../../common/views/components/post-menu.vue';
+import MkNoteMenu from '../../../common/views/components/note-menu.vue';
import MkReactionPicker from '../../../common/views/components/reaction-picker.vue';
-import XSub from './post-detail.sub.vue';
+import XSub from './note-detail.sub.vue';
export default Vue.extend({
components: {
@@ -94,7 +94,7 @@ export default Vue.extend({
},
props: {
- post: {
+ note: {
type: Object,
required: true
},
@@ -113,10 +113,10 @@ export default Vue.extend({
computed: {
acct(): string {
- return getAcct(this.post.user);
+ return getAcct(this.note.user);
},
name(): string {
- return getUserName(this.post.user);
+ return getUserName(this.note.user);
},
pAcct(): string {
return getAcct(this.p.user);
@@ -124,14 +124,14 @@ export default Vue.extend({
pName(): string {
return getUserName(this.p.user);
},
- isRepost(): boolean {
- return (this.post.repost &&
- this.post.text == null &&
- this.post.mediaIds == null &&
- this.post.poll == null);
+ isRenote(): boolean {
+ return (this.note.renote &&
+ this.note.text == null &&
+ this.note.mediaIds == null &&
+ this.note.poll == null);
},
p(): any {
- return this.isRepost ? this.post.repost : this.post;
+ return this.isRenote ? this.note.renote : this.note;
},
reactionsCount(): number {
return this.p.reactionCounts
@@ -155,8 +155,8 @@ export default Vue.extend({
mounted() {
// Get replies
if (!this.compact) {
- (this as any).api('posts/replies', {
- postId: this.p.id,
+ (this as any).api('notes/replies', {
+ noteId: this.p.id,
limit: 8
}).then(replies => {
this.replies = replies;
@@ -187,8 +187,8 @@ export default Vue.extend({
this.contextFetching = true;
// Fetch context
- (this as any).api('posts/context', {
- postId: this.p.replyId
+ (this as any).api('notes/context', {
+ noteId: this.p.replyId
}).then(context => {
this.contextFetching = false;
this.context = context.reverse();
@@ -199,22 +199,22 @@ export default Vue.extend({
reply: this.p
});
},
- repost() {
+ renote() {
(this as any).apis.post({
- repost: this.p
+ renote: this.p
});
},
react() {
(this as any).os.new(MkReactionPicker, {
source: this.$refs.reactButton,
- post: this.p,
+ note: this.p,
compact: true
});
},
menu() {
- (this as any).os.new(MkPostMenu, {
+ (this as any).os.new(MkNoteMenu, {
source: this.$refs.menuButton,
- post: this.p,
+ note: this.p,
compact: true
});
}
@@ -225,7 +225,7 @@ export default Vue.extend({
<style lang="stylus" scoped>
@import '~const.styl'
-.mk-post-detail
+.mk-note-detail
overflow hidden
margin 0 auto
padding 0
@@ -267,7 +267,7 @@ export default Vue.extend({
> *
border-bottom 1px solid #eef0f2
- > .repost
+ > .renote
color #9dbb00
background linear-gradient(to bottom, #edfde2 0%, #fff 100%)
@@ -357,10 +357,10 @@ export default Vue.extend({
> .body
padding 8px 0
- > .repost
+ > .renote
margin 8px 0
- > .mk-post-preview
+ > .mk-note-preview
padding 16px
border dashed 1px #c0dac6
border-radius 8px
diff --git a/src/client/app/mobile/views/components/post-form.vue b/src/client/app/mobile/views/components/post-form.vue
index 5b78a25710..6fcbbb47e8 100644
--- a/src/client/app/mobile/views/components/post-form.vue
+++ b/src/client/app/mobile/views/components/post-form.vue
@@ -9,8 +9,8 @@
</div>
</header>
<div class="form">
- <mk-post-preview v-if="reply" :post="reply"/>
- <textarea v-model="text" ref="text" :disabled="posting" :placeholder="reply ? '%i18n:mobile.tags.mk-post-form.reply-placeholder%' : '%i18n:mobile.tags.mk-post-form.post-placeholder%'"></textarea>
+ <mk-note-preview v-if="reply" :note="reply"/>
+ <textarea v-model="text" ref="text" :disabled="posting" :placeholder="reply ? '%i18n:mobile.tags.mk-post-form.reply-placeholder%' : '%i18n:mobile.tags.mk-post-form.note-placeholder%'"></textarea>
<div class="attaches" v-show="files.length != 0">
<x-draggable class="files" :list="files" :options="{ animation: 150 }">
<div class="file" v-for="file in files" :key="file.id">
@@ -112,7 +112,7 @@ export default Vue.extend({
post() {
this.posting = true;
const viaMobile = (this as any).os.i.account.clientSettings.disableViaMobile !== true;
- (this as any).api('posts/create', {
+ (this as any).api('notes/create', {
text: this.text == '' ? undefined : this.text,
mediaIds: this.files.length > 0 ? this.files.map(f => f.id) : undefined,
replyId: this.reply ? this.reply.id : undefined,
@@ -127,7 +127,7 @@ export default Vue.extend({
} : null,
viaMobile: viaMobile
}).then(data => {
- this.$emit('post');
+ this.$emit('note');
this.$destroy();
}).catch(err => {
this.posting = false;
@@ -200,7 +200,7 @@ export default Vue.extend({
max-width 500px
margin 0 auto
- > .mk-post-preview
+ > .mk-note-preview
padding 16px
> .attaches
diff --git a/src/client/app/mobile/views/components/post.vue b/src/client/app/mobile/views/components/post.vue
index eee1e80fd3..4b33c6f071 100644
--- a/src/client/app/mobile/views/components/post.vue
+++ b/src/client/app/mobile/views/components/post.vue
@@ -1,19 +1,19 @@
<template>
-<div class="post" :class="{ repost: isRepost }">
+<div class="note" :class="{ renote: isRenote }">
<div class="reply-to" v-if="p.reply">
- <x-sub :post="p.reply"/>
+ <x-sub :note="p.reply"/>
</div>
- <div class="repost" v-if="isRepost">
+ <div class="renote" v-if="isRenote">
<p>
<router-link class="avatar-anchor" :to="`/@${acct}`">
- <img class="avatar" :src="`${post.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
+ <img class="avatar" :src="`${note.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
</router-link>
%fa:retweet%
- <span>{{ '%i18n:mobile.tags.mk-timeline-post.reposted-by%'.substr(0, '%i18n:mobile.tags.mk-timeline-post.reposted-by%'.indexOf('{')) }}</span>
+ <span>{{ '%i18n:mobile.tags.mk-timeline-note.reposted-by%'.substr(0, '%i18n:mobile.tags.mk-timeline-note.reposted-by%'.indexOf('{')) }}</span>
<router-link class="name" :to="`/@${acct}`">{{ name }}</router-link>
- <span>{{ '%i18n:mobile.tags.mk-timeline-post.reposted-by%'.substr('%i18n:mobile.tags.mk-timeline-post.reposted-by%'.indexOf('}') + 1) }}</span>
+ <span>{{ '%i18n:mobile.tags.mk-timeline-note.reposted-by%'.substr('%i18n:mobile.tags.mk-timeline-note.reposted-by%'.indexOf('}') + 1) }}</span>
</p>
- <mk-time :time="post.createdAt"/>
+ <mk-time :time="note.createdAt"/>
</div>
<article>
<router-link class="avatar-anchor" :to="`/@${pAcct}`">
@@ -37,13 +37,13 @@
<a class="reply" v-if="p.reply">
%fa:reply%
</a>
- <mk-post-html v-if="p.text" :text="p.text" :i="os.i" :class="$style.text"/>
- <a class="rp" v-if="p.repost != null">RP:</a>
+ <mk-note-html v-if="p.text" :text="p.text" :i="os.i" :class="$style.text"/>
+ <a class="rp" v-if="p.renote != null">RP:</a>
</div>
<div class="media" v-if="p.media.length > 0">
<mk-media-list :media-list="p.media"/>
</div>
- <mk-poll v-if="p.poll" :post="p" ref="pollViewer"/>
+ <mk-poll v-if="p.poll" :note="p" ref="pollViewer"/>
<div class="tags" v-if="p.tags && p.tags.length > 0">
<router-link v-for="tag in p.tags" :key="tag" :to="`/search?q=#${tag}`">{{ tag }}</router-link>
</div>
@@ -51,17 +51,17 @@
<a class="location" v-if="p.geo" :href="`http://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% 位置情報</a>
<div class="map" v-if="p.geo" ref="map"></div>
<span class="app" v-if="p.app">via <b>{{ p.app.name }}</b></span>
- <div class="repost" v-if="p.repost">
- <mk-post-preview :post="p.repost"/>
+ <div class="renote" v-if="p.renote">
+ <mk-note-preview :note="p.renote"/>
</div>
</div>
<footer>
- <mk-reactions-viewer :post="p" ref="reactionsViewer"/>
+ <mk-reactions-viewer :note="p" ref="reactionsViewer"/>
<button @click="reply">
%fa:reply%<p class="count" v-if="p.repliesCount > 0">{{ p.repliesCount }}</p>
</button>
- <button @click="repost" title="Repost">
- %fa:retweet%<p class="count" v-if="p.repostCount > 0">{{ p.repostCount }}</p>
+ <button @click="renote" title="Renote">
+ %fa:retweet%<p class="count" v-if="p.renoteCount > 0">{{ p.renoteCount }}</p>
</button>
<button :class="{ reacted: p.myReaction != null }" @click="react" ref="reactButton">
%fa:plus%<p class="count" v-if="p.reactions_count > 0">{{ p.reactions_count }}</p>
@@ -81,16 +81,16 @@ import getAcct from '../../../../../acct/render';
import getUserName from '../../../../../renderers/get-user-name';
import parse from '../../../../../text/parse';
-import MkPostMenu from '../../../common/views/components/post-menu.vue';
+import MkNoteMenu from '../../../common/views/components/note-menu.vue';
import MkReactionPicker from '../../../common/views/components/reaction-picker.vue';
-import XSub from './post.sub.vue';
+import XSub from './note.sub.vue';
export default Vue.extend({
components: {
XSub
},
- props: ['post'],
+ props: ['note'],
data() {
return {
@@ -101,10 +101,10 @@ export default Vue.extend({
computed: {
acct(): string {
- return getAcct(this.post.user);
+ return getAcct(this.note.user);
},
name(): string {
- return getUserName(this.post.user);
+ return getUserName(this.note.user);
},
pAcct(): string {
return getAcct(this.p.user);
@@ -112,14 +112,14 @@ export default Vue.extend({
pName(): string {
return getUserName(this.p.user);
},
- isRepost(): boolean {
- return (this.post.repost &&
- this.post.text == null &&
- this.post.mediaIds == null &&
- this.post.poll == null);
+ isRenote(): boolean {
+ return (this.note.renote &&
+ this.note.text == null &&
+ this.note.mediaIds == null &&
+ this.note.poll == null);
},
p(): any {
- return this.isRepost ? this.post.repost : this.post;
+ return this.isRenote ? this.note.renote : this.note;
},
reactionsCount(): number {
return this.p.reactionCounts
@@ -192,7 +192,7 @@ export default Vue.extend({
type: 'capture',
id: this.p.id
});
- if (withHandler) this.connection.on('post-updated', this.onStreamPostUpdated);
+ if (withHandler) this.connection.on('note-updated', this.onStreamNoteUpdated);
}
},
decapture(withHandler = false) {
@@ -201,18 +201,18 @@ export default Vue.extend({
type: 'decapture',
id: this.p.id
});
- if (withHandler) this.connection.off('post-updated', this.onStreamPostUpdated);
+ if (withHandler) this.connection.off('note-updated', this.onStreamNoteUpdated);
}
},
onStreamConnected() {
this.capture();
},
- onStreamPostUpdated(data) {
- const post = data.post;
- if (post.id == this.post.id) {
- this.$emit('update:post', post);
- } else if (post.id == this.post.repostId) {
- this.post.repost = post;
+ onStreamNoteUpdated(data) {
+ const note = data.note;
+ if (note.id == this.note.id) {
+ this.$emit('update:note', note);
+ } else if (note.id == this.note.renoteId) {
+ this.note.renote = note;
}
},
reply() {
@@ -220,22 +220,22 @@ export default Vue.extend({
reply: this.p
});
},
- repost() {
+ renote() {
(this as any).apis.post({
- repost: this.p
+ renote: this.p
});
},
react() {
(this as any).os.new(MkReactionPicker, {
source: this.$refs.reactButton,
- post: this.p,
+ note: this.p,
compact: true
});
},
menu() {
- (this as any).os.new(MkPostMenu, {
+ (this as any).os.new(MkNoteMenu, {
source: this.$refs.menuButton,
- post: this.p,
+ note: this.p,
compact: true
});
}
@@ -246,14 +246,14 @@ export default Vue.extend({
<style lang="stylus" scoped>
@import '~const.styl'
-.post
+.note
font-size 12px
border-bottom solid 1px #eaeaea
&:first-child
border-radius 8px 8px 0 0
- > .repost
+ > .renote
border-radius 8px 8px 0 0
&:last-of-type
@@ -265,7 +265,7 @@ export default Vue.extend({
@media (min-width 500px)
font-size 16px
- > .repost
+ > .renote
color #9dbb00
background linear-gradient(to bottom, #edfde2 0%, #fff 100%)
@@ -309,7 +309,7 @@ export default Vue.extend({
> .reply-to
background rgba(0, 0, 0, 0.0125)
- > .mk-post-preview
+ > .mk-note-preview
background transparent
> article
@@ -485,10 +485,10 @@ export default Vue.extend({
> .mk-poll
font-size 80%
- > .repost
+ > .renote
margin 8px 0
- > .mk-post-preview
+ > .mk-note-preview
padding 16px
border dashed 1px #c0dac6
border-radius 8px
diff --git a/src/client/app/mobile/views/components/sub-note-content.vue b/src/client/app/mobile/views/components/sub-note-content.vue
new file mode 100644
index 0000000000..22e6ebe3f1
--- /dev/null
+++ b/src/client/app/mobile/views/components/sub-note-content.vue
@@ -0,0 +1,43 @@
+<template>
+<div class="mk-sub-note-content">
+ <div class="body">
+ <a class="reply" v-if="note.replyId">%fa:reply%</a>
+ <mk-note-html v-if="note.text" :text="note.text" :i="os.i"/>
+ <a class="rp" v-if="note.renoteId">RP: ...</a>
+ </div>
+ <details v-if="note.media.length > 0">
+ <summary>({{ note.media.length }}個のメディア)</summary>
+ <mk-media-list :media-list="note.media"/>
+ </details>
+ <details v-if="note.poll">
+ <summary>%i18n:mobile.tags.mk-sub-note-content.poll%</summary>
+ <mk-poll :note="note"/>
+ </details>
+</div>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+export default Vue.extend({
+ props: ['note']
+});
+</script>
+
+<style lang="stylus" scoped>
+.mk-sub-note-content
+ overflow-wrap break-word
+
+ > .body
+ > .reply
+ margin-right 6px
+ color #717171
+
+ > .rp
+ margin-left 4px
+ font-style oblique
+ color #a0bf46
+
+ mk-poll
+ font-size 80%
+
+</style>
diff --git a/src/client/app/mobile/views/components/sub-post-content.vue b/src/client/app/mobile/views/components/sub-post-content.vue
deleted file mode 100644
index 97dd987dd7..0000000000
--- a/src/client/app/mobile/views/components/sub-post-content.vue
+++ /dev/null
@@ -1,43 +0,0 @@
-<template>
-<div class="mk-sub-post-content">
- <div class="body">
- <a class="reply" v-if="post.replyId">%fa:reply%</a>
- <mk-post-html v-if="post.text" :text="post.text" :i="os.i"/>
- <a class="rp" v-if="post.repostId">RP: ...</a>
- </div>
- <details v-if="post.media.length > 0">
- <summary>({{ post.media.length }}個のメディア)</summary>
- <mk-media-list :media-list="post.media"/>
- </details>
- <details v-if="post.poll">
- <summary>%i18n:mobile.tags.mk-sub-post-content.poll%</summary>
- <mk-poll :post="post"/>
- </details>
-</div>
-</template>
-
-<script lang="ts">
-import Vue from 'vue';
-export default Vue.extend({
- props: ['post']
-});
-</script>
-
-<style lang="stylus" scoped>
-.mk-sub-post-content
- overflow-wrap break-word
-
- > .body
- > .reply
- margin-right 6px
- color #717171
-
- > .rp
- margin-left 4px
- font-style oblique
- color #a0bf46
-
- mk-poll
- font-size 80%
-
-</style>
diff --git a/src/client/app/mobile/views/components/timeline.vue b/src/client/app/mobile/views/components/timeline.vue
index 7b5948faf1..4d6abcd167 100644
--- a/src/client/app/mobile/views/components/timeline.vue
+++ b/src/client/app/mobile/views/components/timeline.vue
@@ -1,11 +1,11 @@
<template>
<div class="mk-timeline">
<mk-friends-maker v-if="alone"/>
- <mk-posts :posts="posts">
+ <mk-notes :notes="notes">
<div class="init" v-if="fetching">
%fa:spinner .pulse%%i18n:common.loading%
</div>
- <div class="empty" v-if="!fetching && posts.length == 0">
+ <div class="empty" v-if="!fetching && notes.length == 0">
%fa:R comments%
%i18n:mobile.tags.mk-home-timeline.empty-timeline%
</div>
@@ -13,7 +13,7 @@
<span v-if="!moreFetching">%i18n:mobile.tags.mk-timeline.load-more%</span>
<span v-if="moreFetching">%i18n:common.loading%<mk-ellipsis/></span>
</button>
- </mk-posts>
+ </mk-notes>
</div>
</template>
@@ -33,7 +33,7 @@ export default Vue.extend({
return {
fetching: true,
moreFetching: false,
- posts: [],
+ notes: [],
existMore: false,
connection: null,
connectionId: null
@@ -48,14 +48,14 @@ export default Vue.extend({
this.connection = (this as any).os.stream.getConnection();
this.connectionId = (this as any).os.stream.use();
- this.connection.on('post', this.onPost);
+ this.connection.on('note', this.onNote);
this.connection.on('follow', this.onChangeFollowing);
this.connection.on('unfollow', this.onChangeFollowing);
this.fetch();
},
beforeDestroy() {
- this.connection.off('post', this.onPost);
+ this.connection.off('note', this.onNote);
this.connection.off('follow', this.onChangeFollowing);
this.connection.off('unfollow', this.onChangeFollowing);
(this as any).os.stream.dispose(this.connectionId);
@@ -63,15 +63,15 @@ export default Vue.extend({
methods: {
fetch(cb?) {
this.fetching = true;
- (this as any).api('posts/timeline', {
+ (this as any).api('notes/timeline', {
limit: limit + 1,
untilDate: this.date ? (this.date as any).getTime() : undefined
- }).then(posts => {
- if (posts.length == limit + 1) {
- posts.pop();
+ }).then(notes => {
+ if (notes.length == limit + 1) {
+ notes.pop();
this.existMore = true;
}
- this.posts = posts;
+ this.notes = notes;
this.fetching = false;
this.$emit('loaded');
if (cb) cb();
@@ -79,22 +79,22 @@ export default Vue.extend({
},
more() {
this.moreFetching = true;
- (this as any).api('posts/timeline', {
+ (this as any).api('notes/timeline', {
limit: limit + 1,
- untilId: this.posts[this.posts.length - 1].id
- }).then(posts => {
- if (posts.length == limit + 1) {
- posts.pop();
+ untilId: this.notes[this.notes.length - 1].id
+ }).then(notes => {
+ if (notes.length == limit + 1) {
+ notes.pop();
this.existMore = true;
} else {
this.existMore = false;
}
- this.posts = this.posts.concat(posts);
+ this.notes = this.notes.concat(notes);
this.moreFetching = false;
});
},
- onPost(post) {
- this.posts.unshift(post);
+ onNote(note) {
+ this.notes.unshift(note);
},
onChangeFollowing() {
this.fetch();
diff --git a/src/client/app/mobile/views/components/user-timeline.vue b/src/client/app/mobile/views/components/user-timeline.vue
index bd3e3d0c87..7a04441f76 100644
--- a/src/client/app/mobile/views/components/user-timeline.vue
+++ b/src/client/app/mobile/views/components/user-timeline.vue
@@ -1,18 +1,18 @@
<template>
<div class="mk-user-timeline">
- <mk-posts :posts="posts">
+ <mk-notes :notes="notes">
<div class="init" v-if="fetching">
%fa:spinner .pulse%%i18n:common.loading%
</div>
- <div class="empty" v-if="!fetching && posts.length == 0">
+ <div class="empty" v-if="!fetching && notes.length == 0">
%fa:R comments%
- {{ withMedia ? '%i18n:mobile.tags.mk-user-timeline.no-posts-with-media%' : '%i18n:mobile.tags.mk-user-timeline.no-posts%' }}
+ {{ withMedia ? '%i18n:mobile.tags.mk-user-timeline.no-notes-with-media%' : '%i18n:mobile.tags.mk-user-timeline.no-notes%' }}
</div>
<button v-if="!fetching && existMore" @click="more" :disabled="moreFetching" slot="tail">
<span v-if="!moreFetching">%i18n:mobile.tags.mk-user-timeline.load-more%</span>
<span v-if="moreFetching">%i18n:common.loading%<mk-ellipsis/></span>
</button>
- </mk-posts>
+ </mk-notes>
</div>
</template>
@@ -26,22 +26,22 @@ export default Vue.extend({
data() {
return {
fetching: true,
- posts: [],
+ notes: [],
existMore: false,
moreFetching: false
};
},
mounted() {
- (this as any).api('users/posts', {
+ (this as any).api('users/notes', {
userId: this.user.id,
withMedia: this.withMedia,
limit: limit + 1
- }).then(posts => {
- if (posts.length == limit + 1) {
- posts.pop();
+ }).then(notes => {
+ if (notes.length == limit + 1) {
+ notes.pop();
this.existMore = true;
}
- this.posts = posts;
+ this.notes = notes;
this.fetching = false;
this.$emit('loaded');
});
@@ -49,19 +49,19 @@ export default Vue.extend({
methods: {
more() {
this.moreFetching = true;
- (this as any).api('users/posts', {
+ (this as any).api('users/notes', {
userId: this.user.id,
withMedia: this.withMedia,
limit: limit + 1,
- untilId: this.posts[this.posts.length - 1].id
- }).then(posts => {
- if (posts.length == limit + 1) {
- posts.pop();
+ untilId: this.notes[this.notes.length - 1].id
+ }).then(notes => {
+ if (notes.length == limit + 1) {
+ notes.pop();
this.existMore = true;
} else {
this.existMore = false;
}
- this.posts = this.posts.concat(posts);
+ this.notes = this.notes.concat(notes);
this.moreFetching = false;
});
}
diff --git a/src/client/app/mobile/views/pages/home.vue b/src/client/app/mobile/views/pages/home.vue
index 6fb1c6d4fa..ab61166cf3 100644
--- a/src/client/app/mobile/views/pages/home.vue
+++ b/src/client/app/mobile/views/pages/home.vue
@@ -64,7 +64,7 @@ import Vue from 'vue';
import * as XDraggable from 'vuedraggable';
import * as uuid from 'uuid';
import Progress from '../../../common/scripts/loading';
-import getPostSummary from '../../../../../renderers/get-post-summary';
+import getNoteSummary from '../../../../../renderers/get-note-summary';
export default Vue.extend({
components: {
@@ -124,14 +124,14 @@ export default Vue.extend({
this.connection = (this as any).os.stream.getConnection();
this.connectionId = (this as any).os.stream.use();
- this.connection.on('post', this.onStreamPost);
+ this.connection.on('note', this.onStreamNote);
this.connection.on('mobile_home_updated', this.onHomeUpdated);
document.addEventListener('visibilitychange', this.onVisibilitychange, false);
Progress.start();
},
beforeDestroy() {
- this.connection.off('post', this.onStreamPost);
+ this.connection.off('note', this.onStreamNote);
this.connection.off('mobile_home_updated', this.onHomeUpdated);
(this as any).os.stream.dispose(this.connectionId);
document.removeEventListener('visibilitychange', this.onVisibilitychange);
@@ -143,10 +143,10 @@ export default Vue.extend({
onLoaded() {
Progress.done();
},
- onStreamPost(post) {
- if (document.hidden && post.userId !== (this as any).os.i.id) {
+ onStreamNote(note) {
+ if (document.hidden && note.userId !== (this as any).os.i.id) {
this.unreadCount++;
- document.title = `(${this.unreadCount}) ${getPostSummary(post)}`;
+ document.title = `(${this.unreadCount}) ${getNoteSummary(note)}`;
}
},
onVisibilitychange() {
diff --git a/src/client/app/mobile/views/pages/post.vue b/src/client/app/mobile/views/pages/note.vue
index 49a4bfd9dc..89b8c776f2 100644
--- a/src/client/app/mobile/views/pages/post.vue
+++ b/src/client/app/mobile/views/pages/note.vue
@@ -1,12 +1,12 @@
<template>
<mk-ui>
- <span slot="header">%fa:R sticky-note%%i18n:mobile.tags.mk-post-page.title%</span>
+ <span slot="header">%fa:R sticky-note%%i18n:mobile.tags.mk-note-page.title%</span>
<main v-if="!fetching">
- <a v-if="post.next" :href="post.next">%fa:angle-up%%i18n:mobile.tags.mk-post-page.next%</a>
+ <a v-if="note.next" :href="note.next">%fa:angle-up%%i18n:mobile.tags.mk-note-page.next%</a>
<div>
- <mk-post-detail :post="post"/>
+ <mk-note-detail :note="note"/>
</div>
- <a v-if="post.prev" :href="post.prev">%fa:angle-down%%i18n:mobile.tags.mk-post-page.prev%</a>
+ <a v-if="note.prev" :href="note.prev">%fa:angle-down%%i18n:mobile.tags.mk-note-page.prev%</a>
</main>
</mk-ui>
</template>
@@ -19,7 +19,7 @@ export default Vue.extend({
data() {
return {
fetching: true,
- post: null
+ note: null
};
},
watch: {
@@ -37,10 +37,10 @@ export default Vue.extend({
Progress.start();
this.fetching = true;
- (this as any).api('posts/show', {
- postId: this.$route.params.post
- }).then(post => {
- this.post = post;
+ (this as any).api('notes/show', {
+ noteId: this.$route.params.note
+ }).then(note => {
+ this.note = note;
this.fetching = false;
Progress.done();
diff --git a/src/client/app/mobile/views/pages/search.vue b/src/client/app/mobile/views/pages/search.vue
index cbab504e3c..a96832beec 100644
--- a/src/client/app/mobile/views/pages/search.vue
+++ b/src/client/app/mobile/views/pages/search.vue
@@ -2,13 +2,13 @@
<mk-ui>
<span slot="header">%fa:search% {{ q }}</span>
<main v-if="!fetching">
- <mk-posts :class="$style.posts" :posts="posts">
- <span v-if="posts.length == 0">{{ '%i18n:mobile.tags.mk-search-posts.empty%'.replace('{}', q) }}</span>
+ <mk-notes :class="$style.notes" :notes="notes">
+ <span v-if="notes.length == 0">{{ '%i18n:mobile.tags.mk-search-notes.empty%'.replace('{}', q) }}</span>
<button v-if="existMore" @click="more" :disabled="fetching" slot="tail">
<span v-if="!fetching">%i18n:mobile.tags.mk-timeline.load-more%</span>
<span v-if="fetching">%i18n:common.loading%<mk-ellipsis/></span>
</button>
- </mk-posts>
+ </mk-notes>
</main>
</mk-ui>
</template>
@@ -25,7 +25,7 @@ export default Vue.extend({
return {
fetching: true,
existMore: false,
- posts: [],
+ notes: [],
offset: 0
};
},
@@ -48,30 +48,30 @@ export default Vue.extend({
this.fetching = true;
Progress.start();
- (this as any).api('posts/search', Object.assign({
+ (this as any).api('notes/search', Object.assign({
limit: limit + 1
- }, parse(this.q))).then(posts => {
- if (posts.length == limit + 1) {
- posts.pop();
+ }, parse(this.q))).then(notes => {
+ if (notes.length == limit + 1) {
+ notes.pop();
this.existMore = true;
}
- this.posts = posts;
+ this.notes = notes;
this.fetching = false;
Progress.done();
});
},
more() {
this.offset += limit;
- (this as any).api('posts/search', Object.assign({
+ (this as any).api('notes/search', Object.assign({
limit: limit + 1,
offset: this.offset
- }, parse(this.q))).then(posts => {
- if (posts.length == limit + 1) {
- posts.pop();
+ }, parse(this.q))).then(notes => {
+ if (notes.length == limit + 1) {
+ notes.pop();
} else {
this.existMore = false;
}
- this.posts = this.posts.concat(posts);
+ this.notes = this.notes.concat(notes);
});
}
}
@@ -79,7 +79,7 @@ export default Vue.extend({
</script>
<style lang="stylus" module>
-.posts
+.notes
margin 8px auto
max-width 500px
width calc(100% - 16px)
diff --git a/src/client/app/mobile/views/pages/user.vue b/src/client/app/mobile/views/pages/user.vue
index 3b7b4d6c28..08fa4e2774 100644
--- a/src/client/app/mobile/views/pages/user.vue
+++ b/src/client/app/mobile/views/pages/user.vue
@@ -27,8 +27,8 @@
</div>
<div class="status">
<a>
- <b>{{ user.postsCount | number }}</b>
- <i>%i18n:mobile.tags.mk-user.posts%</i>
+ <b>{{ user.notesCount | number }}</b>
+ <i>%i18n:mobile.tags.mk-user.notes%</i>
</a>
<a :href="`@${acct}/following`">
<b>{{ user.followingCount | number }}</b>
@@ -44,13 +44,13 @@
<nav>
<div class="nav-container">
<a :data-is-active=" page == 'home' " @click="page = 'home'">%i18n:mobile.tags.mk-user.overview%</a>
- <a :data-is-active=" page == 'posts' " @click="page = 'posts'">%i18n:mobile.tags.mk-user.timeline%</a>
+ <a :data-is-active=" page == 'notes' " @click="page = 'notes'">%i18n:mobile.tags.mk-user.timeline%</a>
<a :data-is-active=" page == 'media' " @click="page = 'media'">%i18n:mobile.tags.mk-user.media%</a>
</div>
</nav>
<div class="body">
<x-home v-if="page == 'home'" :user="user"/>
- <mk-user-timeline v-if="page == 'posts'" :user="user"/>
+ <mk-user-timeline v-if="page == 'notes'" :user="user"/>
<mk-user-timeline v-if="page == 'media'" :user="user" with-media/>
</div>
</main>
diff --git a/src/client/app/mobile/views/pages/user/home.posts.vue b/src/client/app/mobile/views/pages/user/home.notes.vue
index 654f7f63e0..02afed9b88 100644
--- a/src/client/app/mobile/views/pages/user/home.posts.vue
+++ b/src/client/app/mobile/views/pages/user/home.notes.vue
@@ -1,10 +1,10 @@
<template>
-<div class="root posts">
- <p class="fetching" v-if="fetching">%fa:spinner .pulse .fw%%i18n:mobile.tags.mk-user-overview-posts.loading%<mk-ellipsis/></p>
- <div v-if="!fetching && posts.length > 0">
- <mk-post-card v-for="post in posts" :key="post.id" :post="post"/>
+<div class="root notes">
+ <p class="fetching" v-if="fetching">%fa:spinner .pulse .fw%%i18n:mobile.tags.mk-user-overview-notes.loading%<mk-ellipsis/></p>
+ <div v-if="!fetching && notes.length > 0">
+ <mk-note-card v-for="note in notes" :key="note.id" :note="note"/>
</div>
- <p class="empty" v-if="!fetching && posts.length == 0">%i18n:mobile.tags.mk-user-overview-posts.no-posts%</p>
+ <p class="empty" v-if="!fetching && notes.length == 0">%i18n:mobile.tags.mk-user-overview-notes.no-notes%</p>
</div>
</template>
@@ -15,14 +15,14 @@ export default Vue.extend({
data() {
return {
fetching: true,
- posts: []
+ notes: []
};
},
mounted() {
- (this as any).api('users/posts', {
+ (this as any).api('users/notes', {
userId: this.user.id
- }).then(posts => {
- this.posts = posts;
+ }).then(notes => {
+ this.notes = notes;
this.fetching = false;
});
}
@@ -30,7 +30,7 @@ export default Vue.extend({
</script>
<style lang="stylus" scoped>
-.root.posts
+.root.notes
> div
overflow-x scroll
diff --git a/src/client/app/mobile/views/pages/user/home.photos.vue b/src/client/app/mobile/views/pages/user/home.photos.vue
index ecf5082072..1c59260812 100644
--- a/src/client/app/mobile/views/pages/user/home.photos.vue
+++ b/src/client/app/mobile/views/pages/user/home.photos.vue
@@ -5,7 +5,7 @@
<a v-for="image in images"
class="img"
:style="`background-image: url(${image.media.url}?thumbnail&size=256)`"
- :href="`/@${getAcct(image.post.user)}/${image.post.id}`"
+ :href="`/@${getAcct(image.note.user)}/${image.note.id}`"
></a>
</div>
<p class="empty" v-if="!fetching && images.length == 0">%i18n:mobile.tags.mk-user-overview-photos.no-photos%</p>
@@ -28,15 +28,15 @@ export default Vue.extend({
getAcct
},
mounted() {
- (this as any).api('users/posts', {
+ (this as any).api('users/notes', {
userId: this.user.id,
withMedia: true,
limit: 6
- }).then(posts => {
- posts.forEach(post => {
- post.media.forEach(media => {
+ }).then(notes => {
+ notes.forEach(note => {
+ note.media.forEach(media => {
if (this.images.length < 9) this.images.push({
- post,
+ note,
media
});
});
diff --git a/src/client/app/mobile/views/pages/user/home.vue b/src/client/app/mobile/views/pages/user/home.vue
index 1afcd1f5ba..2554084969 100644
--- a/src/client/app/mobile/views/pages/user/home.vue
+++ b/src/client/app/mobile/views/pages/user/home.vue
@@ -1,10 +1,10 @@
<template>
<div class="root home">
- <mk-post-detail v-if="user.pinnedPost" :post="user.pinnedPost" :compact="true"/>
- <section class="recent-posts">
- <h2>%fa:R comments%%i18n:mobile.tags.mk-user-overview.recent-posts%</h2>
+ <mk-note-detail v-if="user.pinnedNote" :note="user.pinnedNote" :compact="true"/>
+ <section class="recent-notes">
+ <h2>%fa:R comments%%i18n:mobile.tags.mk-user-overview.recent-notes%</h2>
<div>
- <x-posts :user="user"/>
+ <x-notes :user="user"/>
</div>
</section>
<section class="images">
@@ -37,14 +37,14 @@
<script lang="ts">
import Vue from 'vue';
-import XPosts from './home.posts.vue';
+import XNotes from './home.notes.vue';
import XPhotos from './home.photos.vue';
import XFriends from './home.friends.vue';
import XFollowersYouKnow from './home.followers-you-know.vue';
export default Vue.extend({
components: {
- XPosts,
+ XNotes,
XPhotos,
XFriends,
XFollowersYouKnow
@@ -58,7 +58,7 @@ export default Vue.extend({
max-width 600px
margin 0 auto
- > .mk-post-detail
+ > .mk-note-detail
margin 0 0 8px 0
> section
diff --git a/src/client/app/stats/tags/index.tag b/src/client/app/stats/tags/index.tag
index 63fdd24044..f8944c0832 100644
--- a/src/client/app/stats/tags/index.tag
+++ b/src/client/app/stats/tags/index.tag
@@ -2,7 +2,7 @@
<h1>Misskey<i>Statistics</i></h1>
<main v-if="!initializing">
<mk-users stats={ stats }/>
- <mk-posts stats={ stats }/>
+ <mk-notes stats={ stats }/>
</main>
<footer><a href={ _URL_ }>{ _HOST_ }</a></footer>
<style lang="stylus" scoped>
@@ -56,9 +56,9 @@
</script>
</mk-index>
-<mk-posts>
- <h2>%i18n:stats.posts-count% <b>{ stats.postsCount }</b></h2>
- <mk-posts-chart v-if="!initializing" data={ data }/>
+<mk-notes>
+ <h2>%i18n:stats.notes-count% <b>{ stats.notesCount }</b></h2>
+ <mk-notes-chart v-if="!initializing" data={ data }/>
<style lang="stylus" scoped>
:scope
display block
@@ -70,7 +70,7 @@
this.stats = this.opts.stats;
this.on('mount', () => {
- this.$root.$data.os.api('aggregation/posts', {
+ this.$root.$data.os.api('aggregation/notes', {
limit: 365
}).then(data => {
this.update({
@@ -80,7 +80,7 @@
});
});
</script>
-</mk-posts>
+</mk-notes>
<mk-users>
<h2>%i18n:stats.users-count% <b>{ stats.usersCount }</b></h2>
@@ -108,11 +108,11 @@
</script>
</mk-users>
-<mk-posts-chart>
+<mk-notes-chart>
<svg riot-viewBox="0 0 { viewBoxX } { viewBoxY }" preserveAspectRatio="none">
- <title>Black ... Total<br/>Blue ... Posts<br/>Red ... Replies<br/>Green ... Reposts</title>
+ <title>Black ... Total<br/>Blue ... Notes<br/>Red ... Replies<br/>Green ... Renotes</title>
<polyline
- riot-points={ pointsPost }
+ riot-points={ pointsNote }
fill="none"
stroke-width="1"
stroke="#41ddde"/>
@@ -122,7 +122,7 @@
stroke-width="1"
stroke="#f7796c"/>
<polyline
- riot-points={ pointsRepost }
+ riot-points={ pointsRenote }
fill="none"
stroke-width="1"
stroke="#a1de41"/>
@@ -147,7 +147,7 @@
this.viewBoxY = 80;
this.data = this.opts.data.reverse();
- this.data.forEach(d => d.total = d.posts + d.replies + d.reposts);
+ this.data.forEach(d => d.total = d.notes + d.replies + d.renotes);
const peak = Math.max.apply(null, this.data.map(d => d.total));
this.on('mount', () => {
@@ -156,14 +156,14 @@
this.render = () => {
this.update({
- pointsPost: this.data.map((d, i) => `${i},${(1 - (d.posts / peak)) * this.viewBoxY}`).join(' '),
+ pointsNote: this.data.map((d, i) => `${i},${(1 - (d.notes / peak)) * this.viewBoxY}`).join(' '),
pointsReply: this.data.map((d, i) => `${i},${(1 - (d.replies / peak)) * this.viewBoxY}`).join(' '),
- pointsRepost: this.data.map((d, i) => `${i},${(1 - (d.reposts / peak)) * this.viewBoxY}`).join(' '),
+ pointsRenote: this.data.map((d, i) => `${i},${(1 - (d.renotes / peak)) * this.viewBoxY}`).join(' '),
pointsTotal: this.data.map((d, i) => `${i},${(1 - (d.total / peak)) * this.viewBoxY}`).join(' ')
});
};
</script>
-</mk-posts-chart>
+</mk-notes-chart>
<mk-users-chart>
<svg riot-viewBox="0 0 { viewBoxX } { viewBoxY }" preserveAspectRatio="none">
diff --git a/src/client/docs/api/endpoints/posts/create.yaml b/src/client/docs/api/endpoints/notes/create.yaml
index d2d6e27fc7..04ada2ecd5 100644
--- a/src/client/docs/api/endpoints/posts/create.yaml
+++ b/src/client/docs/api/endpoints/notes/create.yaml
@@ -1,8 +1,8 @@
-endpoint: "posts/create"
+endpoint: "notes/create"
desc:
ja: "投稿します。"
- en: "Compose new post."
+ en: "Compose new note."
params:
- name: "text"
@@ -10,7 +10,7 @@ params:
optional: true
desc:
ja: "投稿の本文"
- en: "The text of your post"
+ en: "The text of your note"
- name: "cw"
type: "string"
optional: true
@@ -24,17 +24,17 @@ params:
ja: "添付するメディア(1~4つ)"
en: "Media you want to attach (1~4)"
- name: "replyId"
- type: "id(Post)"
+ type: "id(Note)"
optional: true
desc:
ja: "返信する投稿"
- en: "The post you want to reply"
- - name: "repostId"
- type: "id(Post)"
+ en: "The note you want to reply"
+ - name: "renoteId"
+ type: "id(Note)"
optional: true
desc:
ja: "引用する投稿"
- en: "The post you want to quote"
+ en: "The note you want to quote"
- name: "poll"
type: "object"
optional: true
@@ -51,9 +51,9 @@ params:
en: "Choices of a poll"
res:
- - name: "createdPost"
- type: "entity(Post)"
+ - name: "createdNote"
+ type: "entity(Note)"
optional: false
desc:
ja: "作成した投稿"
- en: "A post that created"
+ en: "A note that created"
diff --git a/src/client/docs/api/endpoints/posts/timeline.yaml b/src/client/docs/api/endpoints/notes/timeline.yaml
index 9c44dd736a..71c346f355 100644
--- a/src/client/docs/api/endpoints/posts/timeline.yaml
+++ b/src/client/docs/api/endpoints/notes/timeline.yaml
@@ -1,4 +1,4 @@
-endpoint: "posts/timeline"
+endpoint: "notes/timeline"
desc:
ja: "タイムラインを取得します。"
@@ -11,12 +11,12 @@ params:
desc:
ja: "取得する最大の数"
- name: "sinceId"
- type: "id(Post)"
+ type: "id(Note)"
optional: true
desc:
ja: "指定すると、この投稿を基点としてより新しい投稿を取得します"
- name: "untilId"
- type: "id(Post)"
+ type: "id(Note)"
optional: true
desc:
ja: "指定すると、この投稿を基点としてより古い投稿を取得します"
diff --git a/src/client/docs/api/entities/note.yaml b/src/client/docs/api/entities/note.yaml
new file mode 100644
index 0000000000..718d331d13
--- /dev/null
+++ b/src/client/docs/api/entities/note.yaml
@@ -0,0 +1,174 @@
+name: "Note"
+
+desc:
+ ja: "投稿。"
+ en: "A note."
+
+props:
+ - name: "id"
+ type: "id"
+ optional: false
+ desc:
+ ja: "投稿ID"
+ en: "The ID of this note"
+ - name: "createdAt"
+ type: "date"
+ optional: false
+ desc:
+ ja: "投稿日時"
+ en: "The posted date of this note"
+ - name: "viaMobile"
+ type: "boolean"
+ optional: true
+ desc:
+ ja: "モバイル端末から投稿したか否か(自己申告であることに留意)"
+ en: "Whether this note sent via a mobile device"
+ - name: "text"
+ type: "string"
+ optional: true
+ desc:
+ ja: "投稿の本文 (ローカルの場合Markdown風のフォーマット)"
+ en: "The text of this note (in Markdown like format if local)"
+ - name: "textHtml"
+ type: "string"
+ optional: true
+ desc:
+ ja: "投稿の本文 (HTML) (投稿時は無視)"
+ en: "The text of this note (in HTML. Ignored when posting.)"
+ - name: "mediaIds"
+ type: "id(DriveFile)[]"
+ optional: true
+ desc:
+ ja: "添付されているメディアのID (なければレスポンスでは空配列)"
+ en: "The IDs of the attached media (empty array for response if no media is attached)"
+ - name: "media"
+ type: "entity(DriveFile)[]"
+ optional: true
+ desc:
+ ja: "添付されているメディア"
+ en: "The attached media"
+ - name: "userId"
+ type: "id(User)"
+ optional: false
+ desc:
+ ja: "投稿者ID"
+ en: "The ID of author of this note"
+ - name: "user"
+ type: "entity(User)"
+ optional: true
+ desc:
+ ja: "投稿者"
+ en: "The author of this note"
+ - name: "myReaction"
+ type: "string"
+ optional: true
+ desc:
+ ja: "この投稿に対する自分の<a href='/docs/api/reactions'>リアクション</a>"
+ en: "The your <a href='/docs/api/reactions'>reaction</a> of this note"
+ - name: "reactionCounts"
+ type: "object"
+ optional: false
+ desc:
+ ja: "<a href='/docs/api/reactions'>リアクション</a>をキーとし、この投稿に対するそのリアクションの数を値としたオブジェクト"
+ - name: "replyId"
+ type: "id(Note)"
+ optional: true
+ desc:
+ ja: "返信した投稿のID"
+ en: "The ID of the replyed note"
+ - name: "reply"
+ type: "entity(Note)"
+ optional: true
+ desc:
+ ja: "返信した投稿"
+ en: "The replyed note"
+ - name: "renoteId"
+ type: "id(Note)"
+ optional: true
+ desc:
+ ja: "引用した投稿のID"
+ en: "The ID of the quoted note"
+ - name: "renote"
+ type: "entity(Note)"
+ optional: true
+ desc:
+ ja: "引用した投稿"
+ en: "The quoted note"
+ - name: "poll"
+ type: "object"
+ optional: true
+ desc:
+ ja: "投票"
+ en: "The poll"
+ defName: "poll"
+ def:
+ - name: "choices"
+ type: "object[]"
+ optional: false
+ desc:
+ ja: "投票の選択肢"
+ en: "The choices of this poll"
+ defName: "choice"
+ def:
+ - name: "id"
+ type: "number"
+ optional: false
+ desc:
+ ja: "選択肢ID"
+ en: "The ID of this choice"
+ - name: "isVoted"
+ type: "boolean"
+ optional: true
+ desc:
+ ja: "自分がこの選択肢に投票したかどうか"
+ en: "Whether you voted to this choice"
+ - name: "text"
+ type: "string"
+ optional: false
+ desc:
+ ja: "選択肢本文"
+ en: "The text of this choice"
+ - name: "votes"
+ type: "number"
+ optional: false
+ desc:
+ ja: "この選択肢に投票された数"
+ en: "The number voted for this choice"
+ - name: "geo"
+ type: "object"
+ optional: true
+ desc:
+ ja: "位置情報"
+ en: "Geo location"
+ defName: "geo"
+ def:
+ - name: "coordinates"
+ type: "number[]"
+ optional: false
+ desc:
+ ja: "座標。最初に経度:-180〜180で表す。最後に緯度:-90〜90で表す。"
+ - name: "altitude"
+ type: "number"
+ optional: false
+ desc:
+ ja: "高度。メートル単位で表す。"
+ - name: "accuracy"
+ type: "number"
+ optional: false
+ desc:
+ ja: "緯度、経度の精度。メートル単位で表す。"
+ - name: "altitudeAccuracy"
+ type: "number"
+ optional: false
+ desc:
+ ja: "高度の精度。メートル単位で表す。"
+ - name: "heading"
+ type: "number"
+ optional: false
+ desc:
+ ja: "方角。0〜360の角度で表す。0が北、90が東、180が南、270が西。"
+ - name: "speed"
+ type: "number"
+ optional: false
+ desc:
+ ja: "速度。メートル / 秒数で表す。"
diff --git a/src/client/docs/api/entities/post.yaml b/src/client/docs/api/entities/post.yaml
index 7077700129..718d331d13 100644
--- a/src/client/docs/api/entities/post.yaml
+++ b/src/client/docs/api/entities/post.yaml
@@ -1,8 +1,8 @@
-name: "Post"
+name: "Note"
desc:
ja: "投稿。"
- en: "A post."
+ en: "A note."
props:
- name: "id"
@@ -10,31 +10,31 @@ props:
optional: false
desc:
ja: "投稿ID"
- en: "The ID of this post"
+ en: "The ID of this note"
- name: "createdAt"
type: "date"
optional: false
desc:
ja: "投稿日時"
- en: "The posted date of this post"
+ en: "The posted date of this note"
- name: "viaMobile"
type: "boolean"
optional: true
desc:
ja: "モバイル端末から投稿したか否か(自己申告であることに留意)"
- en: "Whether this post sent via a mobile device"
+ en: "Whether this note sent via a mobile device"
- name: "text"
type: "string"
optional: true
desc:
ja: "投稿の本文 (ローカルの場合Markdown風のフォーマット)"
- en: "The text of this post (in Markdown like format if local)"
+ en: "The text of this note (in Markdown like format if local)"
- name: "textHtml"
type: "string"
optional: true
desc:
ja: "投稿の本文 (HTML) (投稿時は無視)"
- en: "The text of this post (in HTML. Ignored when posting.)"
+ en: "The text of this note (in HTML. Ignored when posting.)"
- name: "mediaIds"
type: "id(DriveFile)[]"
optional: true
@@ -52,48 +52,48 @@ props:
optional: false
desc:
ja: "投稿者ID"
- en: "The ID of author of this post"
+ en: "The ID of author of this note"
- name: "user"
type: "entity(User)"
optional: true
desc:
ja: "投稿者"
- en: "The author of this post"
+ en: "The author of this note"
- name: "myReaction"
type: "string"
optional: true
desc:
ja: "この投稿に対する自分の<a href='/docs/api/reactions'>リアクション</a>"
- en: "The your <a href='/docs/api/reactions'>reaction</a> of this post"
+ en: "The your <a href='/docs/api/reactions'>reaction</a> of this note"
- name: "reactionCounts"
type: "object"
optional: false
desc:
ja: "<a href='/docs/api/reactions'>リアクション</a>をキーとし、この投稿に対するそのリアクションの数を値としたオブジェクト"
- name: "replyId"
- type: "id(Post)"
+ type: "id(Note)"
optional: true
desc:
ja: "返信した投稿のID"
- en: "The ID of the replyed post"
+ en: "The ID of the replyed note"
- name: "reply"
- type: "entity(Post)"
+ type: "entity(Note)"
optional: true
desc:
ja: "返信した投稿"
- en: "The replyed post"
- - name: "repostId"
- type: "id(Post)"
+ en: "The replyed note"
+ - name: "renoteId"
+ type: "id(Note)"
optional: true
desc:
ja: "引用した投稿のID"
- en: "The ID of the quoted post"
- - name: "repost"
- type: "entity(Post)"
+ en: "The ID of the quoted note"
+ - name: "renote"
+ type: "entity(Note)"
optional: true
desc:
ja: "引用した投稿"
- en: "The quoted post"
+ en: "The quoted note"
- name: "poll"
type: "object"
optional: true
diff --git a/src/client/docs/api/entities/user.yaml b/src/client/docs/api/entities/user.yaml
index a1fae1482b..cccf42f221 100644
--- a/src/client/docs/api/entities/user.yaml
+++ b/src/client/docs/api/entities/user.yaml
@@ -81,24 +81,24 @@ props:
desc:
ja: "自分がこのユーザーをミュートしているか"
en: "Whether you muted this user"
- - name: "postsCount"
+ - name: "notesCount"
type: "number"
optional: false
desc:
ja: "投稿の数"
- en: "The number of the posts of this user"
- - name: "pinnedPost"
- type: "entity(Post)"
+ en: "The number of the notes of this user"
+ - name: "pinnedNote"
+ type: "entity(Note)"
optional: true
desc:
ja: "ピン留めされた投稿"
- en: "The pinned post of this user"
- - name: "pinnedPostId"
- type: "id(Post)"
+ en: "The pinned note of this user"
+ - name: "pinnedNoteId"
+ type: "id(Note)"
optional: true
desc:
ja: "ピン留めされた投稿のID"
- en: "The ID of the pinned post of this user"
+ en: "The ID of the pinned note of this user"
- name: "driveCapacity"
type: "number"
optional: false
diff --git a/src/client/docs/mute.ja.pug b/src/client/docs/mute.ja.pug
index 5e79af5f8c..807f7b67a7 100644
--- a/src/client/docs/mute.ja.pug
+++ b/src/client/docs/mute.ja.pug
@@ -4,7 +4,7 @@ p ユーザーページから、そのユーザーをミュートすることが
p ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります:
ul
- li タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRepost)
+ li タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote)
li そのユーザーからの通知
li メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴
diff --git a/src/client/docs/search.ja.pug b/src/client/docs/search.ja.pug
index e14e8c867e..fc62d16cae 100644
--- a/src/client/docs/search.ja.pug
+++ b/src/client/docs/search.ja.pug
@@ -64,19 +64,19 @@ section
tr
td mute
td
- | mute_all ... ミュートしているユーザーの投稿とその投稿に対する返信やRepostを除外する(デフォルト)
+ | mute_all ... ミュートしているユーザーの投稿とその投稿に対する返信やRenoteを除外する(デフォルト)
br
- | mute_related ... ミュートしているユーザーの投稿に対する返信やRepostだけ除外する
+ | mute_related ... ミュートしているユーザーの投稿に対する返信やRenoteだけ除外する
br
| mute_direct ... ミュートしているユーザーの投稿だけ除外する
br
- | disabled ... ミュートしているユーザーの投稿とその投稿に対する返信やRepostも含める
+ | disabled ... ミュートしているユーザーの投稿とその投稿に対する返信やRenoteも含める
br
| direct_only ... ミュートしているユーザーの投稿だけに限定
br
- | related_only ... ミュートしているユーザーの投稿に対する返信やRepostだけに限定
+ | related_only ... ミュートしているユーザーの投稿に対する返信やRenoteだけに限定
br
- | all_only ... ミュートしているユーザーの投稿とその投稿に対する返信やRepostに限定
+ | all_only ... ミュートしているユーザーの投稿とその投稿に対する返信やRenoteに限定
tr
td reply
td
@@ -86,11 +86,11 @@ section
br
| null ... 特に限定しない(デフォルト)
tr
- td repost
+ td renote
td
- | true ... Repostに限定。
+ | true ... Renoteに限定。
br
- | false ... Repostでない投稿に限定。
+ | false ... Renoteでない投稿に限定。
br
| null ... 特に限定しない(デフォルト)
tr