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: "中" | middle: "中" | ||||||
| low: "低" | low: "低" | ||||||
| emailNotConfiguredWarning: "メールアドレスの設定がされていません。" | emailNotConfiguredWarning: "メールアドレスの設定がされていません。" | ||||||
|  | ratio: "比率" | ||||||
| 
 | 
 | ||||||
| _forgotPassword: | _forgotPassword: | ||||||
|   enterEmail: "アカウントに登録したメールアドレスを入力してください。そのアドレス宛てに、パスワードリセット用のリンクが送信されます。" |   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"> | <script lang="ts"> | ||||||
| import { defineComponent, ref } from 'vue'; | import { defineComponent, ref } from 'vue'; | ||||||
| import { instance } from '@client/instance'; | import { Instance, instance } from '@client/instance'; | ||||||
| import { host } from '@client/config'; | import { host } from '@client/config'; | ||||||
| import MkButton from '@client/components/ui/button.vue'; | import MkButton from '@client/components/ui/button.vue'; | ||||||
| 
 | 
 | ||||||
|  | @ -45,32 +45,45 @@ export default defineComponent({ | ||||||
| 			showMenu.value = !showMenu.value; | 			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)); | 			let ads = instance.ads.filter(ad => props.prefer.includes(ad.place)); | ||||||
| 
 | 
 | ||||||
| 			if (ads.length === 0) { | 			if (ads.length === 0) { | ||||||
| 				ads = instance.ads.filter(ad => ad.place === 'square'); | 				ads = instance.ads.filter(ad => ad.place === 'square'); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			const high = ads.filter(ad => ad.priority === 'high'); | 			const lowPriorityAds = ads.filter(ad => ad.ratio === 0); | ||||||
| 			const middle = ads.filter(ad => ad.priority === 'middle'); | 			ads = ads.filter(ad => ad.ratio !== 0); | ||||||
| 			const low = ads.filter(ad => ad.priority === 'low'); |  | ||||||
| 
 | 
 | ||||||
| 			if (high.length > 0) { | 			if (ads.length === 0) { | ||||||
| 				ad = high[Math.floor(Math.random() * high.length)]; | 				if (lowPriorityAds.length !== 0) { | ||||||
| 			} else if (middle.length > 0) { | 					return lowPriorityAds[Math.floor(Math.random() * lowPriorityAds.length)]; | ||||||
| 				ad = middle[Math.floor(Math.random() * middle.length)]; | 				} else { | ||||||
| 			} else if (low.length > 0) { | 					return null; | ||||||
| 				ad = low[Math.floor(Math.random() * low.length)]; | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 
 | ||||||
|  | 			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 { | 		return { | ||||||
| 			ad, | 			ad: choseAd(), | ||||||
| 			showMenu, | 			showMenu, | ||||||
| 			toggleMenu, | 			toggleMenu, | ||||||
| 			host, | 			host, | ||||||
|  |  | ||||||
|  | @ -3,10 +3,16 @@ import { api } from './os'; | ||||||
| 
 | 
 | ||||||
| // TODO: 他のタブと永続化されたstateを同期
 | // TODO: 他のタブと永続化されたstateを同期
 | ||||||
| 
 | 
 | ||||||
| type Instance = { | export type Instance = { | ||||||
| 	emojis: { | 	emojis: { | ||||||
| 		category: string; | 		category: string; | ||||||
| 	}[]; | 	}[]; | ||||||
|  | 	ads: { | ||||||
|  | 		ratio: number; | ||||||
|  | 		place: string; | ||||||
|  | 		url: string; | ||||||
|  | 		imageUrl: string; | ||||||
|  | 	}[]; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const data = localStorage.getItem('instance'); | 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">horizontal</MkRadio> | ||||||
| 				<MkRadio v-model="ad.place" value="horizontal-big">horizontal-big</MkRadio> | 				<MkRadio v-model="ad.place" value="horizontal-big">horizontal-big</MkRadio> | ||||||
| 			</div> | 			</div> | ||||||
|  | 			<!-- | ||||||
| 			<div style="margin: 32px 0;"> | 			<div style="margin: 32px 0;"> | ||||||
| 				{{ $ts.priority }} | 				{{ $ts.priority }} | ||||||
| 				<MkRadio v-model="ad.priority" value="high">{{ $ts.high }}</MkRadio> | 				<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="middle">{{ $ts.middle }}</MkRadio> | ||||||
| 				<MkRadio v-model="ad.priority" value="low">{{ $ts.low }}</MkRadio> | 				<MkRadio v-model="ad.priority" value="low">{{ $ts.low }}</MkRadio> | ||||||
| 			</div> | 			</div> | ||||||
|  | 			--> | ||||||
|  | 			<MkInput v-model:value="ad.ratio" type="number"> | ||||||
|  | 				<span>{{ $ts.ratio }}</span> | ||||||
|  | 			</MkInput> | ||||||
| 			<MkInput v-model:value="ad.expiresAt" type="date"> | 			<MkInput v-model:value="ad.expiresAt" type="date"> | ||||||
| 				<span>{{ $ts.expiration }}</span> | 				<span>{{ $ts.expiration }}</span> | ||||||
| 			</MkInput> | 			</MkInput> | ||||||
|  | @ -82,6 +87,7 @@ export default defineComponent({ | ||||||
| 				memo: '', | 				memo: '', | ||||||
| 				place: 'square', | 				place: 'square', | ||||||
| 				priority: 'middle', | 				priority: 'middle', | ||||||
|  | 				ratio: 1, | ||||||
| 				url: '', | 				url: '', | ||||||
| 				imageUrl: null, | 				imageUrl: null, | ||||||
| 				expiresAt: null, | 				expiresAt: null, | ||||||
|  |  | ||||||
|  | @ -23,11 +23,17 @@ export class Ad { | ||||||
| 	}) | 	}) | ||||||
| 	public place: string; | 	public place: string; | ||||||
| 
 | 
 | ||||||
|  | 	// 今は使われていないが将来的に活用される可能性はある
 | ||||||
| 	@Column('varchar', { | 	@Column('varchar', { | ||||||
| 		length: 32, nullable: false | 		length: 32, nullable: false | ||||||
| 	}) | 	}) | ||||||
| 	public priority: string; | 	public priority: string; | ||||||
| 
 | 
 | ||||||
|  | 	@Column('integer', { | ||||||
|  | 		default: 1, nullable: false | ||||||
|  | 	}) | ||||||
|  | 	public ratio: number; | ||||||
|  | 
 | ||||||
| 	@Column('varchar', { | 	@Column('varchar', { | ||||||
| 		length: 1024, nullable: false | 		length: 1024, nullable: false | ||||||
| 	}) | 	}) | ||||||
|  |  | ||||||
|  | @ -22,6 +22,9 @@ export const meta = { | ||||||
| 		priority: { | 		priority: { | ||||||
| 			validator: $.str | 			validator: $.str | ||||||
| 		}, | 		}, | ||||||
|  | 		ratio: { | ||||||
|  | 			validator: $.num.int().min(0) | ||||||
|  | 		}, | ||||||
| 		expiresAt: { | 		expiresAt: { | ||||||
| 			validator: $.num.int() | 			validator: $.num.int() | ||||||
| 		}, | 		}, | ||||||
|  | @ -39,6 +42,7 @@ export default define(meta, async (ps) => { | ||||||
| 		url: ps.url, | 		url: ps.url, | ||||||
| 		imageUrl: ps.imageUrl, | 		imageUrl: ps.imageUrl, | ||||||
| 		priority: ps.priority, | 		priority: ps.priority, | ||||||
|  | 		ratio: ps.ratio, | ||||||
| 		place: ps.place, | 		place: ps.place, | ||||||
| 		memo: ps.memo, | 		memo: ps.memo, | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
|  | @ -29,6 +29,9 @@ export const meta = { | ||||||
| 		priority: { | 		priority: { | ||||||
| 			validator: $.str | 			validator: $.str | ||||||
| 		}, | 		}, | ||||||
|  | 		ratio: { | ||||||
|  | 			validator: $.num.int().min(0) | ||||||
|  | 		}, | ||||||
| 		expiresAt: { | 		expiresAt: { | ||||||
| 			validator: $.num.int() | 			validator: $.num.int() | ||||||
| 		}, | 		}, | ||||||
|  | @ -52,6 +55,7 @@ export default define(meta, async (ps, me) => { | ||||||
| 		url: ps.url, | 		url: ps.url, | ||||||
| 		place: ps.place, | 		place: ps.place, | ||||||
| 		priority: ps.priority, | 		priority: ps.priority, | ||||||
|  | 		ratio: ps.ratio, | ||||||
| 		memo: ps.memo, | 		memo: ps.memo, | ||||||
| 		imageUrl: ps.imageUrl, | 		imageUrl: ps.imageUrl, | ||||||
| 		expiresAt: new Date(ps.expiresAt), | 		expiresAt: new Date(ps.expiresAt), | ||||||
|  |  | ||||||
|  | @ -511,7 +511,7 @@ export default define(meta, async (ps, me) => { | ||||||
| 		ads: ads.map(ad => ({ | 		ads: ads.map(ad => ({ | ||||||
| 			url: ad.url, | 			url: ad.url, | ||||||
| 			place: ad.place, | 			place: ad.place, | ||||||
| 			priority: ad.priority, | 			ratio: ad.ratio, | ||||||
| 			imageUrl: ad.imageUrl, | 			imageUrl: ad.imageUrl, | ||||||
| 		})), | 		})), | ||||||
| 		enableEmail: instance.enableEmail, | 		enableEmail: instance.enableEmail, | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue