55 * https://opensource.org/licenses/MIT
66 */
77
8- import TimeLimitItem from "@entity/dto/time-limit-item"
8+ import TimeLimitItem , { TimeLimitItemLike } from "@entity/dto/time-limit-item"
99import limitService from "@service/limit-service"
1010import { t2Chrome } from "@util/i18n/chrome/t"
11- import { ChromeMessage } from "@util/message"
11+ import { ChromeCallback , ChromeMessage , ChromeResult } from "@util/message"
12+
13+ class _Modal {
14+ url : string
15+ mask : HTMLDivElement
16+ delayContainer : HTMLParagraphElement
17+ visible : boolean = false
18+ constructor ( url : string ) {
19+ this . mask = document . createElement ( 'div' )
20+ this . mask . id = "_timer_mask"
21+ this . mask . append ( link2Setup ( url ) )
22+ this . url = url
23+ Object . assign ( this . mask . style , maskStyle )
24+ }
25+
26+ showModal ( showDelay : boolean ) {
27+ const _thisUrl = this . url
28+ if ( showDelay && this . mask . childElementCount === 1 ) {
29+ this . delayContainer = document . createElement ( 'p' )
30+ this . delayContainer . style . marginTop = '100px'
31+
32+ // Only delay-allowed rules exist, can delay
33+ // @since 0.4.0
34+ const link = document . createElement ( 'a' )
35+ Object . assign ( link . style , linkStyle )
36+ link . setAttribute ( 'href' , 'javascript:void(0)' )
37+ const text = t2Chrome ( msg => msg . message . more5Minutes )
38+ link . innerText = text
39+ link . onclick = async ( ) => {
40+ await limitService . moreMinutes ( _thisUrl )
41+ this . hideModal ( )
42+ }
43+ this . delayContainer . append ( link )
44+ this . mask . append ( this . delayContainer )
45+ }
46+ if ( this . visible ) {
47+ return
48+ }
49+ document . body . append ( this . mask )
50+ document . body . style . overflow = 'hidden'
51+ this . visible = true
52+ }
53+
54+ hideModal ( ) {
55+ if ( ! this . visible ) {
56+ return
57+ }
58+ this . mask . remove ( )
59+ document . body . style . overflow = ''
60+ this . visible = false
61+ }
62+
63+ process ( data : TimeLimitItem [ ] ) {
64+ const anyMatch = data . map ( item => item . matches ( this . url ) ) . reduce ( ( a , b ) => a || b )
65+ if ( anyMatch ) {
66+ const anyDelay = data . map ( item => item . matches ( this . url ) && item . allowDelay ) . reduce ( ( a , b ) => a || b )
67+ this . showModal ( anyDelay )
68+ }
69+ }
70+ }
1271
1372const maskStyle : Partial < CSSStyleDeclaration > = {
1473 width : "100%" ,
@@ -34,8 +93,6 @@ function messageCode(url: string): ChromeMessage<string> {
3493 return { code : 'openLimitPage' , data : encodeURIComponent ( url ) }
3594}
3695
37- let mask : HTMLDivElement
38-
3996function link2Setup ( url : string ) : HTMLParagraphElement {
4097 const link = document . createElement ( 'a' )
4198 Object . assign ( link . style , linkStyle )
@@ -49,44 +106,24 @@ function link2Setup(url: string): HTMLParagraphElement {
49106 return p
50107}
51108
52- function moreMinutes ( url : string , limitedRules : TimeLimitItem [ ] ) : HTMLParagraphElement {
53- const p = document . createElement ( 'p' )
54- p . style . marginTop = '100px'
55- const canDelayRules = limitedRules . filter ( r => r . allowDelay )
56-
57- if ( canDelayRules && canDelayRules . length ) {
58- // Only delay-allowed rules exist, can delay
59- // @since 0.4.0
60- const link = document . createElement ( 'a' )
61- Object . assign ( link . style , linkStyle )
62- link . setAttribute ( 'href' , 'javascript:void(0)' )
63- const text = t2Chrome ( msg => msg . message . more5Minutes )
64- link . innerText = text
65- link . onclick = async ( ) => {
66- await limitService . moreMinutes ( url , canDelayRules )
67- mask . remove ( )
68- document . body . style . overflow = ''
69- }
70- p . append ( link )
71- }
72- return p
73- }
74-
75- function generateMask ( url : string , limitedRules : TimeLimitItem [ ] ) : HTMLDivElement {
76- const modalMask = document . createElement ( 'div' )
77- modalMask . id = "_timer_mask"
78- modalMask . append ( link2Setup ( url ) , moreMinutes ( url , limitedRules ) )
79- Object . assign ( modalMask . style , maskStyle )
80- return modalMask
81- }
82-
83109export default async function processLimit ( url : string ) {
110+ const modal = new _Modal ( url )
84111 const limitedRules : TimeLimitItem [ ] = await limitService . getLimited ( url )
85- if ( ! limitedRules . length ) return
86- mask = generateMask ( url , limitedRules )
87- window . onload = ( ) => {
88- document . body . append ( mask )
89- document . body . style . overflow = 'hidden'
112+ if ( limitedRules ?. length ) {
113+ window . onload = ( ) => modal . showModal ( ! ! limitedRules ?. filter ?.( item => item . allowDelay ) . length )
90114 }
115+ chrome . runtime . onMessage . addListener ( ( msg : ChromeMessage < TimeLimitItemLike [ ] > , _sender , sendResponse : ChromeCallback ) => {
116+ if ( msg . code !== "limitTimeMeet" ) {
117+ sendResponse ( { code : "ignore" } )
118+ return
119+ }
120+ const itemLikes : TimeLimitItemLike [ ] = msg . data
121+ if ( ! itemLikes ) {
122+ sendResponse ( { code : "fail" , msg : "Empty time limit item" } )
123+ }
124+ const items = itemLikes . map ( itemLike => TimeLimitItem . of ( itemLike ) )
125+ modal . process ( items )
126+ sendResponse ( { code : "success" } )
127+ } )
91128}
92129
0 commit comments