diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 5a3f40a6dc..0f786a6b14 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -748,6 +748,13 @@ gallery: "ギャラリー" recentPosts: "最近の投稿" popularPosts: "人気の投稿" shareWithNote: "ノートで共有" +ads: "広告" +expiration: "期限" +memo: "メモ" +priority: "優先度" +high: "高" +middle: "中" +low: "低" emailNotConfiguredWarning: "メールアドレスの設定がされていません。" _forgotPassword: diff --git a/migration/1620019354680-ad.ts b/migration/1620019354680-ad.ts new file mode 100644 index 0000000000..27fb99f181 --- /dev/null +++ b/migration/1620019354680-ad.ts @@ -0,0 +1,18 @@ +import {MigrationInterface, QueryRunner} from "typeorm"; + +export class ad1620019354680 implements MigrationInterface { + name = 'ad1620019354680' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`CREATE TABLE "ad" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "expiresAt" TIMESTAMP WITH TIME ZONE NOT NULL, "place" character varying(32) NOT NULL, "priority" character varying(32) NOT NULL, "url" character varying(1024) NOT NULL, "imageUrl" character varying(1024) NOT NULL, "memo" character varying(8192) NOT NULL, CONSTRAINT "PK_0193d5ef09746e88e9ea92c634d" PRIMARY KEY ("id")); COMMENT ON COLUMN "ad"."createdAt" IS 'The created date of the Ad.'; COMMENT ON COLUMN "ad"."expiresAt" IS 'The expired date of the Ad.'`); + await queryRunner.query(`CREATE INDEX "IDX_1129c2ef687fc272df040bafaa" ON "ad" ("createdAt") `); + await queryRunner.query(`CREATE INDEX "IDX_2da24ce20ad209f1d9dc032457" ON "ad" ("expiresAt") `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP INDEX "IDX_2da24ce20ad209f1d9dc032457"`); + await queryRunner.query(`DROP INDEX "IDX_1129c2ef687fc272df040bafaa"`); + await queryRunner.query(`DROP TABLE "ad"`); + } + +} diff --git a/package.json b/package.json index 25ebacaa7c..9a14373667 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,6 @@ "resolutions": { "chokidar": "^3.3.1", "constantinople": "^4.0.1", - "gulp/gulp-cli/yargs/yargs-parser": "5.0.0-security.0", "jsonld/rdf-canonize/node-forge": "0.10.0", "lodash": "^4.17.20" }, diff --git a/src/client/components/date-separated-list.vue b/src/client/components/date-separated-list.vue index 2a861adb09..d458a0eeb8 100644 --- a/src/client/components/date-separated-list.vue +++ b/src/client/components/date-separated-list.vue @@ -1,5 +1,6 @@ + + diff --git a/src/client/components/index.ts b/src/client/components/index.ts index 0630ed3d8c..8b914c5eec 100644 --- a/src/client/components/index.ts +++ b/src/client/components/index.ts @@ -12,8 +12,10 @@ import url from './global/url.vue'; import i18n from './global/i18n'; import loading from './global/loading.vue'; import error from './global/error.vue'; +import ad from './global/ad.vue'; export default function(app: App) { + app.component('I18n', i18n); app.component('Mfm', mfm); app.component('MkA', a); app.component('MkAcct', acct); @@ -25,5 +27,5 @@ export default function(app: App) { app.component('MkUrl', url); app.component('MkLoading', loading); app.component('MkError', error); - app.component('I18n', i18n); + app.component('MkAd', ad); } diff --git a/src/client/components/notes.vue b/src/client/components/notes.vue index 675748d540..e90102921a 100644 --- a/src/client/components/notes.vue +++ b/src/client/components/notes.vue @@ -17,7 +17,7 @@ - + diff --git a/src/client/pages/gallery/post.vue b/src/client/pages/gallery/post.vue index 703506a78d..50f81376ec 100644 --- a/src/client/pages/gallery/post.vue +++ b/src/client/pages/gallery/post.vue @@ -33,6 +33,7 @@ + diff --git a/src/client/pages/instance/ads.vue b/src/client/pages/instance/ads.vue new file mode 100644 index 0000000000..4297e56c37 --- /dev/null +++ b/src/client/pages/instance/ads.vue @@ -0,0 +1,125 @@ + + + + + diff --git a/src/client/pages/instance/index.vue b/src/client/pages/instance/index.vue index 5972a02de0..974c4345bb 100644 --- a/src/client/pages/instance/index.vue +++ b/src/client/pages/instance/index.vue @@ -23,6 +23,7 @@ {{ $ts.jobQueue }} {{ $ts.files }} {{ $ts.announcements }} + {{ $ts.ads }} {{ $ts.abuseReports }} @@ -102,6 +103,7 @@ export default defineComponent({ case 'queue': return defineAsyncComponent(() => import('./queue.vue')); case 'files': return defineAsyncComponent(() => import('./files.vue')); case 'announcements': return defineAsyncComponent(() => import('./announcements.vue')); + case 'ads': return defineAsyncComponent(() => import('./ads.vue')); case 'database': return defineAsyncComponent(() => import('./database.vue')); case 'abuses': return defineAsyncComponent(() => import('./abuses.vue')); case 'settings': return defineAsyncComponent(() => import('./settings.vue')); diff --git a/src/client/pages/page.vue b/src/client/pages/page.vue index 6ee3ee8d26..4e237c2186 100644 --- a/src/client/pages/page.vue +++ b/src/client/pages/page.vue @@ -45,6 +45,7 @@
{{ $ts.createdAt }}:
{{ $ts.updatedAt }}:
+ diff --git a/src/client/scripts/paging.ts b/src/client/scripts/paging.ts index 2e49f1a64c..bcb0d7f2b0 100644 --- a/src/client/scripts/paging.ts +++ b/src/client/scripts/paging.ts @@ -91,8 +91,10 @@ export default (opts) => ({ ...params, limit: this.pagination.noPaging ? (this.pagination.limit || 10) : (this.pagination.limit || 10) + 1, }).then(items => { - for (const item of items) { + for (let i = 0; i < items.length; i++) { + const item = items[i]; markRaw(item); + if (i === 3) item._shouldInsertAd_ = true; } if (!this.pagination.noPaging && (items.length > (this.pagination.limit || 10))) { items.pop(); @@ -128,8 +130,10 @@ export default (opts) => ({ untilId: this.pagination.reversed ? this.items[0].id : this.items[this.items.length - 1].id, }), }).then(items => { - for (const item of items) { + for (let i = 0; i < items.length; i++) { + const item = items[i]; markRaw(item); + if (i === 10) item._shouldInsertAd_ = true; } if (items.length > SECOND_FETCH_LIMIT) { items.pop(); diff --git a/src/client/style.scss b/src/client/style.scss index 523ab13034..39bf6ef2d5 100644 --- a/src/client/style.scss +++ b/src/client/style.scss @@ -11,6 +11,8 @@ @media (max-width: 500px) { --margin: var(--marginHalf); } + + //--ad: rgb(255 169 0 / 10%); } ::selection { diff --git a/src/client/ui/chat/date-separated-list.vue b/src/client/ui/chat/date-separated-list.vue index b073a38eb1..bc7fc91d38 100644 --- a/src/client/ui/chat/date-separated-list.vue +++ b/src/client/ui/chat/date-separated-list.vue @@ -42,11 +42,7 @@ export default defineComponent({ if ( i != this.items.length - 1 && - new Date(item.createdAt).getDate() != new Date(this.items[i + 1].createdAt).getDate() && - !item._prId_ && - !this.items[i + 1]._prId_ && - !item._featuredId_ && - !this.items[i + 1]._featuredId_ + new Date(item.createdAt).getDate() != new Date(this.items[i + 1].createdAt).getDate() ) { const separator = h('div', { class: 'separator', diff --git a/src/client/ui/default.widgets.vue b/src/client/ui/default.widgets.vue index cabd83937e..0dd073409b 100644 --- a/src/client/ui/default.widgets.vue +++ b/src/client/ui/default.widgets.vue @@ -1,6 +1,7 @@