Improve ad
This commit is contained in:
		
							parent
							
								
									3d7c3c39ff
								
							
						
					
					
						commit
						b60f9fbc00
					
				
					 9 changed files with 72 additions and 18 deletions
				
			
		|  | @ -756,6 +756,7 @@ high: "高" | |||
| middle: "中" | ||||
| low: "低" | ||||
| emailNotConfiguredWarning: "メールアドレスの設定がされていません。" | ||||
| ratio: "比率" | ||||
| 
 | ||||
| _forgotPassword: | ||||
|   enterEmail: "アカウントに登録したメールアドレスを入力してください。そのアドレス宛てに、パスワードリセット用のリンクが送信されます。" | ||||
|  |  | |||
							
								
								
									
										14
									
								
								migration/1620364649428-ad2.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								migration/1620364649428-ad2.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | |||
| import {MigrationInterface, QueryRunner} from "typeorm"; | ||||
| 
 | ||||
| export class ad21620364649428 implements MigrationInterface { | ||||
|     name = 'ad21620364649428' | ||||
| 
 | ||||
|     public async up(queryRunner: QueryRunner): Promise<void> { | ||||
|         await queryRunner.query(`ALTER TABLE "ad" ADD "ratio" integer NOT NULL DEFAULT '1'`); | ||||
|     } | ||||
| 
 | ||||
|     public async down(queryRunner: QueryRunner): Promise<void> { | ||||
|         await queryRunner.query(`ALTER TABLE "ad" DROP COLUMN "ratio"`); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | @ -19,7 +19,7 @@ | |||
| 
 | ||||
| <script lang="ts"> | ||||
| import { defineComponent, ref } from 'vue'; | ||||
| import { instance } from '@client/instance'; | ||||
| import { Instance, instance } from '@client/instance'; | ||||
| import { host } from '@client/config'; | ||||
| import MkButton from '@client/components/ui/button.vue'; | ||||
| 
 | ||||
|  | @ -45,32 +45,45 @@ export default defineComponent({ | |||
| 			showMenu.value = !showMenu.value; | ||||
| 		}; | ||||
| 
 | ||||
| 		let ad = null; | ||||
| 		const choseAd = (): Instance['ads'][number] | null => { | ||||
| 			if (props.specify) { | ||||
| 				return props.specify as Instance['ads'][number]; | ||||
| 			} | ||||
| 
 | ||||
| 		if (props.specify) { | ||||
| 			ad = props.specify; | ||||
| 		} else { | ||||
| 			let ads = instance.ads.filter(ad => props.prefer.includes(ad.place)); | ||||
| 
 | ||||
| 			if (ads.length === 0) { | ||||
| 				ads = instance.ads.filter(ad => ad.place === 'square'); | ||||
| 			} | ||||
| 
 | ||||
| 			const high = ads.filter(ad => ad.priority === 'high'); | ||||
| 			const middle = ads.filter(ad => ad.priority === 'middle'); | ||||
| 			const low = ads.filter(ad => ad.priority === 'low'); | ||||
| 			const lowPriorityAds = ads.filter(ad => ad.ratio === 0); | ||||
| 			ads = ads.filter(ad => ad.ratio !== 0); | ||||
| 
 | ||||
| 			if (high.length > 0) { | ||||
| 				ad = high[Math.floor(Math.random() * high.length)]; | ||||
| 			} else if (middle.length > 0) { | ||||
| 				ad = middle[Math.floor(Math.random() * middle.length)]; | ||||
| 			} else if (low.length > 0) { | ||||
| 				ad = low[Math.floor(Math.random() * low.length)]; | ||||
| 			if (ads.length === 0) { | ||||
| 				if (lowPriorityAds.length !== 0) { | ||||
| 					return lowPriorityAds[Math.floor(Math.random() * lowPriorityAds.length)]; | ||||
| 				} else { | ||||
| 					return null; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 			const totalFactor = ads.reduce((a, b) => a + b.ratio, 0); | ||||
| 			const r = Math.random() * totalFactor; | ||||
| 
 | ||||
| 			let stackedFactor = 0; | ||||
| 			for (const ad of ads) { | ||||
| 				if (r >= stackedFactor && r <= stackedFactor + ad.ratio) { | ||||
| 					return ad; | ||||
| 				} else { | ||||
| 					stackedFactor += ad.ratio; | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			return null; | ||||
| 		}; | ||||
| 
 | ||||
| 		return { | ||||
| 			ad, | ||||
| 			ad: choseAd(), | ||||
| 			showMenu, | ||||
| 			toggleMenu, | ||||
| 			host, | ||||
|  |  | |||
|  | @ -3,10 +3,16 @@ import { api } from './os'; | |||
| 
 | ||||
| // TODO: 他のタブと永続化されたstateを同期
 | ||||
| 
 | ||||
| type Instance = { | ||||
| export type Instance = { | ||||
| 	emojis: { | ||||
| 		category: string; | ||||
| 	}[]; | ||||
| 	ads: { | ||||
| 		ratio: number; | ||||
| 		place: string; | ||||
| 		url: string; | ||||
| 		imageUrl: string; | ||||
| 	}[]; | ||||
| }; | ||||
| 
 | ||||
| const data = localStorage.getItem('instance'); | ||||
|  |  | |||
|  | @ -15,12 +15,17 @@ | |||
| 				<MkRadio v-model="ad.place" value="horizontal">horizontal</MkRadio> | ||||
| 				<MkRadio v-model="ad.place" value="horizontal-big">horizontal-big</MkRadio> | ||||
| 			</div> | ||||
| 			<!-- | ||||
| 			<div style="margin: 32px 0;"> | ||||
| 				{{ $ts.priority }} | ||||
| 				<MkRadio v-model="ad.priority" value="high">{{ $ts.high }}</MkRadio> | ||||
| 				<MkRadio v-model="ad.priority" value="middle">{{ $ts.middle }}</MkRadio> | ||||
| 				<MkRadio v-model="ad.priority" value="low">{{ $ts.low }}</MkRadio> | ||||
| 			</div> | ||||
| 			--> | ||||
| 			<MkInput v-model:value="ad.ratio" type="number"> | ||||
| 				<span>{{ $ts.ratio }}</span> | ||||
| 			</MkInput> | ||||
| 			<MkInput v-model:value="ad.expiresAt" type="date"> | ||||
| 				<span>{{ $ts.expiration }}</span> | ||||
| 			</MkInput> | ||||
|  | @ -82,6 +87,7 @@ export default defineComponent({ | |||
| 				memo: '', | ||||
| 				place: 'square', | ||||
| 				priority: 'middle', | ||||
| 				ratio: 1, | ||||
| 				url: '', | ||||
| 				imageUrl: null, | ||||
| 				expiresAt: null, | ||||
|  |  | |||
|  | @ -23,11 +23,17 @@ export class Ad { | |||
| 	}) | ||||
| 	public place: string; | ||||
| 
 | ||||
| 	// 今は使われていないが将来的に活用される可能性はある
 | ||||
| 	@Column('varchar', { | ||||
| 		length: 32, nullable: false | ||||
| 	}) | ||||
| 	public priority: string; | ||||
| 
 | ||||
| 	@Column('integer', { | ||||
| 		default: 1, nullable: false | ||||
| 	}) | ||||
| 	public ratio: number; | ||||
| 
 | ||||
| 	@Column('varchar', { | ||||
| 		length: 1024, nullable: false | ||||
| 	}) | ||||
|  |  | |||
|  | @ -22,6 +22,9 @@ export const meta = { | |||
| 		priority: { | ||||
| 			validator: $.str | ||||
| 		}, | ||||
| 		ratio: { | ||||
| 			validator: $.num.int().min(0) | ||||
| 		}, | ||||
| 		expiresAt: { | ||||
| 			validator: $.num.int() | ||||
| 		}, | ||||
|  | @ -39,6 +42,7 @@ export default define(meta, async (ps) => { | |||
| 		url: ps.url, | ||||
| 		imageUrl: ps.imageUrl, | ||||
| 		priority: ps.priority, | ||||
| 		ratio: ps.ratio, | ||||
| 		place: ps.place, | ||||
| 		memo: ps.memo, | ||||
| 	}); | ||||
|  |  | |||
|  | @ -29,6 +29,9 @@ export const meta = { | |||
| 		priority: { | ||||
| 			validator: $.str | ||||
| 		}, | ||||
| 		ratio: { | ||||
| 			validator: $.num.int().min(0) | ||||
| 		}, | ||||
| 		expiresAt: { | ||||
| 			validator: $.num.int() | ||||
| 		}, | ||||
|  | @ -52,6 +55,7 @@ export default define(meta, async (ps, me) => { | |||
| 		url: ps.url, | ||||
| 		place: ps.place, | ||||
| 		priority: ps.priority, | ||||
| 		ratio: ps.ratio, | ||||
| 		memo: ps.memo, | ||||
| 		imageUrl: ps.imageUrl, | ||||
| 		expiresAt: new Date(ps.expiresAt), | ||||
|  |  | |||
|  | @ -511,7 +511,7 @@ export default define(meta, async (ps, me) => { | |||
| 		ads: ads.map(ad => ({ | ||||
| 			url: ad.url, | ||||
| 			place: ad.place, | ||||
| 			priority: ad.priority, | ||||
| 			ratio: ad.ratio, | ||||
| 			imageUrl: ad.imageUrl, | ||||
| 		})), | ||||
| 		enableEmail: instance.enableEmail, | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue