diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index 288ffd39f..fd668c03d 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -415,6 +415,7 @@ accountSettings: "アカウント設定"
promotion: "プロモーション"
promote: "プロモート"
numberOfDays: "日数"
+hideThisNote: "このノートを非表示"
_ago:
unknown: "謎"
diff --git a/src/client/components/note.vue b/src/client/components/note.vue
index e6b522d8d..3a02753c6 100644
--- a/src/client/components/note.vue
+++ b/src/client/components/note.vue
@@ -9,8 +9,8 @@
>
-
{{ $t('pinnedNote') }}
- {{ $t('promotion') }}
+ {{ $t('pinnedNote') }}
+ {{ $t('promotion') }}
@@ -264,6 +264,13 @@ export default Vue.extend({
},
methods: {
+ readPromo() {
+ (this as any).$root.api('promo/read', {
+ noteId: this.appearNote.id
+ });
+ this.hideThisNote = true;
+ },
+
capture(withHandler = false) {
if (this.$store.getters.isSignedIn) {
this.connection.send(document.body.contains(this.$el) ? 'sn' : 's', { id: this.appearNote.id });
@@ -744,7 +751,9 @@ export default Vue.extend({
border-radius: 0 0 var(--radius) var(--radius);
}
- > .pinned {
+ > .info {
+ display: flex;
+ align-items: center;
padding: 16px 32px 8px 32px;
line-height: 24px;
font-size: 90%;
@@ -758,9 +767,14 @@ export default Vue.extend({
> [data-icon] {
margin-right: 4px;
}
+
+ > .hide {
+ margin-left: auto;
+ color: inherit;
+ }
}
- > .pinned + .article {
+ > .info + .article {
padding-top: 8px;
}
diff --git a/src/server/api/endpoints/promo/read.ts b/src/server/api/endpoints/promo/read.ts
new file mode 100644
index 000000000..9ce253374
--- /dev/null
+++ b/src/server/api/endpoints/promo/read.ts
@@ -0,0 +1,50 @@
+import $ from 'cafy';
+import { ID } from '../../../../misc/cafy-id';
+import define from '../../define';
+import { ApiError } from '../../error';
+import { getNote } from '../../common/getters';
+import { PromoReads } from '../../../../models';
+import { genId } from '../../../../misc/gen-id';
+
+export const meta = {
+ tags: ['notes'],
+
+ requireCredential: true as const,
+
+ params: {
+ noteId: {
+ validator: $.type(ID),
+ }
+ },
+
+ errors: {
+ noSuchNote: {
+ message: 'No such note.',
+ code: 'NO_SUCH_NOTE',
+ id: 'd785b897-fcd3-4fe9-8fc3-b85c26e6c932'
+ },
+ }
+};
+
+export default define(meta, async (ps, user) => {
+ const note = await getNote(ps.noteId).catch(e => {
+ if (e.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote);
+ throw e;
+ });
+
+ const exist = await PromoReads.findOne({
+ noteId: note.id,
+ userId: user.id
+ });
+
+ if (exist != null) {
+ return;
+ }
+
+ await PromoReads.save({
+ id: genId(),
+ createdAt: new Date(),
+ noteId: note.id,
+ userId: user.id
+ });
+});