From b7a5de57507cd023828673ca81fcd13142d85465 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Fri, 5 Jul 2024 20:52:30 +0200 Subject: [PATCH 001/100] Move keyframes to separate css file for default balloon --- resources/balloons/default/default.css | 29 +++++++++++++++++++++++++ src/content/style.css | 30 -------------------------- 2 files changed, 29 insertions(+), 30 deletions(-) create mode 100644 resources/balloons/default/default.css diff --git a/resources/balloons/default/default.css b/resources/balloons/default/default.css new file mode 100644 index 00000000..5e570cff --- /dev/null +++ b/resources/balloons/default/default.css @@ -0,0 +1,29 @@ +@keyframes rise { + 0% { + transform: translateY(100vh); + } + 100% { + transform: translateY(-10vh); + } +} + +@keyframes swing { + 0% { + transform: translateX(15px); + } + 50% { + transform: translateX(-15px); + } + 100% { + transform: translateX(15px); + } +} + +@keyframes wave { + 0% { + transform: rotate(-8deg); + } + 100% { + transform: rotate(8deg); + } +} diff --git a/src/content/style.css b/src/content/style.css index 711a799b..d83ce76e 100644 --- a/src/content/style.css +++ b/src/content/style.css @@ -33,33 +33,3 @@ pointer-events: none; } - -@keyframes rise { - 0% { - transform: translateY(100vh); - } - 100% { - transform: translateY(-10vh); - } -} - -@keyframes swing { - 0% { - transform: translateX(15px); - } - 50% { - transform: translateX(-15px); - } - 100% { - transform: translateX(15px); - } -} - -@keyframes wave { - 0% { - transform: rotate(-8deg); - } - 100% { - transform: rotate(8deg); - } -} \ No newline at end of file From db76450c4841d3cbd3ffeb40618da8b03466f1b0 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Fri, 5 Jul 2024 21:46:56 +0200 Subject: [PATCH 002/100] Add resoureLocation property to abstract balloon --- src/balloon.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/balloon.ts b/src/balloon.ts index e0e99aaa..4fcf8ee6 100644 --- a/src/balloon.ts +++ b/src/balloon.ts @@ -31,6 +31,10 @@ export default abstract class Balloon { public readonly element: HTMLDivElement = document.createElement('div'); + public get resourceLocation(): string { + return balloonResourceLocation + this.name + '/'; + } + constructor() { // Add an event listener to the balloon this.element.addEventListener('click', this.pop.bind(this)); From 46d462ed9c4d443dd03d9f5857bf1ef1f6bf506d Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Fri, 5 Jul 2024 21:47:37 +0200 Subject: [PATCH 003/100] Import custom stylesheet for default balloon --- src/balloons/default.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/balloons/default.ts b/src/balloons/default.ts index b2258d25..ae469333 100644 --- a/src/balloons/default.ts +++ b/src/balloons/default.ts @@ -1,7 +1,7 @@ import Balloon, { balloonResourceLocation } from '@/balloon'; import storage from '@/managers/storage'; import { BalloonName } from '@/const'; -import { random } from '@/utils'; +import { importStylesheet, random } from '@/utils'; export type BuildProps = { size: number; @@ -86,6 +86,7 @@ export default class Default extends Balloon { constructor() { super(); + importStylesheet('default-styles', this.resourceLocation + 'default.css'); // Load the pop sound this.popSound.src = this.popSoundUrl; // Load the balloon image From 17a8aafdb48456dae3a317125ac6be2dac2adbbc Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Fri, 5 Jul 2024 21:51:31 +0200 Subject: [PATCH 004/100] Move more styles to default balloon stylesheet --- resources/balloons/default/default.css | 9 +++++++++ src/content/style.css | 9 --------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/resources/balloons/default/default.css b/resources/balloons/default/default.css index 5e570cff..242b14ce 100644 --- a/resources/balloons/default/default.css +++ b/resources/balloons/default/default.css @@ -1,3 +1,12 @@ +.balloon img { + width: 100%; + height: 100%; + aspect-ratio: 1/1; + object-fit: contain; + + pointer-events: none; +} + @keyframes rise { 0% { transform: translateY(100vh); diff --git a/src/content/style.css b/src/content/style.css index d83ce76e..ff4cbfc5 100644 --- a/src/content/style.css +++ b/src/content/style.css @@ -24,12 +24,3 @@ pointer-events: auto; } - -.balloon img { - width: 100%; - height: 100%; - aspect-ratio: 1/1; - object-fit: contain; - - pointer-events: none; -} From 03be2167b2d53d976d5bd62a1695eaf00314cad4 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Fri, 5 Jul 2024 22:14:14 +0200 Subject: [PATCH 005/100] Specify an x value where the balloon needs to rise to close #250 --- resources/balloons/default/default.css | 2 +- src/balloons/default.ts | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/resources/balloons/default/default.css b/resources/balloons/default/default.css index 242b14ce..3e357c96 100644 --- a/resources/balloons/default/default.css +++ b/resources/balloons/default/default.css @@ -12,7 +12,7 @@ transform: translateY(100vh); } 100% { - transform: translateY(-10vh); + transform: translateY(var(--rise-to, -10vh)); } } diff --git a/src/balloons/default.ts b/src/balloons/default.ts index ae469333..7ef3697c 100644 --- a/src/balloons/default.ts +++ b/src/balloons/default.ts @@ -107,6 +107,9 @@ export default class Default extends Balloon { this.element.classList.add('balloon'); + // Set css variables + this.element.style.setProperty('--rise-to', -size + 'px'); + // Set the balloon's width and height this.element.style.width = size + 'px'; this.element.style.height = this.element.style.width; From b4a3c8fed465bca264a73b4e813f16f5a2c64e02 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Fri, 5 Jul 2024 22:21:41 +0200 Subject: [PATCH 006/100] Add `--swing` css property to keyframe for default balloon #251 --- resources/balloons/default/default.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/balloons/default/default.css b/resources/balloons/default/default.css index 3e357c96..1105621b 100644 --- a/resources/balloons/default/default.css +++ b/resources/balloons/default/default.css @@ -18,13 +18,13 @@ @keyframes swing { 0% { - transform: translateX(15px); + transform: translateX(var(--swing, 15px)); } 50% { - transform: translateX(-15px); + transform: translateX(calc(-1 * var(--swing, 15px))); } 100% { - transform: translateX(15px); + transform: translateX(var(--swing, 15px)); } } From 3141f25be0936efee08b8081ec09f7953c3f9de4 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Fri, 5 Jul 2024 22:23:22 +0200 Subject: [PATCH 007/100] Add `--wave-deg` css property to wave keyframes #251 --- resources/balloons/default/default.css | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/resources/balloons/default/default.css b/resources/balloons/default/default.css index 1105621b..f0cb0024 100644 --- a/resources/balloons/default/default.css +++ b/resources/balloons/default/default.css @@ -18,21 +18,21 @@ @keyframes swing { 0% { - transform: translateX(var(--swing, 15px)); + transform: translateX(var(--swing-offset, 15px)); } 50% { - transform: translateX(calc(-1 * var(--swing, 15px))); + transform: translateX(calc(-1 * var(--swing-offset, 15px))); } 100% { - transform: translateX(var(--swing, 15px)); + transform: translateX(var(--swing-offset, 15px)); } } @keyframes wave { 0% { - transform: rotate(-8deg); + transform: rotate(calc(-1 * var(--wave-deg, 8deg))); } 100% { - transform: rotate(8deg); + transform: rotate(var(--wave-deg, 8deg)); } } From ec104e2d290bc4e02e727a0fb3e75254269aa94d Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Fri, 5 Jul 2024 22:39:31 +0200 Subject: [PATCH 008/100] Add swing offset and wave degrees to default balloon options close #251 --- src/balloons/default.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/balloons/default.ts b/src/balloons/default.ts index 7ef3697c..e7b4a7e0 100644 --- a/src/balloons/default.ts +++ b/src/balloons/default.ts @@ -31,6 +31,16 @@ export type BalloonOptions = { * If not provided, the default sound will be used. */ popSoundUrl: string; + /** + * The amount of pixels the balloon should wave back and forth. + * + * First `waveDegrees` to the right, return back to the center, then `waveDegrees` to the left. + */ + swingOffset: number; + /** + * The degrees the balloon will tilt when back ant forth. + */ + waveDegrees: number; }; export default class Default extends Balloon { @@ -40,6 +50,8 @@ export default class Default extends Balloon { dir_name: this.name, imageUrl: '/icon.png', popSoundUrl: '/pop.mp3', + swingOffset: 15, + waveDegrees: 8, }; /** @@ -109,6 +121,14 @@ export default class Default extends Balloon { // Set css variables this.element.style.setProperty('--rise-to', -size + 'px'); + this.element.style.setProperty( + '--swing-offset', + this.options.swingOffset + 'px' + ); + this.element.style.setProperty( + '--wave-deg', + this.options.waveDegrees + 'deg' + ); // Set the balloon's width and height this.element.style.width = size + 'px'; From eca5fff1160119d00d9efc32d99fba03a0862b89 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sun, 7 Jul 2024 21:11:38 +0200 Subject: [PATCH 009/100] mock fetch in default balloon test --- tests/balloons/default.test.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/balloons/default.test.ts b/tests/balloons/default.test.ts index f838f2e6..95d27409 100644 --- a/tests/balloons/default.test.ts +++ b/tests/balloons/default.test.ts @@ -1,10 +1,15 @@ import { Default } from '@/balloons'; +import fetchMock from 'jest-fetch-mock'; + +fetchMock.enableMocks(); describe('Default Balloon', () => { let balloon: Default; beforeEach(() => { balloon = new Default(); + + fetchMock.resetMocks(); }); test('name should be "default"', () => { From 2cdc1f062f9ce2dfcda9fac7142dfe9c7d5d731d Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Tue, 25 Jun 2024 14:34:07 +0200 Subject: [PATCH 010/100] Load image and audio sorces when building the balloon --- src/balloons/default.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/balloons/default.ts b/src/balloons/default.ts index e7b4a7e0..60f9cd65 100644 --- a/src/balloons/default.ts +++ b/src/balloons/default.ts @@ -99,10 +99,6 @@ export default class Default extends Balloon { constructor() { super(); importStylesheet('default-styles', this.resourceLocation + 'default.css'); - // Load the pop sound - this.popSound.src = this.popSoundUrl; - // Load the balloon image - this.balloonImage.src = this.balloonImageUrl; } public build() { @@ -117,6 +113,11 @@ export default class Default extends Balloon { this.swingDurationThreshold[1] ); + // Load the pop sound + this.popSound.src = this.popSoundUrl; + // Load the balloon image + this.balloonImage.src = this.balloonImageUrl; + this.element.classList.add('balloon'); // Set css variables From ff95f01f64462ab15aae5222427306265bc34f55 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Tue, 25 Jun 2024 14:34:29 +0200 Subject: [PATCH 011/100] Add a golden balloon svg #242 --- resources/balloons/gold/balloon.svg | 46 +++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 resources/balloons/gold/balloon.svg diff --git a/resources/balloons/gold/balloon.svg b/resources/balloons/gold/balloon.svg new file mode 100644 index 00000000..e0636276 --- /dev/null +++ b/resources/balloons/gold/balloon.svg @@ -0,0 +1,46 @@ + + + + + + + + + + \ No newline at end of file From cc16ff3ecadc7fd0a22a6f8fa05c464435d5de97 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Tue, 25 Jun 2024 17:51:21 +0200 Subject: [PATCH 012/100] Add gradient to golden balloon #242 --- resources/balloons/gold/balloon.svg | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/resources/balloons/gold/balloon.svg b/resources/balloons/gold/balloon.svg index e0636276..fded9830 100644 --- a/resources/balloons/gold/balloon.svg +++ b/resources/balloons/gold/balloon.svg @@ -1,12 +1,18 @@ + + + + + + - + - + \ No newline at end of file From 8910f3c49d602791841bec7c4ed1140e587e85f5 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Tue, 25 Jun 2024 19:06:32 +0200 Subject: [PATCH 013/100] Add the golden balloon #242 --- src/balloons/gold.ts | 12 ++++++++++++ src/balloons/index.ts | 1 + 2 files changed, 13 insertions(+) create mode 100644 src/balloons/gold.ts diff --git a/src/balloons/gold.ts b/src/balloons/gold.ts new file mode 100644 index 00000000..e38f61bf --- /dev/null +++ b/src/balloons/gold.ts @@ -0,0 +1,12 @@ +import Default, { BalloonOptions } from './default'; + +export default class Confetti extends Default { + public static readonly spawn_chance: number = 10.1; + // @ts-ignore + public readonly name = 'gold'; + + constructor() { + super(); + this.options.imageUrl = `/../${this.name}/balloon.svg`; + } +} diff --git a/src/balloons/index.ts b/src/balloons/index.ts index 05d885f6..872d0bc0 100644 --- a/src/balloons/index.ts +++ b/src/balloons/index.ts @@ -1,2 +1,3 @@ export { default as Default } from './default'; export { default as Confetti } from './confetti'; +export { default as Gold } from './gold'; From 2606dd96f25357265187b654f044a78be7ee47b5 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Thu, 27 Jun 2024 14:06:50 +0200 Subject: [PATCH 014/100] Update gold balloon spawn rate --- src/balloons/gold.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/balloons/gold.ts b/src/balloons/gold.ts index e38f61bf..8718a4d4 100644 --- a/src/balloons/gold.ts +++ b/src/balloons/gold.ts @@ -1,7 +1,7 @@ import Default, { BalloonOptions } from './default'; export default class Confetti extends Default { - public static readonly spawn_chance: number = 10.1; + public static readonly spawn_chance: number = 0.05; // @ts-ignore public readonly name = 'gold'; From d7b6e50e2c66b6c3c4edf31a161a56774e535eaf Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Tue, 28 Jun 2022 22:57:11 +0200 Subject: [PATCH 015/100] Update balloon colors --- resources/balloons/gold/balloon.svg | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/resources/balloons/gold/balloon.svg b/resources/balloons/gold/balloon.svg index fded9830..b0b303ce 100644 --- a/resources/balloons/gold/balloon.svg +++ b/resources/balloons/gold/balloon.svg @@ -3,8 +3,8 @@ - - + + From e38822cd754bd76a4dabf0b5d064d614ba22f600 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sat, 29 Jun 2024 23:00:40 +0200 Subject: [PATCH 016/100] Make the golden balloon rise slower --- src/balloons/gold.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/balloons/gold.ts b/src/balloons/gold.ts index 8718a4d4..379d152e 100644 --- a/src/balloons/gold.ts +++ b/src/balloons/gold.ts @@ -5,6 +5,8 @@ export default class Confetti extends Default { // @ts-ignore public readonly name = 'gold'; + public readonly riseDurationThreshold: [number, number] = [15000, 20000]; + constructor() { super(); this.options.imageUrl = `/../${this.name}/balloon.svg`; From cb83106c916bf6cf7f81ef0e18f9e64db3bb80b1 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sun, 30 Jun 2024 22:09:12 +0200 Subject: [PATCH 017/100] Fix balloon set riseDuration configuration --- src/balloons/gold.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/balloons/gold.ts b/src/balloons/gold.ts index 379d152e..ca1975c8 100644 --- a/src/balloons/gold.ts +++ b/src/balloons/gold.ts @@ -5,10 +5,10 @@ export default class Confetti extends Default { // @ts-ignore public readonly name = 'gold'; - public readonly riseDurationThreshold: [number, number] = [15000, 20000]; - constructor() { super(); this.options.imageUrl = `/../${this.name}/balloon.svg`; + this.riseDurationThreshold[0] = 15000; + this.riseDurationThreshold[1] = 20000; } } From 8ebfa29f6783df4577803fb9202f93c794021291 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Mon, 1 Jul 2024 17:54:11 +0200 Subject: [PATCH 018/100] Rename Gold balloon class to Gold --- src/balloons/gold.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/balloons/gold.ts b/src/balloons/gold.ts index ca1975c8..1297c1a9 100644 --- a/src/balloons/gold.ts +++ b/src/balloons/gold.ts @@ -1,6 +1,6 @@ -import Default, { BalloonOptions } from './default'; +import Default from './default'; -export default class Confetti extends Default { +export default class Gold extends Default { public static readonly spawn_chance: number = 0.05; // @ts-ignore public readonly name = 'gold'; From c28c44e0099c12ddb79ba6faa122484adc90561b Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Mon, 1 Jul 2024 18:01:46 +0200 Subject: [PATCH 019/100] Make gold balloon swing slower --- src/balloons/gold.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/balloons/gold.ts b/src/balloons/gold.ts index 1297c1a9..7475a025 100644 --- a/src/balloons/gold.ts +++ b/src/balloons/gold.ts @@ -1,7 +1,7 @@ import Default from './default'; export default class Gold extends Default { - public static readonly spawn_chance: number = 0.05; + public static readonly spawn_chance: number = 1.05; // @ts-ignore public readonly name = 'gold'; @@ -10,5 +10,7 @@ export default class Gold extends Default { this.options.imageUrl = `/../${this.name}/balloon.svg`; this.riseDurationThreshold[0] = 15000; this.riseDurationThreshold[1] = 20000; + this.swingDurationThreshold[0] = 3; + this.swingDurationThreshold[1] = 4; } } From 5aed11efc84926139fa5a1832d8886f955e26ec2 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Tue, 2 Jul 2024 09:48:43 +0200 Subject: [PATCH 020/100] Fix gold spawnrate, again --- src/balloons/gold.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/balloons/gold.ts b/src/balloons/gold.ts index 7475a025..2649db04 100644 --- a/src/balloons/gold.ts +++ b/src/balloons/gold.ts @@ -1,7 +1,7 @@ import Default from './default'; export default class Gold extends Default { - public static readonly spawn_chance: number = 1.05; + public static readonly spawn_chance: number = 0.05; // @ts-ignore public readonly name = 'gold'; From a1fff00af98ad75e52acf4c2ee8428c951392496 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Tue, 2 Jul 2024 21:24:04 +0200 Subject: [PATCH 021/100] Refactor default balloon options and name --- src/balloons/default.ts | 55 ++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/src/balloons/default.ts b/src/balloons/default.ts index 60f9cd65..60ce80b7 100644 --- a/src/balloons/default.ts +++ b/src/balloons/default.ts @@ -31,6 +31,18 @@ export type BalloonOptions = { * If not provided, the default sound will be used. */ popSoundUrl: string; + /** + * The duration thresholds for the rise animation. + * + * The first value is the minimum duration and the second value is the maximum duration. + */ + riseDurationThreshold: [number, number]; + /** + * The duration thresholds for the swing animation. + * + * The first value is the minimum duration and the second value is the maximum duration. + */ + swingDurationThreshold: [number, number]; /** * The amount of pixels the balloon should wave back and forth. * @@ -45,27 +57,20 @@ export type BalloonOptions = { export default class Default extends Balloon { public static readonly spawn_chance: number = 0.9; - public readonly name = 'default'; - public readonly options: BalloonOptions = { - dir_name: this.name, - imageUrl: '/icon.png', - popSoundUrl: '/pop.mp3', - swingOffset: 15, - waveDegrees: 8, - }; - - /** - * The duration thresholds for the rise animation. - * - * The first value is the minimum duration and the second value is the maximum duration. - */ - public readonly riseDurationThreshold: [number, number] = [10000, 15000]; - /** - * The duration thresholds for the swing animation. - * - * The first value is the minimum duration and the second value is the maximum duration. - */ - public readonly swingDurationThreshold: [number, number] = [2, 4]; + public get name(): 'default' { + return 'default'; + } + public get options(): BalloonOptions { + return { + dir_name: this.name, + imageUrl: '/icon.png', + popSoundUrl: '/pop.mp3', + riseDurationThreshold: [10000, 15000], + swingDurationThreshold: [2, 4], + swingOffset: 15, + waveDegrees: 8, + }; + } /** * The image element for the balloon image. @@ -105,12 +110,12 @@ export default class Default extends Balloon { const size = random(50, 75); const positionX = random(5, 95); const riseDuration = random( - this.riseDurationThreshold[0], - this.riseDurationThreshold[1] + this.options.riseDurationThreshold[0], + this.options.riseDurationThreshold[1] ); const waveDuration = random( - this.swingDurationThreshold[0], - this.swingDurationThreshold[1] + this.options.swingDurationThreshold[0], + this.options.swingDurationThreshold[1] ); // Load the pop sound From e98efd37d3393c88259e2f646e8a78772964636a Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Tue, 2 Jul 2024 21:24:54 +0200 Subject: [PATCH 022/100] Update confetti and gold options and name --- src/balloons/confetti.ts | 4 +++- src/balloons/gold.ts | 19 ++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/balloons/confetti.ts b/src/balloons/confetti.ts index 0efc4771..a05d4ddf 100644 --- a/src/balloons/confetti.ts +++ b/src/balloons/confetti.ts @@ -5,7 +5,9 @@ import Default from './default'; export default class Confetti extends Default { public static readonly spawn_chance: number = 0.1; // @ts-ignore - public readonly name = 'confetti'; + public get name(): 'confetti' { + return 'confetti'; + } private readonly mask = document.createElement('img'); diff --git a/src/balloons/gold.ts b/src/balloons/gold.ts index 2649db04..773b9bfd 100644 --- a/src/balloons/gold.ts +++ b/src/balloons/gold.ts @@ -1,16 +1,17 @@ -import Default from './default'; +import Default, { BalloonOptions } from './default'; export default class Gold extends Default { public static readonly spawn_chance: number = 0.05; // @ts-ignore - public readonly name = 'gold'; + public get name(): 'gold' { + return 'gold'; + } - constructor() { - super(); - this.options.imageUrl = `/../${this.name}/balloon.svg`; - this.riseDurationThreshold[0] = 15000; - this.riseDurationThreshold[1] = 20000; - this.swingDurationThreshold[0] = 3; - this.swingDurationThreshold[1] = 4; + public get options(): BalloonOptions { + return { + ...super.options, + riseDurationThreshold: [15000, 20000], + swingDurationThreshold: [3, 4], + }; } } From 8225bfe48fa8d59021406fcd74ea91aad0b29375 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Tue, 2 Jul 2024 21:38:45 +0200 Subject: [PATCH 023/100] Add balloon.originalPath function to make overriding the options easier --- src/balloons/default.ts | 18 ++++++++++++++++-- src/balloons/gold.ts | 1 + 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/balloons/default.ts b/src/balloons/default.ts index 60ce80b7..12190a69 100644 --- a/src/balloons/default.ts +++ b/src/balloons/default.ts @@ -57,14 +57,16 @@ export type BalloonOptions = { export default class Default extends Balloon { public static readonly spawn_chance: number = 0.9; + public get name(): 'default' { return 'default'; } + public get options(): BalloonOptions { return { dir_name: this.name, - imageUrl: '/icon.png', - popSoundUrl: '/pop.mp3', + imageUrl: this.originalPath('/icon.png'), + popSoundUrl: this.originalPath('/pop.mp3'), riseDurationThreshold: [10000, 15000], swingDurationThreshold: [2, 4], swingOffset: 15, @@ -106,6 +108,18 @@ export default class Default extends Balloon { importStylesheet('default-styles', this.resourceLocation + 'default.css'); } + /** + * Get the path for the resources of the default balloon. + * + * This should only be used in the balloon.options. + * + * @param path The path of the resource. + * @returns The original path of the resource. + */ + protected originalPath(path: string): string { + return '/../default' + path; + } + public build() { const size = random(50, 75); const positionX = random(5, 95); diff --git a/src/balloons/gold.ts b/src/balloons/gold.ts index 773b9bfd..d49df763 100644 --- a/src/balloons/gold.ts +++ b/src/balloons/gold.ts @@ -10,6 +10,7 @@ export default class Gold extends Default { public get options(): BalloonOptions { return { ...super.options, + imageUrl: '/balloon.svg', riseDurationThreshold: [15000, 20000], swingDurationThreshold: [3, 4], }; From 2d79e88d942a06ebe0506d41242344a32acf731a Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Fri, 5 Jul 2024 09:11:39 +0200 Subject: [PATCH 024/100] Add size option to default balloon close #249 --- src/balloons/default.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/balloons/default.ts b/src/balloons/default.ts index 12190a69..c7defa3f 100644 --- a/src/balloons/default.ts +++ b/src/balloons/default.ts @@ -31,6 +31,12 @@ export type BalloonOptions = { * If not provided, the default sound will be used. */ popSoundUrl: string; + /** + * The size of the balloon. + * + * The first value is the minimum size and the second value is the maximum size. + */ + size: [number, number]; /** * The duration thresholds for the rise animation. * @@ -67,6 +73,7 @@ export default class Default extends Balloon { dir_name: this.name, imageUrl: this.originalPath('/icon.png'), popSoundUrl: this.originalPath('/pop.mp3'), + size: [50, 75], riseDurationThreshold: [10000, 15000], swingDurationThreshold: [2, 4], swingOffset: 15, @@ -121,8 +128,8 @@ export default class Default extends Balloon { } public build() { - const size = random(50, 75); const positionX = random(5, 95); + const size = random(this.options.size[0], this.options.size[1]); const riseDuration = random( this.options.riseDurationThreshold[0], this.options.riseDurationThreshold[1] From 27fc2d072b6ae9cb721aba73bbfef15ec529e73c Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Fri, 5 Jul 2024 09:23:05 +0200 Subject: [PATCH 025/100] Slightly increase golden balloon size --- src/balloons/gold.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/balloons/gold.ts b/src/balloons/gold.ts index d49df763..c3d00ec8 100644 --- a/src/balloons/gold.ts +++ b/src/balloons/gold.ts @@ -1,7 +1,7 @@ import Default, { BalloonOptions } from './default'; export default class Gold extends Default { - public static readonly spawn_chance: number = 0.05; + public static readonly spawn_chance: number = 1.05; // @ts-ignore public get name(): 'gold' { return 'gold'; @@ -13,6 +13,7 @@ export default class Gold extends Default { imageUrl: '/balloon.svg', riseDurationThreshold: [15000, 20000], swingDurationThreshold: [3, 4], + size: [100, 125], }; } } From b168d885e7382533c947449b06ba49daabba7c08 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sat, 6 Jul 2024 12:18:58 +0200 Subject: [PATCH 026/100] Add a golden shine to golden balloon --- resources/balloons/gold/balloon.svg | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/resources/balloons/gold/balloon.svg b/resources/balloons/gold/balloon.svg index b0b303ce..aaf16a0c 100644 --- a/resources/balloons/gold/balloon.svg +++ b/resources/balloons/gold/balloon.svg @@ -6,6 +6,17 @@ + + + + + + + + + + + Date: Sun, 7 Jul 2024 21:17:27 +0200 Subject: [PATCH 027/100] Fix gold balloon spawn rate, again --- src/balloons/gold.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/balloons/gold.ts b/src/balloons/gold.ts index c3d00ec8..de632190 100644 --- a/src/balloons/gold.ts +++ b/src/balloons/gold.ts @@ -1,7 +1,7 @@ import Default, { BalloonOptions } from './default'; export default class Gold extends Default { - public static readonly spawn_chance: number = 1.05; + public static readonly spawn_chance: number = 0.05; // @ts-ignore public get name(): 'gold' { return 'gold'; From bc53ec0da7b35fcea6b308a698b7ea14f0686c06 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sun, 7 Jul 2024 22:10:51 +0200 Subject: [PATCH 028/100] Add golden balloon test --- tests/balloons/gold.test.ts | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 tests/balloons/gold.test.ts diff --git a/tests/balloons/gold.test.ts b/tests/balloons/gold.test.ts new file mode 100644 index 00000000..d7c378fb --- /dev/null +++ b/tests/balloons/gold.test.ts @@ -0,0 +1,23 @@ +import { Gold } from '@/balloons'; +import fetchMock from 'jest-fetch-mock'; + +fetchMock.enableMocks(); + +describe('Gold Balloon', () => { + let balloon: Gold; + + beforeEach(() => { + balloon = new Gold(); + + fetchMock.resetMocks(); + }); + + test('name should be "gold"', () => { + expect(balloon.name).toBe('gold'); + }); + + test('name should be the same as the class name', () => { + expect(balloon.name).toBe('gold'); + expect(balloon.name).toBe(Gold.name.toLowerCase()); + }); +}); From 92fbf14c105faa4c73d81d158547ed0a565a214c Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Mon, 8 Jul 2024 21:51:08 +0200 Subject: [PATCH 029/100] Replace default balloon image with svg #243 --- resources/balloons/default/balloon.svg | 52 +++++++++++++++++++++++++ resources/balloons/default/icon.png | Bin 3934 -> 0 bytes 2 files changed, 52 insertions(+) create mode 100644 resources/balloons/default/balloon.svg delete mode 100644 resources/balloons/default/icon.png diff --git a/resources/balloons/default/balloon.svg b/resources/balloons/default/balloon.svg new file mode 100644 index 00000000..a280a776 --- /dev/null +++ b/resources/balloons/default/balloon.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/balloons/default/icon.png b/resources/balloons/default/icon.png deleted file mode 100644 index 4d6e70dc7c98e44e71874db3b5e40d299bf161ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3934 zcmV-k525ghP)pF8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H14(mxo zK~#90?VWpc7UiACKfih3KoSUGqTI;^1(FB~D}vi~>!sexk%A~FgiEQXuy{Fjx9hQX zFK2hV-Bzt_t=p|gy9a>);sq#5i^sKf)zhjdl@b!V0tu)=Dqy%LdEfc%A8%fmc`sbw zH_yB?`J9t;c%GSe<~z)Hp8G{ql`evdWm-TNX6Z6O!09qT!09qTzzLfckZt6;>%yhY zgT{-+XjQ!oxD=tkD7_SV0|>OJa1dn=P$wdr(dee8hUnX>tDlcRmO5pb1N{XLW}U9`{2{m zslrEU%amQ)mc5&qJ9Zv9XMpnRnYXEGEl}W$FBF(x0`p3g!n6F^&y=GI3-`tTj%m_O zj;dPIcQq{iWp?hK9dgP5rPVX;5tS!NXuuj>06!j}RCMbc9Xs0K8=nZ9k0%|9g5KLy zzkFfmC^>&}#sH<2GvlQ(IDlT9;f+nI1J;*!j0EKc_|z`1V8#I>}<-Y#@`%)c^?UF?*Gc; zV%cA4tXr`uqc_Vio;JYXsyQVgA{&A7cw88GYB1c`^EA50kA*v@KygAV@TSf1#LqIW zb;Dt}=cA;QU?+K8(X_etK*n#FAw1g~C?XOjx(vt52Y7U#p8DnY=?xEl0~Xw!{PF>g z9?PuI4sPxV-ye{qtAchsT^8`H0m??y%_}6d4rIpFYY#aVq z2hXj}u+o!E?G0Z|_S~&yRWs*g?WX66C$oTxk<v7iqihrF))8F znm@0CqI*2RL4S zp~UL>X)#@LWpZxh!Dl zh*_5d)17hO>c7>h+VPY+mP6U};F|uZ~8AYk_lmSGn zd!6C2g>Ze(G$&tw4O9(x$E|r8e)mq6)SW#y^n@|4E-NHz>-~o0q{K4@7+f`{1h~@~ zcYkr3lZ%RA%0zcuT?71beRjm12ltgEqyj2;m0ebIu45E4j%N&DNn|#TF5c2^@Wmc! z^6-hbK##(c;p45aXtB{eKONWgfI;p8Y#|ZxOl`nB22gQ*{WX2SN|pEb?giIg?T%aX z5`5m0MRn&+NMg_8LUo!EF)8qb0fvm2Gf2^K@vtQ@rB|A-`TA?1o1^1@{{eXQw^>$r zeoX15BzSpzdG)LTX4JUxgaJaK=wuxI{A2Q=Z>lCL5%}xBbjPiK1tO;$y=j~Qd2m^Q z%g~l;^ed+HIPru5u=NIK@TQ_P=T%p_J9t`K;f>#AQCQ}iCpOnUsj;$d#HZ(D*WH}SP$Q8{|j~X*%z20!UCfb z<}5`b(Q&EI?mUe51`0CV`CW|47a&av(9#0m{Xu8Q$_k_M;T=aev5F2)e|G0!JO!{V zt#F1*)AjoKfFXJA%Ala-W|W-7xB*axI)i>TKxwyxluc!5>N7hJ;|8#hfzI&2#Q!88 zF*qRwz;Zvk35**+!By+;m9qWU9~6ZW%x!DBzRpg=xB&oH4Y|1DY`If<>?%&CcC-T=jVh2i0gAYZgq(GNuRVbhw7cLrIu>~t=-)70kQEC66$u`;iOf8xdEkD1m2UPuAZ zKRLr&TK$^>oIvd@rX|ENZU9TvHIrlWF%lP9@Eb~={kCZlaf};aXZ?!Cj&*o}SY7!~ zxiQM?TxnpHcNUd2ZU6vLbxr1b-FWjz77^YuEy0N=3}C}6&hUmq{woI@x8dERu<2On zHPc$0cw&W+(#q)rMXcR)7}65>{l!W@<8_qG&|<@+Mqy`cw}BRw(AB%PF7ZS`&=V=Z zu7(w#D4Zw^+6t==`X?1wcHqRz2k4DPyXFQaA*^x+Yd?<}A=im&>{(nSG=7=HGX_wr z{TUoRgS*<`^`iy_Wr){~NMiH$Q3=ZmLvoVvi~)9US+!qar8Dj)pXGiw@Ki#DPn8v3 zS~$`(1^`g_DUL}2?;nHzG2UNxer$Cw7pGyho-`ySC7v=sQ+@4wpzEA*k9`))M{||0 zxE8jQr*~{y`hh7esqmBm0Bo#(1Wxpv*B=-D`#|ny1>ftZJNl?SNo<+0t6|tZru8J^ ziFSZQ$|`G?Ak2z~3q*OPBDQQy?qT1|>XomY{yZ~yE(HJx<>`aKiFI9%sqjFv5b>T@ zPlGP@^2-O08eqpCmwyWKO=sMD$KX4Ab1ExnqTTvC(;`lXCk+6wtD$xY$ji>S#RuRy zZ>|NENGrD9!Ast$?xn-C22fSCLv6DGSF72#nuQIAJ)RPX-p|?84Rx zqV{w6=RK~iVw#%jYs-xZI!ipA0>o*oU;YBf-8fnaBfvw=!hihPOzogu;otWP-*&%z z1kx>W)0bU{A|ClXn$;kPvT*ayPE2ky_B81XNR0K0KkwD zHRCLc7l6Tu$NGlh-V$YM?-cX#&ymA6JomZqU;ANisv*nDZiL%neHpn$P8tAU$jE8M zRy4d2-6Sa(o)p+%DC^~F)1r5g*p)Wv%?vD*S=33=n7J$Z6dUN5d0UWfH;!pyV7c^%<~UVC{uHdam2JaiQ-f zulv#fPDG}K%B#9v8MSqcSTY4$zl0?2-_U`gSiGt>t3#G-YOHU2S9Mip_nY?^zBfRe z((0Lais~{PQ{v*fEjLYaIaOejuif)FB$gJ1$*8{l*=KTeQM;M+1l zM;G!+67u{XUjh@0Q$O>%{lWtuCYK3BWLo3aWvjC&*BHJ{0TiAf;iJBHVEUI2v11Dc zB^?i|+Mb%skx6_q0sGAO$tUoKBf^)9VSJI&zhjtrb1S@k2-fcx-Z*GhV`t-M11tcR z0Vn3>DDZkq?2j}}0Vz1xaV=ls+bp1|e)&2Ps}f=Dxn4t%Ux!2CQBC#B*PZ_C+{Cwq zKqo^gXWSyfLxNm;hClg@!XvxtYd2(5mlp_x0pgTa&mJk*6HvVwBfL45fT zPy>W5D`C|hxx|bT^90fWZG}BH;~rjKRZ%s)+>jij1kwN>Z(Mj3!MX3e*o3AV6J(G; z8UR3TmM28rYD9=(0&4)vvew|*rCP^TjG5cVm>@$0)&PxLmo@{=ekafdu+e=9QN2>0=wkwH zfDqzZRX`ypS0X$g0&M_P@|{5o{JmRI3Ic6_sM@X-hBP+%Cr||109Xulg~h#%Z4d~w z0YtUR9cH^JEv5*x0YJXs45_H6mU8b50&9Ts${E)KmpY>CaBJk9bm#k(z#2dk7Nb^S z!}jf~a$_ap3=&8K3>`J2AHvPfIF0fzhU6F}kOr_L)|YTBI}5zOds}Vbl79%O0aSFH zJIs1hT1*p21EB6+Kd~inrT;j=Gyq)S42VQOF(t$_K{bG@)5o?$zFYn4ObMm|)ZOMU zAv Date: Mon, 8 Jul 2024 21:55:12 +0200 Subject: [PATCH 030/100] Update default balloon image url close #243 --- src/balloons/default.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/balloons/default.ts b/src/balloons/default.ts index c7defa3f..7248cf22 100644 --- a/src/balloons/default.ts +++ b/src/balloons/default.ts @@ -71,7 +71,7 @@ export default class Default extends Balloon { public get options(): BalloonOptions { return { dir_name: this.name, - imageUrl: this.originalPath('/icon.png'), + imageUrl: this.originalPath('/balloon.svg'), popSoundUrl: this.originalPath('/pop.mp3'), size: [50, 75], riseDurationThreshold: [10000, 15000], From 288b0b438e55192a300803b7de5cb580f5070ae4 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Mon, 8 Jul 2024 22:00:30 +0200 Subject: [PATCH 031/100] revert balloon color back to original colors --- resources/balloons/default/balloon.svg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/balloons/default/balloon.svg b/resources/balloons/default/balloon.svg index a280a776..24090317 100644 --- a/resources/balloons/default/balloon.svg +++ b/resources/balloons/default/balloon.svg @@ -12,7 +12,7 @@ - + Date: Tue, 9 Jul 2024 20:50:57 +0200 Subject: [PATCH 032/100] Add pull request templates close #254 --- .github/PULL_REQUEST_TEMPLATE/bug_fixed.md | 15 +++++++++++++++ .github/PULL_REQUEST_TEMPLATE/feature_added.md | 15 +++++++++++++++ .github/PULL_REQUEST_TEMPLATE/new_balloon.md | 16 ++++++++++++++++ .github/PULL_REQUEST_TEMPLATE/new_release.md | 14 ++++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE/bug_fixed.md create mode 100644 .github/PULL_REQUEST_TEMPLATE/feature_added.md create mode 100644 .github/PULL_REQUEST_TEMPLATE/new_balloon.md create mode 100644 .github/PULL_REQUEST_TEMPLATE/new_release.md diff --git a/.github/PULL_REQUEST_TEMPLATE/bug_fixed.md b/.github/PULL_REQUEST_TEMPLATE/bug_fixed.md new file mode 100644 index 00000000..4cc2a8a3 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/bug_fixed.md @@ -0,0 +1,15 @@ +--- +name: Bug fixed +about: Fixed a bug +title: '' +labels: '' +assignees: '' +--- + +**Describe the pull request** +Describe what bug was fixed in this pr. + +### Checklist + +- [ ] Reference the related issues +- [ ] Update documentation (if applicable) diff --git a/.github/PULL_REQUEST_TEMPLATE/feature_added.md b/.github/PULL_REQUEST_TEMPLATE/feature_added.md new file mode 100644 index 00000000..0b49093c --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/feature_added.md @@ -0,0 +1,15 @@ +--- +name: Feature added +about: Implemented a new feature +title: '' +labels: '' +assignees: '' +--- + +**Describe the pull request** +Describe what feature was added in this pr. + +### Checklist + +- [ ] Reference the related issues +- [ ] Add documentation diff --git a/.github/PULL_REQUEST_TEMPLATE/new_balloon.md b/.github/PULL_REQUEST_TEMPLATE/new_balloon.md new file mode 100644 index 00000000..95e4b4a7 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/new_balloon.md @@ -0,0 +1,16 @@ +--- +name: New balloon +about: Add a new balloon +title: '' +labels: '' +assignees: '' +--- + +**Describe the pull request** +Describe the added balloon in this pr. + +### Checklist + +- [ ] Reference the related issues +- [ ] Balloon documentation updated +- [ ] Test file added for balloon diff --git a/.github/PULL_REQUEST_TEMPLATE/new_release.md b/.github/PULL_REQUEST_TEMPLATE/new_release.md new file mode 100644 index 00000000..477dc5fc --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/new_release.md @@ -0,0 +1,14 @@ +--- +name: New release +about: Publish a new release +title: vx.x.x update +labels: '' +assignees: '' +--- + +**Describe the pull request** +Describe the release. + +### Checklist + +- [ ] Updated [package.json](/package.json) and [package-lock.json](/package-lock.json) version From adfc6e5d8a18f21dccb09dfdc86d8c3c28bf3ace Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Wed, 10 Jul 2024 19:49:47 +0200 Subject: [PATCH 033/100] Add isFullScreenVideoPlaying utility function #194 --- src/utils.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/utils.ts b/src/utils.ts index 166e9a50..0713bc94 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -139,3 +139,24 @@ export async function askOriginPermissions() { }); log.debug('Permissions granted for', permissions); } + +export const isFullScreenVideoPlaying = () => { + const fullscreenElement = document.fullscreenElement; + if (fullscreenElement) { + if (fullscreenElement.tagName.toLowerCase() === 'video') { + return true; + } + const videos = fullscreenElement.getElementsByTagName('video'); + if (videos.length > 0) { + return true; + } + } + + const videos = document.getElementsByTagName('video'); + for (let video of videos) { + const rect = video.getBoundingClientRect(); + if (rect.width === window.innerWidth) { + return true; + } + } +}; From df0def9aed1a6d7b9c03558d402879138e5cbeba Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Wed, 10 Jul 2024 19:54:44 +0200 Subject: [PATCH 034/100] Prevent balloon spawn during full screen video playback #194 --- src/content/spawn-balloon.ts | 14 +++++++++++++- src/utils.ts | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/content/spawn-balloon.ts b/src/content/spawn-balloon.ts index fd97baf5..49be7e29 100644 --- a/src/content/spawn-balloon.ts +++ b/src/content/spawn-balloon.ts @@ -1,12 +1,24 @@ import browser from 'webextension-polyfill'; import * as balloons from '@/balloons'; -import { getBalloonContainer, importStylesheet, weightedRandom } from '@/utils'; +import { + getBalloonContainer, + importStylesheet, + isFullScreenVideoPlaying, + weightedRandom, +} from '@/utils'; import log from '@/managers/log'; import storage from '@/managers/storage'; (async () => { // Prevent running in popup if (document.body.id === 'pop-a-loon') return; + + // Run checks to see if the balloon should spawn + if (isFullScreenVideoPlaying()) { + log.debug('Full screen video playing, not spawning balloon'); + return; + } + log.setLevel((await storage.local.get('loglevel')) || 'info'); log.groupCollapsed('debug', 'Pop-a-loon: Spawning balloon'); log.time('debug', 'Balloon spawn time'); diff --git a/src/utils.ts b/src/utils.ts index 0713bc94..2a18caaf 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -159,4 +159,5 @@ export const isFullScreenVideoPlaying = () => { return true; } } + return false; }; From 32feabcf5cd37c181544ba5b17f95118d490f8de Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Wed, 10 Jul 2024 20:06:04 +0200 Subject: [PATCH 035/100] Only check in full screen #194 --- src/utils.ts | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index 2a18caaf..5f5b2b37 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -146,18 +146,13 @@ export const isFullScreenVideoPlaying = () => { if (fullscreenElement.tagName.toLowerCase() === 'video') { return true; } - const videos = fullscreenElement.getElementsByTagName('video'); + const videos = [ + ...fullscreenElement.getElementsByTagName('video'), + ...document.getElementsByTagName('video'), + ]; if (videos.length > 0) { return true; } } - - const videos = document.getElementsByTagName('video'); - for (let video of videos) { - const rect = video.getBoundingClientRect(); - if (rect.width === window.innerWidth) { - return true; - } - } return false; }; From a78bc969506f542dcf76ccddf8d8ab7e98a32b67 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Wed, 10 Jul 2024 20:14:53 +0200 Subject: [PATCH 036/100] Add storage option to enable full screen video balloon spawns --- src/const.ts | 2 ++ src/content/spawn-balloon.ts | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/const.ts b/src/const.ts index 0177b0d1..23f2b9c7 100644 --- a/src/const.ts +++ b/src/const.ts @@ -8,12 +8,14 @@ import * as Balloons from '@/balloons'; type _initialConfig = { popVolume: number; spawnRate: number; + fullScreenVideoSpawn: boolean; } & RemoteConfig; export const initalConfig: _initialConfig = { // Local config popVolume: 70, spawnRate: 1, + fullScreenVideoSpawn: false, // Remote config -> can be overriden by the remote badge: { diff --git a/src/content/spawn-balloon.ts b/src/content/spawn-balloon.ts index 49be7e29..5f08109f 100644 --- a/src/content/spawn-balloon.ts +++ b/src/content/spawn-balloon.ts @@ -13,8 +13,10 @@ import storage from '@/managers/storage'; // Prevent running in popup if (document.body.id === 'pop-a-loon') return; + const config = await storage.sync.get('config'); + // Run checks to see if the balloon should spawn - if (isFullScreenVideoPlaying()) { + if (!config.fullScreenVideoSpawn && isFullScreenVideoPlaying()) { log.debug('Full screen video playing, not spawning balloon'); return; } From ad5e847d8d46f6249dbf34821b34f668673ccd1a Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Wed, 10 Jul 2024 20:44:32 +0200 Subject: [PATCH 037/100] Add option to popup to enable full screen video spawns #194 --- src/popup/components/forms/LocalSettings.tsx | 53 ++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/popup/components/forms/LocalSettings.tsx b/src/popup/components/forms/LocalSettings.tsx index b327143f..c354b33d 100644 --- a/src/popup/components/forms/LocalSettings.tsx +++ b/src/popup/components/forms/LocalSettings.tsx @@ -3,6 +3,7 @@ import browser, { manifest, type Permissions } from 'webextension-polyfill'; import { useForm } from 'react-hook-form'; import { z } from 'zod'; import { Button } from '@/components/ui/button'; +import { Checkbox } from '@/components/ui/checkbox'; import { Form, FormField, @@ -28,6 +29,7 @@ const SPAWN_RATE_STEP = 0.1; const formSchema = z.object({ popVolume: z.number().int().min(MIN_POP_VOLUME).max(MAX_POP_VOLUME), spawnRate: z.number().int().min(MIN_SPAWN_RATE).max(MAX_SPAWN_RATE), + fullScreenVideoSpawn: z.boolean(), permissions: z.object({ origins: z.array(z.string()), permissions: z.array(z.string()), @@ -37,6 +39,7 @@ const formSchema = z.object({ export default () => { const [popVolume, setPopVolume] = useState(0); const [spawnRate, setSpawnRate] = useState(0); + const [fullScreenVideoSpawn, setFullScreenVideoSpawn] = useState(false); const [permissions, setPermissions] = useState( {} ); @@ -77,6 +80,23 @@ export default () => { ); }; + const onFullScreenVideoSpawnChange = async ( + fullScreenVideoSpawn: boolean + ) => { + // Save volume to storage + const config = await storage.sync.get('config'); + await storage.sync.set('config', { + ...config, + fullScreenVideoSpawn, + }); + + setFullScreenVideoSpawn(fullScreenVideoSpawn); + log.debug( + 'Spawning in full screen video players:', + (await storage.sync.get('config')).fullScreenVideoSpawn + ); + }; + const onGrantOriginPermissionClick = async () => { await askOriginPermissions(); setPermissions(await browser.permissions.getAll()); @@ -88,6 +108,7 @@ export default () => { // Load volume from storage setPopVolume(config.popVolume); setSpawnRate(config.spawnRate); + setFullScreenVideoSpawn(config.fullScreenVideoSpawn); setPermissions(await browser.permissions.getAll()); }; @@ -168,6 +189,38 @@ export default () => { )} /> + ( + + + Fullscreen video spawn + + + { + onChange(val); + onFullScreenVideoSpawnChange(!!val); + }} + /> + + +

+ Fullscreen video spawn +

+

+ Weither or not to spawn balloons in fullscreen video + players, like youtube. +

+
+
+
+ +
+ )} + /> {/* If the user hasn't granted the host permissions; show the grant permission button */} {!(permissions.origins?.length !== 0) && ( Date: Wed, 10 Jul 2024 20:47:31 +0200 Subject: [PATCH 038/100] Update LocalSettings form initial values to use initalConfig constants --- src/popup/components/forms/LocalSettings.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/popup/components/forms/LocalSettings.tsx b/src/popup/components/forms/LocalSettings.tsx index c354b33d..8981926d 100644 --- a/src/popup/components/forms/LocalSettings.tsx +++ b/src/popup/components/forms/LocalSettings.tsx @@ -18,6 +18,7 @@ import { Default as DefaultBalloon } from '@/balloons'; import storage from '@/managers/storage'; import log from '@/managers/log'; import { askOriginPermissions } from '@/utils'; +import { initalConfig } from '@/const'; const MIN_POP_VOLUME = 0; const VOLUME_STEP = 20; @@ -37,9 +38,11 @@ const formSchema = z.object({ }); export default () => { - const [popVolume, setPopVolume] = useState(0); - const [spawnRate, setSpawnRate] = useState(0); - const [fullScreenVideoSpawn, setFullScreenVideoSpawn] = useState(false); + const [popVolume, setPopVolume] = useState(initalConfig.popVolume); + const [spawnRate, setSpawnRate] = useState(initalConfig.spawnRate); + const [fullScreenVideoSpawn, setFullScreenVideoSpawn] = useState( + initalConfig.fullScreenVideoSpawn + ); const [permissions, setPermissions] = useState( {} ); From f68840a3948df89edaad8b4262194bc89069b594 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Thu, 11 Jul 2024 11:36:43 +0200 Subject: [PATCH 039/100] Fix tailwind animations plugin close #257 --- tailwind.config.js | 67 +++++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 27 deletions(-) diff --git a/tailwind.config.js b/tailwind.config.js index cb89bead..81fbbb35 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,50 +1,63 @@ /** @type {import('tailwindcss').Config} */ module.exports = { - content: ["./src/**/*.{html,tsx,jsx,ts,js}"], + content: ['./src/**/*.{html,tsx,jsx,ts,js}'], theme: { extend: { colors: { - border: "var(--border)", - input: "var(--input)", - ring: "var(--ring)", - background: "var(--background)", - foreground: "var(--foreground)", + border: 'var(--border)', + input: 'var(--input)', + ring: 'var(--ring)', + background: 'var(--background)', + foreground: 'var(--foreground)', primary: { - DEFAULT: "var(--primary)", - foreground: "var(--primary-foreground)", + DEFAULT: 'var(--primary)', + foreground: 'var(--primary-foreground)', }, secondary: { - DEFAULT: "var(--secondary)", - foreground: "var(--secondary-foreground)", + DEFAULT: 'var(--secondary)', + foreground: 'var(--secondary-foreground)', }, destructive: { - DEFAULT: "var(--destructive)", - foreground: "var(--destructive-foreground)", + DEFAULT: 'var(--destructive)', + foreground: 'var(--destructive-foreground)', }, muted: { - DEFAULT: "var(--muted)", - foreground: "var(--muted-foreground)", + DEFAULT: 'var(--muted)', + foreground: 'var(--muted-foreground)', }, accent: { - DEFAULT: "var(--accent)", - foreground: "var(--accent-foreground)", + DEFAULT: 'var(--accent)', + foreground: 'var(--accent-foreground)', }, popover: { - DEFAULT: "var(--popover)", - foreground: "var(--popover-foreground)", + DEFAULT: 'var(--popover)', + foreground: 'var(--popover-foreground)', }, card: { - DEFAULT: "var(--card)", - foreground: "var(--card-foreground)", + DEFAULT: 'var(--card)', + foreground: 'var(--card-foreground)', }, }, borderRadius: { - lg: "var(--radius)", - md: "calc(var(--radius) - 2px)", - sm: "calc(var(--radius) - 4px)", - } + lg: 'var(--radius)', + md: 'calc(var(--radius) - 2px)', + sm: 'calc(var(--radius) - 4px)', + }, + keyframes: { + 'accordion-down': { + from: { height: '0' }, + to: { height: 'var(--radix-accordion-content-height)' }, + }, + 'accordion-up': { + from: { height: 'var(--radix-accordion-content-height)' }, + to: { height: '0' }, + }, + }, + animation: { + 'accordion-down': 'accordion-down 0.2s ease-out', + 'accordion-up': 'accordion-up 0.2s ease-out', + }, }, }, - plugins: [], -} - + plugins: [require('tailwindcss-animate')], +}; From 20ea06cea13f6768e9d95b21f671ff8b9def4f25 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Fri, 12 Jul 2024 19:52:12 +0200 Subject: [PATCH 040/100] Add some helper text to popover to indicate if balloons will spawn or not --- src/popup/components/forms/LocalSettings.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/popup/components/forms/LocalSettings.tsx b/src/popup/components/forms/LocalSettings.tsx index 8981926d..d103415d 100644 --- a/src/popup/components/forms/LocalSettings.tsx +++ b/src/popup/components/forms/LocalSettings.tsx @@ -217,6 +217,13 @@ export default () => { Weither or not to spawn balloons in fullscreen video players, like youtube.

+

+ {fullScreenVideoSpawn ? ( + <>Balloons can spawn! + ) : ( + <>Balloons will not spawn. + )} +

From 360b4d809acba92f3894cf314b769169a9163cca Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sat, 13 Jul 2024 23:08:47 +0200 Subject: [PATCH 041/100] Add importStylesheet method in balloon class #260 --- src/balloon.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/balloon.ts b/src/balloon.ts index 4fcf8ee6..f8a46c18 100644 --- a/src/balloon.ts +++ b/src/balloon.ts @@ -1,5 +1,5 @@ import browser from 'webextension-polyfill'; -import { getBalloonContainer, sendMessage } from '@/utils'; +import { getBalloonContainer, importStylesheet, sendMessage } from '@/utils'; import { BalloonName } from './const'; /** @@ -40,6 +40,10 @@ export default abstract class Balloon { this.element.addEventListener('click', this.pop.bind(this)); } + protected async importStylesheet(name: string): Promise { + await importStylesheet(`${this.name}-styles`, this.resourceLocation + name); + } + /** * @returns Whether the balloon is rising. */ From 01b9cf3956304357aa0b0e21bbd6b1579918fce8 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sat, 13 Jul 2024 23:09:14 +0200 Subject: [PATCH 042/100] Use new importStylesheet in balloons subclasses #260 --- src/balloons/confetti.ts | 10 ++-------- src/balloons/default.ts | 7 ++----- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/balloons/confetti.ts b/src/balloons/confetti.ts index a05d4ddf..84eb9db6 100644 --- a/src/balloons/confetti.ts +++ b/src/balloons/confetti.ts @@ -11,16 +11,10 @@ export default class Confetti extends Default { private readonly mask = document.createElement('img'); - constructor() { - super(); - importStylesheet( - 'confetti-styles', - balloonResourceLocation + 'confetti/confetti.css' - ); - } - public build(): void { super.build(); + this.importStylesheet('confetti.css'); + this.element.firstChild?.firstChild?.appendChild(this.mask); this.mask.src = balloonResourceLocation + this.name + '/mask.png'; this.mask.style.position = 'absolute'; diff --git a/src/balloons/default.ts b/src/balloons/default.ts index 7248cf22..3aee7ae2 100644 --- a/src/balloons/default.ts +++ b/src/balloons/default.ts @@ -110,11 +110,6 @@ export default class Default extends Balloon { ); } - constructor() { - super(); - importStylesheet('default-styles', this.resourceLocation + 'default.css'); - } - /** * Get the path for the resources of the default balloon. * @@ -128,6 +123,8 @@ export default class Default extends Balloon { } public build() { + this.importStylesheet('default.css'); + const positionX = random(5, 95); const size = random(this.options.size[0], this.options.size[1]); const riseDuration = random( From 5fdfda6533e7bd86c43d4d0a19aba1922c0519e7 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sat, 13 Jul 2024 23:39:15 +0200 Subject: [PATCH 043/100] Remove unused imports --- src/balloons/confetti.ts | 2 +- src/balloons/default.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/balloons/confetti.ts b/src/balloons/confetti.ts index 84eb9db6..9641c1a2 100644 --- a/src/balloons/confetti.ts +++ b/src/balloons/confetti.ts @@ -1,5 +1,5 @@ import { balloonResourceLocation } from '@/balloon'; -import { importStylesheet, random } from '@/utils'; +import { random } from '@/utils'; import Default from './default'; export default class Confetti extends Default { diff --git a/src/balloons/default.ts b/src/balloons/default.ts index 3aee7ae2..3923632f 100644 --- a/src/balloons/default.ts +++ b/src/balloons/default.ts @@ -1,7 +1,7 @@ import Balloon, { balloonResourceLocation } from '@/balloon'; import storage from '@/managers/storage'; import { BalloonName } from '@/const'; -import { importStylesheet, random } from '@/utils'; +import { random } from '@/utils'; export type BuildProps = { size: number; From 5f162787838217656f3dac2ac8bc12012f7da89a Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sun, 14 Jul 2024 00:16:34 +0200 Subject: [PATCH 044/100] Add joinPaths function #261 --- src/utils.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/utils.ts b/src/utils.ts index 5f5b2b37..4155a127 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -156,3 +156,16 @@ export const isFullScreenVideoPlaying = () => { } return false; }; + +export const joinPaths = (...paths: string[]): string => { + return paths + .map((part, index) => { + if (index === 0) { + return part.trim().replace(/[/]*$/g, ''); + } else { + return part.trim().replace(/(^[/]*|[/]*$)/g, ''); + } + }) + .filter((part) => part.length) + .join('/'); +}; From 480ef24dd8c0cff4f77f6a996caeaf90046bc57c Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sun, 14 Jul 2024 00:18:37 +0200 Subject: [PATCH 045/100] Use joinPaths to join all paths close #261 --- src/balloon.ts | 22 ++++++++++++++++------ src/balloons/confetti.ts | 4 ++-- src/balloons/default.ts | 18 +++++++++++------- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/src/balloon.ts b/src/balloon.ts index f8a46c18..8e40e42e 100644 --- a/src/balloon.ts +++ b/src/balloon.ts @@ -1,19 +1,26 @@ import browser from 'webextension-polyfill'; -import { getBalloonContainer, importStylesheet, sendMessage } from '@/utils'; +import { + getBalloonContainer, + importStylesheet, + joinPaths, + sendMessage, +} from '@/utils'; import { BalloonName } from './const'; /** * The location of the balloon resources. (`resources/balloons/`) */ export const balloonResourceLocation = browser.runtime.getURL( - 'resources/balloons/' + joinPaths('resources', 'balloons') ); export const defaultBalloonFolderName = 'default'; /** * The location of the default balloon resources. (`resources/balloons/default/`) */ -export const defaultBalloonResourceLocation = - balloonResourceLocation + `${defaultBalloonFolderName}/`; +export const defaultBalloonResourceLocation = joinPaths( + balloonResourceLocation, + defaultBalloonFolderName +); export default abstract class Balloon { public abstract readonly name: BalloonName; @@ -32,7 +39,7 @@ export default abstract class Balloon { public readonly element: HTMLDivElement = document.createElement('div'); public get resourceLocation(): string { - return balloonResourceLocation + this.name + '/'; + return joinPaths(balloonResourceLocation, this.name); } constructor() { @@ -41,7 +48,10 @@ export default abstract class Balloon { } protected async importStylesheet(name: string): Promise { - await importStylesheet(`${this.name}-styles`, this.resourceLocation + name); + await importStylesheet( + `${this.name}-styles`, + joinPaths(this.resourceLocation, name) + ); } /** diff --git a/src/balloons/confetti.ts b/src/balloons/confetti.ts index 9641c1a2..2a811cec 100644 --- a/src/balloons/confetti.ts +++ b/src/balloons/confetti.ts @@ -1,5 +1,5 @@ import { balloonResourceLocation } from '@/balloon'; -import { random } from '@/utils'; +import { joinPaths, random } from '@/utils'; import Default from './default'; export default class Confetti extends Default { @@ -16,7 +16,7 @@ export default class Confetti extends Default { this.importStylesheet('confetti.css'); this.element.firstChild?.firstChild?.appendChild(this.mask); - this.mask.src = balloonResourceLocation + this.name + '/mask.png'; + this.mask.src = joinPaths(balloonResourceLocation, this.name, 'mask.png'); this.mask.style.position = 'absolute'; this.mask.style.top = '-10px'; this.mask.style.left = '0'; diff --git a/src/balloons/default.ts b/src/balloons/default.ts index 3923632f..c5f767e8 100644 --- a/src/balloons/default.ts +++ b/src/balloons/default.ts @@ -1,7 +1,7 @@ import Balloon, { balloonResourceLocation } from '@/balloon'; import storage from '@/managers/storage'; import { BalloonName } from '@/const'; -import { random } from '@/utils'; +import { joinPaths, random } from '@/utils'; export type BuildProps = { size: number; @@ -96,8 +96,10 @@ export default class Default extends Balloon { * The URL of the balloon image. */ public get balloonImageUrl(): string { - return ( - balloonResourceLocation + this.options.dir_name + this.options.imageUrl + return joinPaths( + balloonResourceLocation, + this.options.dir_name, + this.options.imageUrl ); } @@ -105,8 +107,10 @@ export default class Default extends Balloon { * The URL of the pop sound. */ public get popSoundUrl(): string { - return ( - balloonResourceLocation + this.options.dir_name + this.options.popSoundUrl + return joinPaths( + balloonResourceLocation, + this.options.dir_name, + this.options.popSoundUrl ); } @@ -118,8 +122,8 @@ export default class Default extends Balloon { * @param path The path of the resource. * @returns The original path of the resource. */ - protected originalPath(path: string): string { - return '/../default' + path; + protected originalPath(name: string): string { + return joinPaths('..', 'default', name); } public build() { From b3fc0e710f3c0fbe178183110841788dba905afb Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sun, 14 Jul 2024 00:22:06 +0200 Subject: [PATCH 046/100] Update importStylesheet method in balloons subclasses to use originalPath for default.css --- src/balloons/default.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/balloons/default.ts b/src/balloons/default.ts index c5f767e8..76ab8a48 100644 --- a/src/balloons/default.ts +++ b/src/balloons/default.ts @@ -127,7 +127,7 @@ export default class Default extends Balloon { } public build() { - this.importStylesheet('default.css'); + this.importStylesheet(this.originalPath('default.css')); const positionX = random(5, 95); const size = random(this.options.size[0], this.options.size[1]); From 03623c6b8010113cc8f6a35f73517a8cbd8071bd Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sun, 14 Jul 2024 00:26:13 +0200 Subject: [PATCH 047/100] Import styles in abstract rise function instead of in content script --- src/balloon.ts | 5 +++++ src/content/spawn-balloon.ts | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/balloon.ts b/src/balloon.ts index 8e40e42e..ca6c3f57 100644 --- a/src/balloon.ts +++ b/src/balloon.ts @@ -67,6 +67,11 @@ export default abstract class Balloon { * This will create a new balloon element and add it to the balloon container. */ public rise(): void { + // Import base styles + importStylesheet( + 'balloon-styles', + browser.runtime.getURL('resources/stylesheets/style.css') + ); // Build the balloon element this.build(); // Add the balloon to the container diff --git a/src/content/spawn-balloon.ts b/src/content/spawn-balloon.ts index 5f08109f..485933eb 100644 --- a/src/content/spawn-balloon.ts +++ b/src/content/spawn-balloon.ts @@ -25,11 +25,6 @@ import storage from '@/managers/storage'; log.groupCollapsed('debug', 'Pop-a-loon: Spawning balloon'); log.time('debug', 'Balloon spawn time'); - importStylesheet( - 'balloon-styles', - browser.runtime.getURL('resources/stylesheets/style.css') - ); - // Add the balloon container to the document const _ = getBalloonContainer(); From 771224d0c6e35e76dedf76e344b5702072f1c4c5 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sun, 14 Jul 2024 00:27:36 +0200 Subject: [PATCH 048/100] Move default balloon styles to default balloon styles file --- resources/balloons/default/default.css | 17 +++++++++++++++++ src/content/style.css | 17 ----------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/resources/balloons/default/default.css b/resources/balloons/default/default.css index f0cb0024..e00d707c 100644 --- a/resources/balloons/default/default.css +++ b/resources/balloons/default/default.css @@ -1,3 +1,20 @@ +.balloon { + position: fixed; + z-index: 9999; + cursor: pointer; + top: 0; + + /* Make image not dragable and not selectable */ + user-drag: none; + -webkit-user-drag: none; + user-select: none; + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + + pointer-events: auto; +} + .balloon img { width: 100%; height: 100%; diff --git a/src/content/style.css b/src/content/style.css index ff4cbfc5..383ffc57 100644 --- a/src/content/style.css +++ b/src/content/style.css @@ -7,20 +7,3 @@ left: 0; pointer-events: none; } - -.balloon { - position: fixed; - z-index: 9999; - cursor: pointer; - top: 0; - - /* Make image not dragable and not selectable */ - user-drag: none; - -webkit-user-drag: none; - user-select: none; - -moz-user-select: none; - -webkit-user-select: none; - -ms-user-select: none; - - pointer-events: auto; -} From f05e82ad2c8427a776ea5e11207f428693ffb23e Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sun, 14 Jul 2024 00:43:25 +0200 Subject: [PATCH 049/100] Exclude stylesheets from being copied to dist folder --- webpack.config.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/webpack.config.js b/webpack.config.js index 49299f54..094f959b 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -82,14 +82,6 @@ module.exports = { patterns: [ // Copy resource files to dist { from: 'resources/', to: 'resources/' }, - // Copy sylesheets to dist but exclude stylesheets from popup folder - { - from: 'src/**/*.css', - globOptions: { - ignore: ['**/popup/**'], - }, - to: 'resources/stylesheets/[name][ext]', - }, // Copy manifest.json to dist { from: `manifest.json`, From 84e366b17bf6c6b86a31757e4916a8596c26a6b8 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sun, 14 Jul 2024 00:43:54 +0200 Subject: [PATCH 050/100] Move base stylesheet --- src/content/style.css => resources/balloons/base-styles.css | 0 src/balloon.ts | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename src/content/style.css => resources/balloons/base-styles.css (100%) diff --git a/src/content/style.css b/resources/balloons/base-styles.css similarity index 100% rename from src/content/style.css rename to resources/balloons/base-styles.css diff --git a/src/balloon.ts b/src/balloon.ts index ca6c3f57..0c22172d 100644 --- a/src/balloon.ts +++ b/src/balloon.ts @@ -70,7 +70,7 @@ export default abstract class Balloon { // Import base styles importStylesheet( 'balloon-styles', - browser.runtime.getURL('resources/stylesheets/style.css') + joinPaths('resources', 'balloons', 'base-styles.css') ); // Build the balloon element this.build(); From 5b2ac9dca3b94ca99588231dac3e6a1517351529 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sun, 14 Jul 2024 11:10:48 +0200 Subject: [PATCH 051/100] Add prettier-plugin-sort-imports 1.8.6 #262 --- package-lock.json | 21 +++++++++++++++++---- package.json | 3 ++- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 686404af..2e89f942 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55,7 +55,8 @@ "mini-css-extract-plugin": "^2.9.0", "mkdirp": "^3.0.1", "postcss": "^8.4.33", - "prettier": "^3.3.2", + "prettier": "^3.3.3", + "prettier-plugin-sort-imports": "^1.8.6", "prettier-plugin-tailwindcss": "^0.5.14", "rimraf": "^5.0.5", "style-loader": "^3.3.4", @@ -8143,9 +8144,9 @@ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, "node_modules/prettier": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", - "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -8157,6 +8158,18 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/prettier-plugin-sort-imports": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-1.8.6.tgz", + "integrity": "sha512-jOEzFCyvdDL8geCmr4DP/VBKULZ6OaDQHBEmHTuFHf4EzWyedmwnHg2KawNy5rnrQ6gnCqwrfgymMQZctzCE1Q==", + "dev": true, + "dependencies": { + "prettier": "^3.1.1" + }, + "peerDependencies": { + "typescript": ">4.0.0" + } + }, "node_modules/prettier-plugin-tailwindcss": { "version": "0.5.14", "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.5.14.tgz", diff --git a/package.json b/package.json index 42092745..0eb78233 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,8 @@ "mini-css-extract-plugin": "^2.9.0", "mkdirp": "^3.0.1", "postcss": "^8.4.33", - "prettier": "^3.3.2", + "prettier": "^3.3.3", + "prettier-plugin-sort-imports": "^1.8.6", "prettier-plugin-tailwindcss": "^0.5.14", "rimraf": "^5.0.5", "style-loader": "^3.3.4", From 4d3e1f076d453044e97239ff9f61159fd4cc47a9 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sun, 14 Jul 2024 11:34:23 +0200 Subject: [PATCH 052/100] Use prettier-plugin-sort-imports and set configuration close #262 --- .prettierrc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.prettierrc b/.prettierrc index 02847ae9..a946b9bf 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,10 +1,14 @@ { - "plugins": ["prettier-plugin-tailwindcss"], + "plugins": ["prettier-plugin-tailwindcss", "prettier-plugin-sort-imports"], "semi": true, "singleQuote": true, "printWidth": 80, "tabWidth": 2, "useTabs": false, "endOfLine": "lf", - "trailingComma": "es5" + "trailingComma": "es5", + "sortingMethod": "alphabetical", + "stripNewlines": true, + "newlineBetweenTypes": false, + "importTypeOrder": ["NPMPackages", "localImportsType", "localImportsValue"] } From 538e8404d8ee8f7acbc5b00e5c049cb369107b42 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sun, 14 Jul 2024 13:10:47 +0200 Subject: [PATCH 053/100] Add default string to importStylesheet function close #260 --- src/balloon.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/balloon.ts b/src/balloon.ts index 0c22172d..12ba391c 100644 --- a/src/balloon.ts +++ b/src/balloon.ts @@ -47,7 +47,7 @@ export default abstract class Balloon { this.element.addEventListener('click', this.pop.bind(this)); } - protected async importStylesheet(name: string): Promise { + protected async importStylesheet(name: string = 'style.css'): Promise { await importStylesheet( `${this.name}-styles`, joinPaths(this.resourceLocation, name) From a8758ba8df4cb391b8e026cbdb36ecac32b97c5c Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sun, 14 Jul 2024 14:08:05 +0200 Subject: [PATCH 054/100] Refactor importStylesheet method in Balloon class to add overload with id argument --- src/balloon.ts | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/balloon.ts b/src/balloon.ts index 12ba391c..85169354 100644 --- a/src/balloon.ts +++ b/src/balloon.ts @@ -22,6 +22,11 @@ export const defaultBalloonResourceLocation = joinPaths( defaultBalloonFolderName ); +type StyleSheetProps = { + id?: string; + name?: string; +}; + export default abstract class Balloon { public abstract readonly name: BalloonName; @@ -47,10 +52,19 @@ export default abstract class Balloon { this.element.addEventListener('click', this.pop.bind(this)); } - protected async importStylesheet(name: string = 'style.css'): Promise { + protected async importStylesheet(name?: string): Promise; + protected async importStylesheet({ + id, + name, + }: StyleSheetProps): Promise; + protected async importStylesheet( + args?: string | StyleSheetProps + ): Promise { + const { id, name } = + typeof args === 'string' ? { id: undefined, name: args } : (args ?? {}); await importStylesheet( - `${this.name}-styles`, - joinPaths(this.resourceLocation, name) + `${id ?? this.name}-styles`, + joinPaths(this.resourceLocation, name ?? 'styles.css') ); } From f96136771fa49ec8bceb0e268065711a0e2b9e53 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sun, 14 Jul 2024 14:08:51 +0200 Subject: [PATCH 055/100] Add static id for importing default stylesheet --- src/balloons/default.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/balloons/default.ts b/src/balloons/default.ts index 76ab8a48..2863608a 100644 --- a/src/balloons/default.ts +++ b/src/balloons/default.ts @@ -127,7 +127,10 @@ export default class Default extends Balloon { } public build() { - this.importStylesheet(this.originalPath('default.css')); + this.importStylesheet({ + id: 'default', + name: this.originalPath('default.css'), + }); const positionX = random(5, 95); const size = random(this.options.size[0], this.options.size[1]); From ee28644aed0a3104515a07403f187ca756eb3444 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sun, 14 Jul 2024 14:09:52 +0200 Subject: [PATCH 056/100] Don't modify id in base importStylesheet function --- src/utils.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/utils.ts b/src/utils.ts index 4155a127..3093267d 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -115,7 +115,6 @@ export function getBalloonContainer() { } export async function importStylesheet(id: string, href: string) { - id = `pop-a-loon-${id}`; if (!document.getElementById(id)) { // Fetch the CSS file content const response = await fetch(href); From c271f4ad1c48fbc39c9fdb9b6e0f920d3edd4df4 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sun, 14 Jul 2024 14:13:53 +0200 Subject: [PATCH 057/100] Update importStylesheet method in Balloon class to use browser.runtime.getURL() --- src/balloon.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/balloon.ts b/src/balloon.ts index 85169354..1b02e41c 100644 --- a/src/balloon.ts +++ b/src/balloon.ts @@ -84,7 +84,9 @@ export default abstract class Balloon { // Import base styles importStylesheet( 'balloon-styles', - joinPaths('resources', 'balloons', 'base-styles.css') + browser.runtime.getURL( + joinPaths('resources', 'balloons', 'base-styles.css') + ) ); // Build the balloon element this.build(); From 05d1aaba78e6c907571260d4d90f9e647321d1af Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sun, 14 Jul 2024 14:16:53 +0200 Subject: [PATCH 058/100] Mock fetch in test balloon test --- tests/balloon.test.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/balloon.test.ts b/tests/balloon.test.ts index 3506f333..3666e5a7 100644 --- a/tests/balloon.test.ts +++ b/tests/balloon.test.ts @@ -1,5 +1,8 @@ import Balloon from '@/balloon'; import { BalloonName } from '@/const'; +import fetchMock from 'jest-fetch-mock'; + +fetchMock.enableMocks(); // Create a concrete subclass of Balloon for testing class TestBalloon extends Balloon { @@ -14,6 +17,8 @@ describe('Balloon', () => { beforeEach(() => { balloon = new TestBalloon(); + + fetchMock.resetMocks(); }); test('isRising should return a boolean', () => { From d9ef9c5dd2ea40ccac49bedadee482d2a6521c13 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Mon, 15 Jul 2024 01:06:07 +0200 Subject: [PATCH 059/100] Update importOrder #262 --- .prettierrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.prettierrc b/.prettierrc index a946b9bf..1cb3d4b5 100644 --- a/.prettierrc +++ b/.prettierrc @@ -10,5 +10,5 @@ "sortingMethod": "alphabetical", "stripNewlines": true, "newlineBetweenTypes": false, - "importTypeOrder": ["NPMPackages", "localImportsType", "localImportsValue"] + "importTypeOrder": ["NPMPackages", "localImportsValue", "localImportsType"] } From 9d983c4711976124d5bc4f4c7d7fbc38b6c0fb3d Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Wed, 5 Jun 2024 19:19:33 +0200 Subject: [PATCH 060/100] Implement balloon options attribute and update balloon class UML #214 --- docs/README.md | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/docs/README.md b/docs/README.md index 48d916c3..c5214394 100644 --- a/docs/README.md +++ b/docs/README.md @@ -171,19 +171,33 @@ classDiagram direction LR class Balloon { <> - -element: HTMLDivElement + +options: BalloonOptions* + -_popSound: HTMLAudioElement #balloonImage: HTMLImageElement - #<< get >>balloonImageUrl: string - #<< get >>popSoundUrl: string - #<< get >>popSound: HTMLAudioElement - +name: string* + +element: HTMLDivElement + +riseDurationThreshold: [number, number] + +swingDurationThreshold: [number, number] + +<< get >>name: string + +<< get >>balloonImageUrl: string + +<< get >>popSoundUrl: string + +<< get >>popSound: HTMLAudioElement + +<< get >>topElement: HTMLDivElement +constructor() - +getRandomDuration() number* +isRising() boolean +rise() void +remove() void +pop() void + -_pop() void } + +class BalloonOptions { + <> + name: string + imageUrl: string | undefined + popSoundUrl: string | undefined +} + +Balloon <|-- BalloonOptions ``` ### Default balloon From 3bf6c9e522c2a2d8fdd22bce76c1311e778e7902 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Wed, 5 Jun 2024 19:20:29 +0200 Subject: [PATCH 061/100] Update default balloon UML #214 --- docs/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index c5214394..876530fc 100644 --- a/docs/README.md +++ b/docs/README.md @@ -212,8 +212,7 @@ click Balloon href "#abstract-balloon-class" "Abstract balloon class" class Default { +spawn_chance: number$ - +name: string* - +getRandomDuration() number* + +options: BalloonOptions } Default --|> Balloon ``` From ed174cb0e8f492a9050f65e734d1e9340446b179 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Wed, 5 Jun 2024 19:22:29 +0200 Subject: [PATCH 062/100] Add confetti balloon documentation close #214 --- docs/README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/docs/README.md b/docs/README.md index 876530fc..9dc9fec1 100644 --- a/docs/README.md +++ b/docs/README.md @@ -22,6 +22,7 @@ - [Balloons](#balloons) - [Abstract balloon class](#abstract-balloon-class) - [Default balloon](#default-balloon) + - [Confetti balloon](#confetti-balloon) @@ -216,3 +217,22 @@ class Default { } Default --|> Balloon ``` + +### Confetti balloon + +The confetti balloon is a balloon that spawns confetti when popped. + +```mermaid +classDiagram +direction LR +class Balloon { <> } +click Balloon href "#abstract-balloon-class" "Abstract balloon class" + +class Confetti { + +spawn_chance: number$ + +options: BalloonOptions + -mask: HTMLImageElement + +pop(event: MouseEvent) void +} +Confetti --|> Balloon +``` From f9d5f60a45cc3e471053ddfcf45ec22d4a2dbcd3 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Wed, 5 Jun 2024 19:48:22 +0200 Subject: [PATCH 063/100] Document balloon properties and methods #214 --- docs/README.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/docs/README.md b/docs/README.md index 9dc9fec1..138c82e7 100644 --- a/docs/README.md +++ b/docs/README.md @@ -21,6 +21,9 @@ - [Balloon spawn chances](#balloon-spawn-chances) - [Balloons](#balloons) - [Abstract balloon class](#abstract-balloon-class) + - [Properties](#properties) + - [Options](#options) + - [Methods](#methods) - [Default balloon](#default-balloon) - [Confetti balloon](#confetti-balloon) @@ -201,6 +204,39 @@ class BalloonOptions { Balloon <|-- BalloonOptions ``` +#### Properties + +- `options: BalloonOptions` - The [options](#options) for the balloon. + > This is an abstract property and should be implemented by the subclass. +- `_popSound: HTMLAudioElement` - *private* - The HTML audio element without the src loaded by default. +- `balloonImage: HTMLImageElement` - *protected* - The image of the balloon. +- `element: HTMLDivElement` - The element that represents the balloon. +- `riseDurationThreshold: [number, number]` - The range of the duration of the rise animation. +- `swingDurationThreshold: [number, number]` - The range of the duration of the swing animation. +- `name: string` - The name used to identify the balloon. + > This is the name from the balloon [options](#options). +- `balloonImageUrl: string` - The URL of the image of the balloon. +- `popSoundUrl: string` - The URL of the sound that plays when the balloon pops. +- `popSound: HTMLAudioElement` - The sound that plays when the balloon pops. + > The sound is loaded when the balloon is created. +- `topElement: HTMLDivElement` - The top element of the balloon. + > The direct child of the balloon container. + +##### Options + +- `name: string` - The name of the balloon. +- `imageUrl: string | undefined` - The URL of the image of the balloon. +- `popSoundUrl: string | undefined` - The URL of the sound that plays when the balloon pops. + +#### Methods + +- `constructor()` - Creates a new balloon. +- `isRising(): boolean` - Returns whether the balloon is rising. +- `rise(): void` - Makes the balloon rise. +- `remove(): void` - Removes the balloon. +- `pop(): void` - Pops the balloon. +- `_pop(): void` - *private* - Pops the balloon. + ### Default balloon The default balloon is a simple balloon that rises and pops when clicked. From e0620d77864d5ee70e29b3daa45bb021d91497df Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Wed, 5 Jun 2024 20:14:09 +0200 Subject: [PATCH 064/100] Update pop-a-loon npm scripts documentation --- docs/README.md | 101 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 92 insertions(+), 9 deletions(-) diff --git a/docs/README.md b/docs/README.md index 138c82e7..e946cfdf 100644 --- a/docs/README.md +++ b/docs/README.md @@ -10,7 +10,13 @@ - [Installation](#installation) - [Development](#development) - [dev:chrome](#devchrome) + - [dev:chrome:noremote](#devchromenoremote) + - [dev:chrome:remote](#devchromeremote) - [dev:firefox](#devfirefox) + - [dev:firefox:noremote](#devfirefoxnoremote) + - [dev:firefox:remote](#devfirefoxremote) + - [Load the extension to chrome](#load-the-extension-to-chrome) + - [Load the extension to firefox](#load-the-extension-to-firefox) - [Debugging in Visual Studio Code](#debugging-in-visual-studio-code) - [Deployment](#deployment) - [build:chrome](#buildchrome) @@ -56,8 +62,18 @@ npm install Building for development can be done with the `dev:{browser}` script. Replace `{browser}` with the browser you want to build for. The available options are `chrome` and `firefox`. +> [!TIP] +> See the [Load the extension to chrome](#load-the-extension-to-chrome) and [Load the extension to firefox](#load-the-extension-to-firefox) sections for instructions on how to load the extension in the browser. + #### dev:chrome + + +> [!IMPORTANT] +> This will call the [dev:chrome:noremote](#devchromenoremote) script. + + + To build for Chrome: ```bash @@ -70,18 +86,40 @@ This will build the extension in development mode for chrome. You can also inclu npm run dev:chrome -- --watch ``` -The extension can be loaded in the browser by following the steps below: +#### dev:chrome:noremote -1. Open the Extension Management page by navigating to [`chrome://extensions`](chrome://extensions). +To build for Chrome without a remote server: - > Don't forget to enable Developer mode in the top right corner. +```bash +npm run dev:chrome:noremote +``` -2. Click the `Load unpacked` button and select the `dist/` directory. -3. The extension should now be loaded and you can see the icon in the browser toolbar. -4. Pin the extension to the toolbar for easy access. +This will build the extension in development mode for chrome without a remote server. You can also include the `--watch` flag to automatically rebuild the extension when files change. + +```bash +npm run dev:chrome:noremote -- --watch +``` + +#### dev:chrome:remote + +> [!IMPORTANT] +> This will connect to a [pop-a-loon-backend](https://github.com/SimonStnn/pop-a-loon-backend) server which is expected to be running on `http://localhost:3000`. + +To build for Chrome with a remote server: + +```bash +npm run dev:chrome:remote +``` #### dev:firefox + + +> [!IMPORTANT] +> This will call the [dev:firefox:noremote](#devfirefoxnoremote) script. + + + To build for Firefox: ```bash @@ -94,6 +132,51 @@ This will build the extension in development mode for firefox. You can also incl npm run dev:firefox -- --watch ``` +#### dev:firefox:noremote + +To build for Firefox without a remote server: + +```bash +npm run dev:firefox:noremote +``` + +This will build the extension in development mode for firefox without a remote server. You can also include the `--watch` flag to automatically rebuild the extension when files change. + +```bash +npm run dev:firefox:noremote -- --watch +``` + +#### dev:firefox:remote + +> [!IMPORTANT] +> This will connect to a [pop-a-loon-backend](https://github.com/SimonStnn/pop-a-loon-backend) server which is expected to be running on `http://localhost:3000`. + +To build for Firefox with a remote server: + +```bash +npm run dev:firefox:remote +``` + +This will build the extension in development mode for firefox with a remote server. You can also include the `--watch` flag to automatically rebuild the extension when files change. + +```bash +npm run dev:firefox:remote -- --watch +``` + +### Load the extension to chrome + +The extension can be loaded in the browser by following the steps below: + +1. Open the Extension Management page by navigating to [`chrome://extensions`](chrome://extensions). + + > Don't forget to enable Developer mode in the top right corner. + +2. Click the `Load unpacked` button and select the `dist/` directory. +3. The extension should now be loaded and you can see the icon in the browser toolbar. +4. Pin the extension to the toolbar for easy access. + +### Load the extension to firefox + The extension can be loaded in the browser by following the steps below: 1. Open the Add-ons page by navigating to [`about:addons`](about:addons). @@ -208,8 +291,8 @@ Balloon <|-- BalloonOptions - `options: BalloonOptions` - The [options](#options) for the balloon. > This is an abstract property and should be implemented by the subclass. -- `_popSound: HTMLAudioElement` - *private* - The HTML audio element without the src loaded by default. -- `balloonImage: HTMLImageElement` - *protected* - The image of the balloon. +- `_popSound: HTMLAudioElement` - _private_ - The HTML audio element without the src loaded by default. +- `balloonImage: HTMLImageElement` - _protected_ - The image of the balloon. - `element: HTMLDivElement` - The element that represents the balloon. - `riseDurationThreshold: [number, number]` - The range of the duration of the rise animation. - `swingDurationThreshold: [number, number]` - The range of the duration of the swing animation. @@ -235,7 +318,7 @@ Balloon <|-- BalloonOptions - `rise(): void` - Makes the balloon rise. - `remove(): void` - Removes the balloon. - `pop(): void` - Pops the balloon. -- `_pop(): void` - *private* - Pops the balloon. +- `_pop(): void` - _private_ - Pops the balloon. ### Default balloon From 2eaff183fc08052d457925b9567c429b6c65ed95 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Wed, 5 Jun 2024 20:16:11 +0200 Subject: [PATCH 065/100] Add footnote for `noremote` --- docs/README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index e946cfdf..013a635e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -88,7 +88,7 @@ npm run dev:chrome -- --watch #### dev:chrome:noremote -To build for Chrome without a remote server: +To build for Chrome without a remote server[^1]: ```bash npm run dev:chrome:noremote @@ -134,7 +134,7 @@ npm run dev:firefox -- --watch #### dev:firefox:noremote -To build for Firefox without a remote server: +To build for Firefox without a remote server[^1]: ```bash npm run dev:firefox:noremote @@ -163,6 +163,8 @@ This will build the extension in development mode for firefox with a remote serv npm run dev:firefox:remote -- --watch ``` +[^1]: The requests to the remote will be 'mocked' so the extension can be developed without the need for a running server. + ### Load the extension to chrome The extension can be loaded in the browser by following the steps below: From e9240d4ae07abd14c6bbbe7ad36bacf8ff40131a Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Wed, 5 Jun 2024 20:24:51 +0200 Subject: [PATCH 066/100] Add build:all:zip command for building the extension for all browsers and including a zip file of the source code --- docs/README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/README.md b/docs/README.md index 013a635e..5a0a5aff 100644 --- a/docs/README.md +++ b/docs/README.md @@ -23,6 +23,8 @@ - [build:chrome:zip](#buildchromezip) - [build:firefox](#buildfirefox) - [build:firefox:zip](#buildfirefoxzip) + - [build:all:zip](#buildallzip) + - [zip:source](#zipsource) - [Architecture](#architecture) - [Balloon spawn chances](#balloon-spawn-chances) - [Balloons](#balloons) @@ -236,6 +238,26 @@ This will build the extension in production mode for firefox. You can also inclu npm run build:firefox:zip ``` +#### build:all:zip + + + +This will build the extension in production for all browsers and include a [zip file of the source code](#zipsource). + + + +```bash +npm run build:all:zip +``` + +#### zip:source + +This will create a zip file of the source code. The zip file will be created in the `build/` directory with the name `source-v{version}.zip`. + +```bash +npm run zip:source +``` + The zip file will be created in the `build/` directory. ## Architecture From fdd3b0545179361a4959161f3dd25232cad1227c Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Tue, 11 Jun 2024 23:20:33 +0200 Subject: [PATCH 067/100] Add inheritance tree diagram for balloons #139 --- docs/README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/README.md b/docs/README.md index 5a0a5aff..1ae09482 100644 --- a/docs/README.md +++ b/docs/README.md @@ -28,6 +28,7 @@ - [Architecture](#architecture) - [Balloon spawn chances](#balloon-spawn-chances) - [Balloons](#balloons) + - [Inheritance Tree](#inheritance-tree) - [Abstract balloon class](#abstract-balloon-class) - [Properties](#properties) - [Options](#options) @@ -273,6 +274,17 @@ title Balloon spawn chances ## Balloons +### Inheritance Tree + +```mermaid +classDiagram +direction BT +class Balloon { <> } + +Default --|> Balloon +Confetti --|> Balloon +``` + ### Abstract balloon class The abstract balloon class is the base class for all balloons. From 17326634c426cec86916c3d224ae7d7e3437534e Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Tue, 11 Jun 2024 23:23:02 +0200 Subject: [PATCH 068/100] Move inheritance tree to the bottom of the page --- docs/README.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/README.md b/docs/README.md index 1ae09482..ead72a81 100644 --- a/docs/README.md +++ b/docs/README.md @@ -28,13 +28,13 @@ - [Architecture](#architecture) - [Balloon spawn chances](#balloon-spawn-chances) - [Balloons](#balloons) - - [Inheritance Tree](#inheritance-tree) - [Abstract balloon class](#abstract-balloon-class) - [Properties](#properties) - [Options](#options) - [Methods](#methods) - [Default balloon](#default-balloon) - [Confetti balloon](#confetti-balloon) +- [Inheritance Tree](#inheritance-tree) @@ -274,17 +274,6 @@ title Balloon spawn chances ## Balloons -### Inheritance Tree - -```mermaid -classDiagram -direction BT -class Balloon { <> } - -Default --|> Balloon -Confetti --|> Balloon -``` - ### Abstract balloon class The abstract balloon class is the base class for all balloons. @@ -391,3 +380,14 @@ class Confetti { } Confetti --|> Balloon ``` + +## Inheritance Tree + +```mermaid +classDiagram +direction BT +class Balloon { <> } + +Default --|> Balloon +Confetti --|> Balloon +``` From b4e7204b651b48c6e3980e045de0cac85784430c Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Tue, 11 Jun 2024 23:40:46 +0200 Subject: [PATCH 069/100] Add architecture documentation file #139 --- docs/Architecture.md | 54 ++++++++++++++++++++++++++++++++++++++++++++ docs/README.md | 3 +++ 2 files changed, 57 insertions(+) create mode 100644 docs/Architecture.md diff --git a/docs/Architecture.md b/docs/Architecture.md new file mode 100644 index 00000000..b6088085 --- /dev/null +++ b/docs/Architecture.md @@ -0,0 +1,54 @@ +

Architecture

+ +## Table of Contents + + + +- [Table of Contents](#table-of-contents) +- [Directory Structure](#directory-structure) +- [Workflow](#workflow) + - [Background](#background) + - [Content Scripts](#content-scripts) + - [Popup](#popup) +- [Testing](#testing) +- [Building and Deployment](#building-and-deployment) + + + +## Directory Structure + +- `docs/`: Contains documentation files. +- `resources/`: Contains resources used in the extension and are all available when the extension is running. +- `src/`: This directory contains the source code of the extension. + - `popup/`: Contains the code for the popup UI of the extension. + - `background/`: Contains the background scripts of the extension. + - `content/`: Contains the content scripts of the extension. + - `utils.ts`: Contains utility functions used across the extension. +- `tests/`: Contains test files for the extension. +- `manifest.json`: The manifest file of the extension, which provides important metadata for the extension. + +## Workflow + +### Background + +The background scripts handle events and perform tasks that require access to browser APIs. They can listen for events such as page loads, tab changes, and user interactions. These scripts are implemented in the `src/background/` directory. + +### Content Scripts + +Content scripts are injected into web pages and have access to the DOM. They can modify the appearance and behavior of web pages, interact with page elements, and communicate with the background scripts. + +### Popup + +The popup UI provides a user-friendly interface for accessing the extension's features. It can display information, receive user input, and trigger actions. The code for the popup UI is located in the `src/popup/` directory. + +## Testing + +Run the following command to run tests: + +```bash +npm run test +``` + +## Building and Deployment + +See [the development guide](./README.md#development). diff --git a/docs/README.md b/docs/README.md index ead72a81..716fb8bb 100644 --- a/docs/README.md +++ b/docs/README.md @@ -263,6 +263,9 @@ The zip file will be created in the `build/` directory. ## Architecture +> [!NOTE] +> Read the [Architecture](./Architecture.md) document for a more detailed explanation of the architecture. + ## Balloon spawn chances ```mermaid From 52b97e75aa50881babec19274dca0a3c587e8180 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sat, 15 Jun 2024 11:05:32 +0200 Subject: [PATCH 070/100] Update balloon uml diagrams --- docs/README.md | 86 ++++++++++++++++---------------------------------- 1 file changed, 27 insertions(+), 59 deletions(-) diff --git a/docs/README.md b/docs/README.md index 716fb8bb..56ab3596 100644 --- a/docs/README.md +++ b/docs/README.md @@ -29,9 +29,6 @@ - [Balloon spawn chances](#balloon-spawn-chances) - [Balloons](#balloons) - [Abstract balloon class](#abstract-balloon-class) - - [Properties](#properties) - - [Options](#options) - - [Methods](#methods) - [Default balloon](#default-balloon) - [Confetti balloon](#confetti-balloon) - [Inheritance Tree](#inheritance-tree) @@ -286,68 +283,18 @@ classDiagram direction LR class Balloon { <> - +options: BalloonOptions* - -_popSound: HTMLAudioElement - #balloonImage: HTMLImageElement - +element: HTMLDivElement - +riseDurationThreshold: [number, number] - +swingDurationThreshold: [number, number] - +<< get >>name: string - +<< get >>balloonImageUrl: string - +<< get >>popSoundUrl: string - +<< get >>popSound: HTMLAudioElement - +<< get >>topElement: HTMLDivElement + + +name string* + +build() void* + +element HTMLDivElement +constructor() +isRising() boolean +rise() void +remove() void +pop() void - -_pop() void -} - -class BalloonOptions { - <> - name: string - imageUrl: string | undefined - popSoundUrl: string | undefined } - -Balloon <|-- BalloonOptions ``` -#### Properties - -- `options: BalloonOptions` - The [options](#options) for the balloon. - > This is an abstract property and should be implemented by the subclass. -- `_popSound: HTMLAudioElement` - _private_ - The HTML audio element without the src loaded by default. -- `balloonImage: HTMLImageElement` - _protected_ - The image of the balloon. -- `element: HTMLDivElement` - The element that represents the balloon. -- `riseDurationThreshold: [number, number]` - The range of the duration of the rise animation. -- `swingDurationThreshold: [number, number]` - The range of the duration of the swing animation. -- `name: string` - The name used to identify the balloon. - > This is the name from the balloon [options](#options). -- `balloonImageUrl: string` - The URL of the image of the balloon. -- `popSoundUrl: string` - The URL of the sound that plays when the balloon pops. -- `popSound: HTMLAudioElement` - The sound that plays when the balloon pops. - > The sound is loaded when the balloon is created. -- `topElement: HTMLDivElement` - The top element of the balloon. - > The direct child of the balloon container. - -##### Options - -- `name: string` - The name of the balloon. -- `imageUrl: string | undefined` - The URL of the image of the balloon. -- `popSoundUrl: string | undefined` - The URL of the sound that plays when the balloon pops. - -#### Methods - -- `constructor()` - Creates a new balloon. -- `isRising(): boolean` - Returns whether the balloon is rising. -- `rise(): void` - Makes the balloon rise. -- `remove(): void` - Removes the balloon. -- `pop(): void` - Pops the balloon. -- `_pop(): void` - _private_ - Pops the balloon. - ### Default balloon The default balloon is a simple balloon that rises and pops when clicked. @@ -360,9 +307,28 @@ click Balloon href "#abstract-balloon-class" "Abstract balloon class" class Default { +spawn_chance: number$ + +name: string +options: BalloonOptions + +riseDurationThreshold: [number, number] + +swingDurationThreshold: [number, number] + +balloonImageUrl: string + +popSoundUrl: string + +balloonImage: HTMLImageElement + +popSound: HTMLAudioElement + +constructor() + +build() void + +pop() Promise~void~ } Default --|> Balloon + +class BalloonOptions { + <> + dir_name: string + imageUrl: string + popSoundUrl: string +} + +Default <|-- BalloonOptions ``` ### Confetti balloon @@ -377,8 +343,10 @@ click Balloon href "#abstract-balloon-class" "Abstract balloon class" class Confetti { +spawn_chance: number$ - +options: BalloonOptions + +name: string -mask: HTMLImageElement + +constructor() + +build() void +pop(event: MouseEvent) void } Confetti --|> Balloon @@ -392,5 +360,5 @@ direction BT class Balloon { <> } Default --|> Balloon -Confetti --|> Balloon +Confetti --|> Default ``` From 01092af4f3c09c416793e9529417c84e8df1db4d Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Wed, 3 Jul 2024 21:23:28 +0200 Subject: [PATCH 071/100] Update default balloon documentation --- docs/README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/README.md b/docs/README.md index 56ab3596..fae1b4e4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -307,15 +307,14 @@ click Balloon href "#abstract-balloon-class" "Abstract balloon class" class Default { +spawn_chance: number$ - +name: string - +options: BalloonOptions - +riseDurationThreshold: [number, number] - +swingDurationThreshold: [number, number] - +balloonImageUrl: string - +popSoundUrl: string + +<< get >>name: string + +<< get >>options: BalloonOptions + +<< get >>balloonImageUrl: string + +<< get >>popSoundUrl: string +balloonImage: HTMLImageElement +popSound: HTMLAudioElement +constructor() + #originalPath(path: string) string +build() void +pop() Promise~void~ } @@ -326,6 +325,8 @@ class BalloonOptions { dir_name: string imageUrl: string popSoundUrl: string + riseDurationThreshold: [number, number] + swingDurationThreshold: [number, number] } Default <|-- BalloonOptions From 84287d83963e2bcb31485ab1e92dff065f22a47b Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Wed, 3 Jul 2024 21:45:54 +0200 Subject: [PATCH 072/100] Update abstract Balloon class documentation and UML diagrams --- docs/README.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index fae1b4e4..6209f279 100644 --- a/docs/README.md +++ b/docs/README.md @@ -284,9 +284,9 @@ direction LR class Balloon { <> - +name string* + +name: string* +build() void* - +element HTMLDivElement + +element: HTMLDivElement +constructor() +isRising() boolean +rise() void @@ -295,6 +295,19 @@ class Balloon { } ``` +The class serves as a base class for each balloon in pop-a-loon, providing essential functionality that must operate from this class. + +> [!IMPORTANT] +>The class has the following abstract properties and methods: +> +> - `name`: The name of the balloon. Should be the same as the name of the class, but in lowercase. +> - `build()`: Is called when the balloon should be built. In this method the class should for example add the styling and balloon image to the balloon element. + +These properties and methods **must** be implemented in the child classes. + +> [!IMPORTANT] +> `element` is the html element that will be added to the DOM after the balloon is built. + ### Default balloon The default balloon is a simple balloon that rises and pops when clicked. From 9d716bed82accac768e2998b67d6ce350050b67a Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Wed, 3 Jul 2024 22:19:37 +0200 Subject: [PATCH 073/100] Move default balloon documentation to separate file and add inheriting example --- docs/README.md | 35 +---------------------- docs/balloons/default.md | 61 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 34 deletions(-) create mode 100644 docs/balloons/default.md diff --git a/docs/README.md b/docs/README.md index 6209f279..b2b2eef1 100644 --- a/docs/README.md +++ b/docs/README.md @@ -310,40 +310,7 @@ These properties and methods **must** be implemented in the child classes. ### Default balloon -The default balloon is a simple balloon that rises and pops when clicked. - -```mermaid -classDiagram -direction LR -class Balloon { <> } -click Balloon href "#abstract-balloon-class" "Abstract balloon class" - -class Default { - +spawn_chance: number$ - +<< get >>name: string - +<< get >>options: BalloonOptions - +<< get >>balloonImageUrl: string - +<< get >>popSoundUrl: string - +balloonImage: HTMLImageElement - +popSound: HTMLAudioElement - +constructor() - #originalPath(path: string) string - +build() void - +pop() Promise~void~ -} -Default --|> Balloon - -class BalloonOptions { - <> - dir_name: string - imageUrl: string - popSoundUrl: string - riseDurationThreshold: [number, number] - swingDurationThreshold: [number, number] -} - -Default <|-- BalloonOptions -``` +See [Default balloon documentation](./balloons/default.md) for more information. ### Confetti balloon diff --git a/docs/balloons/default.md b/docs/balloons/default.md new file mode 100644 index 00000000..2e1995d2 --- /dev/null +++ b/docs/balloons/default.md @@ -0,0 +1,61 @@ +# Default + +The default balloon is a simple balloon that rises and pops when clicked. + +```mermaid +classDiagram +direction LR +class Balloon { <> } +click Balloon href "#abstract-balloon-class" "Abstract balloon class" + +class Default { + +spawn_chance: number$ + +<< get >>name: string + +<< get >>options: BalloonOptions + +<< get >>balloonImageUrl: string + +<< get >>popSoundUrl: string + +balloonImage: HTMLImageElement + +popSound: HTMLAudioElement + +constructor() + #originalPath(path: string) string + +build() void + +pop() Promise~void~ +} +Default --|> Balloon + +class BalloonOptions { + <> + dir_name: string + imageUrl: string + popSoundUrl: string + riseDurationThreshold: [number, number] + swingDurationThreshold: [number, number] +} + +Default <|-- BalloonOptions +``` + +## Inheriting + +To create a new balloon, extend the `Default` class and implement the abstract methods. + +```ts +class Example extends Default { + public static readonly spawn_chance: number = 0.25; + // @ts-ignore + public get name(): 'example' { + return 'example'; + } + + public get options(): BalloonOptions { + return { + ...super.options, + // Override options here + // e.g. the image url + imageUrl: 'example.svg', + }; + } +} +``` + +In this example the `Example` class extends the `Default` class and overrides the `spawn_chance`, `name` and `options` properties. The options property overrides the image url to `example.svg`. Pop-a-loon will look for this `example.svg` file in the `resources/balloons/example` directory. From 5d540eec27fc1c1340a0999ee1a7eccb49d3a141 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Wed, 3 Jul 2024 22:22:09 +0200 Subject: [PATCH 074/100] Move confetti balloon documentation to separate file --- docs/README.md | 48 ++++++++++++--------------------------- docs/balloons/confetti.md | 20 ++++++++++++++++ 2 files changed, 35 insertions(+), 33 deletions(-) create mode 100644 docs/balloons/confetti.md diff --git a/docs/README.md b/docs/README.md index b2b2eef1..91bea4bf 100644 --- a/docs/README.md +++ b/docs/README.md @@ -28,10 +28,10 @@ - [Architecture](#architecture) - [Balloon spawn chances](#balloon-spawn-chances) - [Balloons](#balloons) +- [Inheritance Tree](#inheritance-tree) - [Abstract balloon class](#abstract-balloon-class) - [Default balloon](#default-balloon) - [Confetti balloon](#confetti-balloon) -- [Inheritance Tree](#inheritance-tree) @@ -274,6 +274,17 @@ title Balloon spawn chances ## Balloons +## Inheritance Tree + +```mermaid +classDiagram +direction BT +class Balloon { <> } + +Default --|> Balloon +Confetti --|> Default +``` + ### Abstract balloon class The abstract balloon class is the base class for all balloons. @@ -298,15 +309,14 @@ class Balloon { The class serves as a base class for each balloon in pop-a-loon, providing essential functionality that must operate from this class. > [!IMPORTANT] ->The class has the following abstract properties and methods: +> The class has the following abstract properties and methods: > > - `name`: The name of the balloon. Should be the same as the name of the class, but in lowercase. > - `build()`: Is called when the balloon should be built. In this method the class should for example add the styling and balloon image to the balloon element. These properties and methods **must** be implemented in the child classes. -> [!IMPORTANT] -> `element` is the html element that will be added to the DOM after the balloon is built. +> [!IMPORTANT] > `element` is the html element that will be added to the DOM after the balloon is built. ### Default balloon @@ -314,32 +324,4 @@ See [Default balloon documentation](./balloons/default.md) for more information. ### Confetti balloon -The confetti balloon is a balloon that spawns confetti when popped. - -```mermaid -classDiagram -direction LR -class Balloon { <> } -click Balloon href "#abstract-balloon-class" "Abstract balloon class" - -class Confetti { - +spawn_chance: number$ - +name: string - -mask: HTMLImageElement - +constructor() - +build() void - +pop(event: MouseEvent) void -} -Confetti --|> Balloon -``` - -## Inheritance Tree - -```mermaid -classDiagram -direction BT -class Balloon { <> } - -Default --|> Balloon -Confetti --|> Default -``` +See [Confetti balloon documentation](./balloons/confetti.md) for more information. diff --git a/docs/balloons/confetti.md b/docs/balloons/confetti.md new file mode 100644 index 00000000..e87c970d --- /dev/null +++ b/docs/balloons/confetti.md @@ -0,0 +1,20 @@ +# Confetti + +The confetti balloon is a balloon that spawns confetti when popped. + +```mermaid +classDiagram +direction LR +class Balloon { <> } +click Balloon href "#abstract-balloon-class" "Abstract balloon class" + +class Confetti { + +spawn_chance: number$ + +name: string + -mask: HTMLImageElement + +constructor() + +build() void + +pop(event: MouseEvent) void +} +Confetti --|> Balloon +``` From a5c333db172bd213f71275ee1c16fed59a29b277 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Wed, 3 Jul 2024 22:31:42 +0200 Subject: [PATCH 075/100] Update docs headers --- docs/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/README.md b/docs/README.md index 91bea4bf..bdc47f06 100644 --- a/docs/README.md +++ b/docs/README.md @@ -27,9 +27,9 @@ - [zip:source](#zipsource) - [Architecture](#architecture) - [Balloon spawn chances](#balloon-spawn-chances) -- [Balloons](#balloons) - [Inheritance Tree](#inheritance-tree) - - [Abstract balloon class](#abstract-balloon-class) +- [Abstract balloon class](#abstract-balloon-class) +- [Balloons](#balloons) - [Default balloon](#default-balloon) - [Confetti balloon](#confetti-balloon) @@ -272,8 +272,6 @@ title Balloon spawn chances "Confetti" : 0.10 ``` -## Balloons - ## Inheritance Tree ```mermaid @@ -285,7 +283,7 @@ Default --|> Balloon Confetti --|> Default ``` -### Abstract balloon class +## Abstract balloon class The abstract balloon class is the base class for all balloons. @@ -318,6 +316,8 @@ These properties and methods **must** be implemented in the child classes. > [!IMPORTANT] > `element` is the html element that will be added to the DOM after the balloon is built. +## Balloons + ### Default balloon See [Default balloon documentation](./balloons/default.md) for more information. From 50988eba2d8c1da0f4caa3f65f7a8b1db8bf24ed Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Wed, 3 Jul 2024 22:32:30 +0200 Subject: [PATCH 076/100] Fix blockquote styling --- docs/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index bdc47f06..ba69d6f8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -314,7 +314,8 @@ The class serves as a base class for each balloon in pop-a-loon, providing essen These properties and methods **must** be implemented in the child classes. -> [!IMPORTANT] > `element` is the html element that will be added to the DOM after the balloon is built. +> [!IMPORTANT] +> `element` is the html element that will be added to the DOM after the balloon is built. ## Balloons From ea6fb73881154ef59f35dc0db9f0607f3430d6b2 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Wed, 3 Jul 2024 22:42:20 +0200 Subject: [PATCH 077/100] Add separate files for the architecture documentation --- docs/Architecture.md | 12 +++++++++--- docs/architecture/background.md | 1 + docs/architecture/content-scripts.md | 1 + docs/architecture/popup.md | 1 + 4 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 docs/architecture/background.md create mode 100644 docs/architecture/content-scripts.md create mode 100644 docs/architecture/popup.md diff --git a/docs/Architecture.md b/docs/Architecture.md index b6088085..38b694c2 100644 --- a/docs/Architecture.md +++ b/docs/Architecture.md @@ -31,15 +31,21 @@ ### Background -The background scripts handle events and perform tasks that require access to browser APIs. They can listen for events such as page loads, tab changes, and user interactions. These scripts are implemented in the `src/background/` directory. +The background scripts handle events and perform tasks that require access to browser APIs. + +Read the [background scripts documentation](./architecture/background.md) for more information. ### Content Scripts -Content scripts are injected into web pages and have access to the DOM. They can modify the appearance and behavior of web pages, interact with page elements, and communicate with the background scripts. +Content scripts are injected into web pages and have access to the DOM. This is used to make the balloons appear on web pages. + +Read the [content scripts documentation](./architecture/content-scripts.md) for more information. ### Popup -The popup UI provides a user-friendly interface for accessing the extension's features. It can display information, receive user input, and trigger actions. The code for the popup UI is located in the `src/popup/` directory. +The popup UI provides a user-friendly interface for accessing the extension's features. It can display information, receive user input. It acts as a bridge between the user and the extension and is internally just a web page. + +Read the [popup documentation](./architecture/popup.md) for more information. ## Testing diff --git a/docs/architecture/background.md b/docs/architecture/background.md new file mode 100644 index 00000000..5767328a --- /dev/null +++ b/docs/architecture/background.md @@ -0,0 +1 @@ +# Background diff --git a/docs/architecture/content-scripts.md b/docs/architecture/content-scripts.md new file mode 100644 index 00000000..91b86ecf --- /dev/null +++ b/docs/architecture/content-scripts.md @@ -0,0 +1 @@ +# Content scripts diff --git a/docs/architecture/popup.md b/docs/architecture/popup.md new file mode 100644 index 00000000..742996dc --- /dev/null +++ b/docs/architecture/popup.md @@ -0,0 +1 @@ +# Popup From 0aed4672ed8c89e451a2eb68cb70508c995da061 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Wed, 3 Jul 2024 22:42:46 +0200 Subject: [PATCH 078/100] Add a small description to the architecture documentation --- docs/Architecture.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/Architecture.md b/docs/Architecture.md index 38b694c2..28aad439 100644 --- a/docs/Architecture.md +++ b/docs/Architecture.md @@ -1,5 +1,7 @@

Architecture

+The pop-a-loon architecture is designed to be modular and extensible. This document provides an overview of the architecture of the extension. + ## Table of Contents From ed960fcc70d40d162d7a713bf2b7f4f4982c4f52 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Thu, 4 Jul 2024 11:18:15 +0200 Subject: [PATCH 079/100] Document webextension polyfill --- docs/Architecture.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/Architecture.md b/docs/Architecture.md index 28aad439..3d7bd3b9 100644 --- a/docs/Architecture.md +++ b/docs/Architecture.md @@ -9,6 +9,7 @@ The pop-a-loon architecture is designed to be modular and extensible. This docum - [Table of Contents](#table-of-contents) - [Directory Structure](#directory-structure) - [Workflow](#workflow) + - [Polyfilling](#polyfilling) - [Background](#background) - [Content Scripts](#content-scripts) - [Popup](#popup) @@ -31,6 +32,23 @@ The pop-a-loon architecture is designed to be modular and extensible. This docum ## Workflow +### Polyfilling + +To ensure compatibility with multiple browsers, the pop-a-loon extension uses the [webextension polyfill](https://github.com/mozilla/webextension-polyfill) library. This polyfill provides a consistent API for browser extensions across different browsers, allowing the extension to work seamlessly on Chrome, Firefox, and other supported browsers. + +By including the webextension polyfill in the background scripts and content scripts, the extension can make use of browser APIs and features without worrying about browser-specific implementations. This greatly simplifies the development process and ensures a consistent experience for users on different browsers. + +This means when you want to access browser API's you don't use the `chrome` or `browser` namespaces directly. You first import the polyfill and then use the `browser` namespace. + +```ts +import browser from 'webextension-polyfill'; + +// For example query some tabs +const tabs = await browser.tabs.query({ active: true }); +``` + +Now, after compiling the extension, the polyfill will be included and make the code access the correct browser API's. + ### Background The background scripts handle events and perform tasks that require access to browser APIs. From 4ef2c2d9fad390f319eb1a178dbf066e55653bd3 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Thu, 4 Jul 2024 11:36:16 +0200 Subject: [PATCH 080/100] Document storage manager --- docs/Architecture.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/docs/Architecture.md b/docs/Architecture.md index 3d7bd3b9..9c614bb4 100644 --- a/docs/Architecture.md +++ b/docs/Architecture.md @@ -10,6 +10,9 @@ The pop-a-loon architecture is designed to be modular and extensible. This docum - [Directory Structure](#directory-structure) - [Workflow](#workflow) - [Polyfilling](#polyfilling) + - [Managers](#managers) + - [Log](#log) + - [Storage](#storage) - [Background](#background) - [Content Scripts](#content-scripts) - [Popup](#popup) @@ -49,6 +52,43 @@ const tabs = await browser.tabs.query({ active: true }); Now, after compiling the extension, the polyfill will be included and make the code access the correct browser API's. +### Managers + +Pop-a-loon has a few custom managers that handle different aspects of the extension. + +#### Log + +The `log` manager is used to log messages to the console. It provides a simple interface for logging messages with different levels of severity, such as `info`, `warn`, and `error`. + +```ts +import log from '@/managers/log'; + +log.debug('This is a debug message'); +log.info('This is an info message'); +log.warn('This is a warning message'); +log.error('This is an error message'); +log.softwarn('Like the warning message but doesn\'t throw an actual warning in the console'); +log.softerror('Like the error message but doesn\'t throw an actual error in the console'); +``` + +This manager also includes log functionallity from the console namespace. Like `log.time`, `log.timeEnd`, `log.group`, `log.groupEnd`, …. + +#### Storage + +The `storage` managers provides a type-safe way to interact with the browser storage via the browser API's. + +```ts +import storage from '@/managers/storage'; + +const config = await storage.sync.get('config') +await storage.sync.set('config', { + ...config, + popVolume: 0.5, +}) +``` + +In this example we update the `popVolume` property of the `config` object in the `sync` storage. + ### Background The background scripts handle events and perform tasks that require access to browser APIs. From 8ea6819f84466fe85b246411a859dba347d1b777 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sat, 6 Jul 2024 22:31:34 +0200 Subject: [PATCH 081/100] Document alarms #139 --- docs/architecture/background.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/docs/architecture/background.md b/docs/architecture/background.md index 5767328a..7f6f181a 100644 --- a/docs/architecture/background.md +++ b/docs/architecture/background.md @@ -1 +1,22 @@ # Background + +The background scripts handle events and perform tasks that require access to browser APIs. + +## Alarms + +The background script creates and listens to alarms. There are currently two alarms: + +1. `spawnBalloon`: This alarm goes off at random intervals. When it goes off, the background script sends a content script to one of the active tabs to spawn a balloon. Because you can only specify a specific interval for alarms, e.g. every 5 minutes, the background script creates an alarm that goes off once and then creates a new alarm when that alarm was triggered. This new alarm will have a different random delay. This way, the balloons are spawned at random intervals. + + When the `spawnBalloon` the background script performs a series of checks before actually spawning a balloon. + + 1. Is there a spawn timeout? + 2. Should there be a spawn timeout? if so, set the spawn timeout. + 3. Is the browser [idle](https://developer.chrome.com/docs/extensions/reference/api/idle)? + 4. Is there already a `spawnBalloon` alarm? + + If all checks pass, the background script will query all [active tabs](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/query#active) and pick one to send the [spawn-balloon script](/src/content/spawn-balloon.ts) to. + +2. `restart`: When this alarm goes off, [runtime.reload](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/reload) is called. This restarts the extension. + + A `restart` alarm is created when the remote server is not available or when any unexpected error occurs during setup. These alarms are created with a delay of one minute. This way, the extension will try to restart itself after a minute. Why a minute? Because the extension is not supposed to be restarted too often. If the remote server is not available, it probably also isn't available the next second, but maybe it is in one minute. From 3e1ccdcbcd58d0a8e331bc3c951d9f2f67833443 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sat, 6 Jul 2024 22:37:48 +0200 Subject: [PATCH 082/100] Add alarm name type documentation #139 --- docs/architecture/background.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/architecture/background.md b/docs/architecture/background.md index 7f6f181a..9e0f8e03 100644 --- a/docs/architecture/background.md +++ b/docs/architecture/background.md @@ -20,3 +20,7 @@ The background script creates and listens to alarms. There are currently two ala 2. `restart`: When this alarm goes off, [runtime.reload](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/reload) is called. This restarts the extension. A `restart` alarm is created when the remote server is not available or when any unexpected error occurs during setup. These alarms are created with a delay of one minute. This way, the extension will try to restart itself after a minute. Why a minute? Because the extension is not supposed to be restarted too often. If the remote server is not available, it probably also isn't available the next second, but maybe it is in one minute. + +### Types + +There is an `AlarmName` type in [const.ts](/src/const.ts) that defines the alarm names. This way, there is type safety and the alarm names are consistent throughout the extension. From 120b6c9274cc96cc4903a895516552ec09fbfd6b Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sat, 6 Jul 2024 23:01:19 +0200 Subject: [PATCH 083/100] Document messages #139 --- docs/architecture/background.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/docs/architecture/background.md b/docs/architecture/background.md index 9e0f8e03..31abea7e 100644 --- a/docs/architecture/background.md +++ b/docs/architecture/background.md @@ -21,6 +21,20 @@ The background script creates and listens to alarms. There are currently two ala A `restart` alarm is created when the remote server is not available or when any unexpected error occurs during setup. These alarms are created with a delay of one minute. This way, the extension will try to restart itself after a minute. Why a minute? Because the extension is not supposed to be restarted too often. If the remote server is not available, it probably also isn't available the next second, but maybe it is in one minute. -### Types +### Alarm Types There is an `AlarmName` type in [const.ts](/src/const.ts) that defines the alarm names. This way, there is type safety and the alarm names are consistent throughout the extension. + +## Messages + +Pop-a-loon uses the [browser messaging API](https://developer.chrome.com/docs/extensions/develop/concepts/messaging) to communicate between different scripts. + +These are the actions for the messages (see [message types](#message-types)): + +1. `updateCounter`: When this message is received, the background script will update the counter in the browser action badge. +2. `incrementCount`: When this message is received, the background will send a request to the remote server with the popped balloo. +3. `setLogLevel`: When this message is received, the background script will set the log level specified in the message. + +### Message Types + +There are a few types defined in [const.ts](/src/const.ts) and exported under the `Message` type. They can be distinguished using the `Message.action` property. From 94d2ca5732805488c7b5e10e35c11bbc7106a6bb Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Thu, 11 Jul 2024 16:04:03 +0200 Subject: [PATCH 084/100] Add instructions on how to add a new balloon #139 --- docs/README.md | 7 ++- docs/adding-balloon.md | 102 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 docs/adding-balloon.md diff --git a/docs/README.md b/docs/README.md index ba69d6f8..2e27bff7 100644 --- a/docs/README.md +++ b/docs/README.md @@ -25,6 +25,7 @@ - [build:firefox:zip](#buildfirefoxzip) - [build:all:zip](#buildallzip) - [zip:source](#zipsource) + - [Adding a balloon](#adding-a-balloon) - [Architecture](#architecture) - [Balloon spawn chances](#balloon-spawn-chances) - [Inheritance Tree](#inheritance-tree) @@ -258,6 +259,10 @@ npm run zip:source The zip file will be created in the `build/` directory. +### Adding a balloon + +Refer to [adding a balloon](./adding-balloon.md) for instructions on how to add a new balloon to the extension. + ## Architecture > [!NOTE] @@ -315,7 +320,7 @@ The class serves as a base class for each balloon in pop-a-loon, providing essen These properties and methods **must** be implemented in the child classes. > [!IMPORTANT] -> `element` is the html element that will be added to the DOM after the balloon is built. +> The `element` is the html element that will be added to the DOM after the balloon is built. ## Balloons diff --git a/docs/adding-balloon.md b/docs/adding-balloon.md new file mode 100644 index 00000000..09906290 --- /dev/null +++ b/docs/adding-balloon.md @@ -0,0 +1,102 @@ +

Adding a new balloon

+ +Adding a new balloon to the extension is a simple process. In this document we will go over the steps to add a new balloon. + +## Table of Contents + + + +- [Table of Contents](#table-of-contents) +- [Choosing a name](#choosing-a-name) +- [Implementation](#implementation) + - [Extending the abstract balloon class](#extending-the-abstract-balloon-class) + - [Extending the Default balloon class](#extending-the-default-balloon-class) + - [Making the balloon available](#making-the-balloon-available) +- [Tests](#tests) +- [Documentation](#documentation) + + + +## Choosing a name + +The name of the balloon is prefered to be a single word. The name should fit in the text ` balloon`. This name will be used in the UI. + +## Implementation + +Each balloon is it's own class. To add a new balloon, create a new file in the [`/src/balloons/`](/src/balloons/) directory. The file should be named `.ts`. Make a class in this file and export it. Your new balloon should extend the Balloon class or any other balloon in the [balloon hierarchy](./README.md#inheritance-tree). + +### Extending the abstract balloon class + +Here we will discuss how to add a balloon extending the [abstract balloon class](./README.md#abstract-balloon-class). This is more complicated as there is less functionality provided in the abstract balloon class. + +> [!TIP] +> For a simpler implementation refer to [extending the Default balloon class](#extending-the-default-balloon-class). This class has more functionality implemented. + +```ts +// example.ts +import Balloon from '@/balloon'; + +export default class Example extends Balloon { + public static readonly spawn_chance: number = 0.1; + public readonly name = 'example'; + + public build() { + // Build the balloon element with the `this.element` div + } +} +``` + +Now you build your class you can [make your balloon available](#making-the-balloon-available) to pop-a-loon and see it on screen. + +### Extending the Default balloon class + +Extending the [Default balloon](./balloons/default.md) is a simpler process. + +```ts +// example.ts +class Example extends Default { + public static readonly spawn_chance: number = 0.1; + // @ts-ignore + public get name(): 'example' { + return 'example'; + } + + public get options(): BalloonOptions { + return { + ...super.options, + // Override options here + // e.g. the image url + imageUrl: 'example.svg', + }; + } +} +``` + +In this example the `Example` class extends the `Default` class and overrides the `spawn_chance`, `name` and `options` properties. The options property overrides the image url to `example.svg`. Pop-a-loon will look for this `example.svg` file in the `resources/balloons/example` directory. The image for the balloon doesn't need to be an `svg`, but it is recommended. + +You can find what other options you can override in the [default balloon documentation](./balloons/default.md). Further implementation is up to you. + +Now you build your class you can [make your balloon available](#making-the-balloon-available) to pop-a-loon and see it on screen. + +### Making the balloon available + +Now we need to export it from the [`/src/balloons/`](/src/balloons/) module. So we include it in [`/src/balloons/index.ts`](/src/balloons/index.ts) + +```ts +// index.ts +// ... other balloons +export { default as Example } from './example'; +// ... other balloons +``` + +Balloon exports happen preferable in alphabetical order. + +## Tests + +Add your balloon test file to the [`/tests/`](/tests/) folder with the name: `.test.ts` and add the required tests that need to pass for your balloon. + +## Documentation + +Add your balloon documentation to the [`/docs/balloons/`](/docs/balloons/) folder with the name: `.md` and add there the documentation for your balloon. + +Add your balloon spawn chance to the [balloon spawn chances](./README.md#balloon-spawn-chances) and the balloon class to the [inheritance tree](./README.md#inheritance-tree). Refer to your balloon documentation at the [Balloons section](./README.md#balloons). From f729a83ac8c47c406fc94c3f638172f55e464760 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Thu, 11 Jul 2024 16:11:01 +0200 Subject: [PATCH 085/100] Add golden balloon documentation #139 --- docs/balloons/gold.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 docs/balloons/gold.md diff --git a/docs/balloons/gold.md b/docs/balloons/gold.md new file mode 100644 index 00000000..c3dac79b --- /dev/null +++ b/docs/balloons/gold.md @@ -0,0 +1,21 @@ +# Gold + +Just like the [default balloon](./default.md), but :sparkles: golden :sparkles:. + +```mermaid +classDiagram +direction LR +class Balloon { <> } +click Balloon href "#abstract-balloon-class" "Abstract balloon class" + +class Gold { + +spawn_chance: number$ + +<< get >>name: string + +<< get >>options: BalloonOptions +} +Gold --|> Balloon +``` + +Has a custom image resource in [`/resources/balloons/gold/balloon.svg`](/resources/balloons/gold/balloon.svg). + +![Gold balloon](/resources/balloons/gold/balloon.svg) \ No newline at end of file From 9da571a676c0f03a954cedca7b3dda7992e161b2 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Thu, 11 Jul 2024 16:23:52 +0200 Subject: [PATCH 086/100] Update default balloon class options --- docs/balloons/default.md | 32 +++++--------------------------- 1 file changed, 5 insertions(+), 27 deletions(-) diff --git a/docs/balloons/default.md b/docs/balloons/default.md index 2e1995d2..be50f3e3 100644 --- a/docs/balloons/default.md +++ b/docs/balloons/default.md @@ -12,10 +12,10 @@ class Default { +spawn_chance: number$ +<< get >>name: string +<< get >>options: BalloonOptions - +<< get >>balloonImageUrl: string - +<< get >>popSoundUrl: string +balloonImage: HTMLImageElement +popSound: HTMLAudioElement + +<< get >>balloonImageUrl: string + +<< get >>popSoundUrl: string +constructor() #originalPath(path: string) string +build() void @@ -28,34 +28,12 @@ class BalloonOptions { dir_name: string imageUrl: string popSoundUrl: string + size: [number, number] riseDurationThreshold: [number, number] swingDurationThreshold: [number, number] + swingOffset: number + waveDegrees: number } Default <|-- BalloonOptions ``` - -## Inheriting - -To create a new balloon, extend the `Default` class and implement the abstract methods. - -```ts -class Example extends Default { - public static readonly spawn_chance: number = 0.25; - // @ts-ignore - public get name(): 'example' { - return 'example'; - } - - public get options(): BalloonOptions { - return { - ...super.options, - // Override options here - // e.g. the image url - imageUrl: 'example.svg', - }; - } -} -``` - -In this example the `Example` class extends the `Default` class and overrides the `spawn_chance`, `name` and `options` properties. The options property overrides the image url to `example.svg`. Pop-a-loon will look for this `example.svg` file in the `resources/balloons/example` directory. From ff6bac3851e5540a1745dec655754cc64a48c2fa Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Thu, 11 Jul 2024 16:26:44 +0200 Subject: [PATCH 087/100] FIx markdownlint violation --- docs/balloons/gold.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/balloons/gold.md b/docs/balloons/gold.md index c3dac79b..41e41502 100644 --- a/docs/balloons/gold.md +++ b/docs/balloons/gold.md @@ -18,4 +18,4 @@ Gold --|> Balloon Has a custom image resource in [`/resources/balloons/gold/balloon.svg`](/resources/balloons/gold/balloon.svg). -![Gold balloon](/resources/balloons/gold/balloon.svg) \ No newline at end of file +![Gold balloon](/resources/balloons/gold/balloon.svg) From 888ddcbda1e97542ef5fd9d21be25bc9e0e570f4 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Fri, 12 Jul 2024 19:32:09 +0200 Subject: [PATCH 088/100] Document Gold balloon spawn chance and add it to the inharitance tree --- docs/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/README.md b/docs/README.md index 2e27bff7..5d66de20 100644 --- a/docs/README.md +++ b/docs/README.md @@ -275,6 +275,7 @@ pie showdata title Balloon spawn chances "Default" : 0.90 "Confetti" : 0.10 + "Gold": 0.05 ``` ## Inheritance Tree @@ -286,6 +287,7 @@ class Balloon { <> } Default --|> Balloon Confetti --|> Default +Gold --|> Default ``` ## Abstract balloon class From 5fff1d95563ec0981c6234d53f737462d51b6813 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Fri, 12 Jul 2024 20:54:04 +0200 Subject: [PATCH 089/100] Document important background functions --- docs/architecture/background.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/architecture/background.md b/docs/architecture/background.md index 31abea7e..a8aa7a62 100644 --- a/docs/architecture/background.md +++ b/docs/architecture/background.md @@ -38,3 +38,14 @@ These are the actions for the messages (see [message types](#message-types)): ### Message Types There are a few types defined in [const.ts](/src/const.ts) and exported under the `Message` type. They can be distinguished using the `Message.action` property. + +## Important methods + +The background script has a few important methods initalized: + +- `setup()`: The setup function where all setups happen. +- `spawnBalloon()`: A balloon is sent to a tab. +- `createSpawnAlarm(name)`: Creates a balloon spawn alarm. Is triggered after `spawnBalloon()` was called. +- `backgroundScript()`: This is the 'main' function. This is the function that is initially called and calls the `setup()` function. + +These include most of the functionallity of the background. From 419ec7a3f9406ec53386859cf4efd5f20f914e5b Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Fri, 12 Jul 2024 20:54:55 +0200 Subject: [PATCH 090/100] Document event listeners in background --- docs/architecture/background.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/architecture/background.md b/docs/architecture/background.md index a8aa7a62..b6be7693 100644 --- a/docs/architecture/background.md +++ b/docs/architecture/background.md @@ -49,3 +49,12 @@ The background script has a few important methods initalized: - `backgroundScript()`: This is the 'main' function. This is the function that is initially called and calls the `setup()` function. These include most of the functionallity of the background. + +## Event listeners + +The background also listens to some events. + +- Alarms with [`onAlarm`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/alarms/onAlarm). See [alarms](#alarms). +- Messages with [`onMessage`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage). See [messages](#messages). +- [`onStartup`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onStartup) +- [`onInstalled`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onInstalled) From c438c9e1ffd5c6dfb50f785c524a84209214188d Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Fri, 12 Jul 2024 21:06:24 +0200 Subject: [PATCH 091/100] Document spawn-balloon content script --- docs/architecture/content-scripts.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/architecture/content-scripts.md b/docs/architecture/content-scripts.md index 91b86ecf..461378f9 100644 --- a/docs/architecture/content-scripts.md +++ b/docs/architecture/content-scripts.md @@ -1 +1,11 @@ # Content scripts + +## spawn-balloon + +This script is sent to a tab and will spawn a balloon. + +It will add a [balloon container](#balloon-container) to the page if its not already in the page. After this it will gather all balloon types and their spawn chances and pick a random balloon to spawn. + +### Balloon container + +This is div element added directly to the body of the page a balloon is sent to. All other page modifications happen in this element. From b0e2cfb29137e7c4ad44314f8bf8396093af9532 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Fri, 12 Jul 2024 21:07:02 +0200 Subject: [PATCH 092/100] Update making balloon available header --- docs/adding-balloon.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/adding-balloon.md b/docs/adding-balloon.md index 09906290..2683e2da 100644 --- a/docs/adding-balloon.md +++ b/docs/adding-balloon.md @@ -11,7 +11,7 @@ Adding a new balloon to the extension is a simple process. In this document we w - [Implementation](#implementation) - [Extending the abstract balloon class](#extending-the-abstract-balloon-class) - [Extending the Default balloon class](#extending-the-default-balloon-class) - - [Making the balloon available](#making-the-balloon-available) +- [Making the balloon available](#making-the-balloon-available) - [Tests](#tests) - [Documentation](#documentation) @@ -78,7 +78,7 @@ You can find what other options you can override in the [default balloon documen Now you build your class you can [make your balloon available](#making-the-balloon-available) to pop-a-loon and see it on screen. -### Making the balloon available +## Making the balloon available Now we need to export it from the [`/src/balloons/`](/src/balloons/) module. So we include it in [`/src/balloons/index.ts`](/src/balloons/index.ts) From 3126adadedb139973d95ca9b24afe716c0e69776 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Fri, 12 Jul 2024 21:52:13 +0200 Subject: [PATCH 093/100] Import default balloon in example --- docs/adding-balloon.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/adding-balloon.md b/docs/adding-balloon.md index 2683e2da..51736ad0 100644 --- a/docs/adding-balloon.md +++ b/docs/adding-balloon.md @@ -54,6 +54,8 @@ Extending the [Default balloon](./balloons/default.md) is a simpler process. ```ts // example.ts +import Default from '@/balloons/default'; + class Example extends Default { public static readonly spawn_chance: number = 0.1; // @ts-ignore From 9c08a9e69e260994cbd1845c170c904bbaa4cc4c Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Fri, 12 Jul 2024 22:06:15 +0200 Subject: [PATCH 094/100] Document how to import custom styles --- docs/adding-balloon.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/adding-balloon.md b/docs/adding-balloon.md index 51736ad0..3fa5ad69 100644 --- a/docs/adding-balloon.md +++ b/docs/adding-balloon.md @@ -11,6 +11,7 @@ Adding a new balloon to the extension is a simple process. In this document we w - [Implementation](#implementation) - [Extending the abstract balloon class](#extending-the-abstract-balloon-class) - [Extending the Default balloon class](#extending-the-default-balloon-class) + - [Custom balloon styles](#custom-balloon-styles) - [Making the balloon available](#making-the-balloon-available) - [Tests](#tests) - [Documentation](#documentation) @@ -80,6 +81,23 @@ You can find what other options you can override in the [default balloon documen Now you build your class you can [make your balloon available](#making-the-balloon-available) to pop-a-loon and see it on screen. +### Custom balloon styles + +Implementing a custom balloon may require custom styles. To do this you can add a new css file to your resources folder. To import the css file you can use the `importStylesheet` function from [utils](/src/utils.ts). + +```ts +import { importStylesheet } from '@/utils'; + +class Example extends Default { + public build() { + super.build(); + importStylesheet('example-styles', this.resourceLocation + 'style.css'); + } +} +``` + +In this example the `importStylesheet` function is used to import the `style.css` file from the `resources/balloons/example` directory. The `resourceLocation` property is provided by the `Default` class and is the path to the balloon resources. + ## Making the balloon available Now we need to export it from the [`/src/balloons/`](/src/balloons/) module. So we include it in [`/src/balloons/index.ts`](/src/balloons/index.ts) From 9e4adce0f211d78891edfa0eeb8b77107f742509 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Sun, 14 Jul 2024 13:13:49 +0200 Subject: [PATCH 095/100] Update importStylesheet function documentation --- docs/adding-balloon.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/adding-balloon.md b/docs/adding-balloon.md index 3fa5ad69..5c3a250d 100644 --- a/docs/adding-balloon.md +++ b/docs/adding-balloon.md @@ -91,13 +91,15 @@ import { importStylesheet } from '@/utils'; class Example extends Default { public build() { super.build(); - importStylesheet('example-styles', this.resourceLocation + 'style.css'); + this.importStylesheet('style.css'); } } ``` In this example the `importStylesheet` function is used to import the `style.css` file from the `resources/balloons/example` directory. The `resourceLocation` property is provided by the `Default` class and is the path to the balloon resources. +> The default value for the file name is `'style.css'`. So in this example it can even be excluded. + ## Making the balloon available Now we need to export it from the [`/src/balloons/`](/src/balloons/) module. So we include it in [`/src/balloons/index.ts`](/src/balloons/index.ts) From bb65f63487aeb4d08cc9dcb1438741ee928759eb Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Mon, 15 Jul 2024 13:00:37 +0200 Subject: [PATCH 096/100] Document webpack configuration --- docs/Architecture.md | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/docs/Architecture.md b/docs/Architecture.md index 9c614bb4..c4bfc6f2 100644 --- a/docs/Architecture.md +++ b/docs/Architecture.md @@ -10,6 +10,9 @@ The pop-a-loon architecture is designed to be modular and extensible. This docum - [Directory Structure](#directory-structure) - [Workflow](#workflow) - [Polyfilling](#polyfilling) + - [Webpack](#webpack) + - [Environment Variables](#environment-variables) + - [Resources folder](#resources-folder) - [Managers](#managers) - [Log](#log) - [Storage](#storage) @@ -52,6 +55,23 @@ const tabs = await browser.tabs.query({ active: true }); Now, after compiling the extension, the polyfill will be included and make the code access the correct browser API's. +### Webpack + +The pop-a-loon extension uses [Webpack](https://webpack.js.org/) to compile its JavaScript code. The webpack configuration is set up to compile the background scripts, popup UI and an entry for each content script into separate bundles. This allows for better organization of the code and ensures that each part of the extension is compiled correctly. Configuration can be found in the [webpack.config.js](/webpack.config.js) file. + +#### Environment Variables + +The webpack configuration uses environment variables to determine the build mode. The `NODE_ENV` environment variable is used to determine whether the extension is being built for development or production. This allows for different optimizations and settings to be applied based on the build mode. + +Webpack also sets some environment variables for the extension. In the source code they are accessed via the `process.env` object. For example, the `process.env.NODE_ENV` variable is used to determine the build mode. + +> [!WARNING] +> The `process` namespace is not available in the browser. This is a Node.js specific feature. Webpack replaces the `process` object with the correct values during compilation. (e.g. `process.env.NODE_ENV` is replaced with `production`). + +#### Resources folder + +The `resources` folder contains all the resources used in the extension. This includes images, icons, and other assets that are used in the extension. These resources are copied to the build directory during the compilation process and are available when the extension is running. + ### Managers Pop-a-loon has a few custom managers that handle different aspects of the extension. @@ -67,8 +87,12 @@ log.debug('This is a debug message'); log.info('This is an info message'); log.warn('This is a warning message'); log.error('This is an error message'); -log.softwarn('Like the warning message but doesn\'t throw an actual warning in the console'); -log.softerror('Like the error message but doesn\'t throw an actual error in the console'); +log.softwarn( + "Like the warning message but doesn't throw an actual warning in the console" +); +log.softerror( + "Like the error message but doesn't throw an actual error in the console" +); ``` This manager also includes log functionallity from the console namespace. Like `log.time`, `log.timeEnd`, `log.group`, `log.groupEnd`, …. @@ -80,11 +104,11 @@ The `storage` managers provides a type-safe way to interact with the browser sto ```ts import storage from '@/managers/storage'; -const config = await storage.sync.get('config') +const config = await storage.sync.get('config'); await storage.sync.set('config', { ...config, popVolume: 0.5, -}) +}); ``` In this example we update the `popVolume` property of the `config` object in the `sync` storage. From ba2c9d07af0fb75bb17ec59095a87969660e0821 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Mon, 15 Jul 2024 13:02:04 +0200 Subject: [PATCH 097/100] Remove workflow header --- docs/Architecture.md | 43 ++++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/docs/Architecture.md b/docs/Architecture.md index c4bfc6f2..c8e9f246 100644 --- a/docs/Architecture.md +++ b/docs/Architecture.md @@ -8,17 +8,16 @@ The pop-a-loon architecture is designed to be modular and extensible. This docum - [Table of Contents](#table-of-contents) - [Directory Structure](#directory-structure) -- [Workflow](#workflow) - - [Polyfilling](#polyfilling) - - [Webpack](#webpack) - - [Environment Variables](#environment-variables) - - [Resources folder](#resources-folder) - - [Managers](#managers) - - [Log](#log) - - [Storage](#storage) - - [Background](#background) - - [Content Scripts](#content-scripts) - - [Popup](#popup) +- [Polyfilling](#polyfilling) +- [Webpack](#webpack) + - [Environment Variables](#environment-variables) + - [Resources folder](#resources-folder) +- [Managers](#managers) + - [Log](#log) + - [Storage](#storage) +- [Background](#background) +- [Content Scripts](#content-scripts) +- [Popup](#popup) - [Testing](#testing) - [Building and Deployment](#building-and-deployment) @@ -36,9 +35,7 @@ The pop-a-loon architecture is designed to be modular and extensible. This docum - `tests/`: Contains test files for the extension. - `manifest.json`: The manifest file of the extension, which provides important metadata for the extension. -## Workflow - -### Polyfilling +## Polyfilling To ensure compatibility with multiple browsers, the pop-a-loon extension uses the [webextension polyfill](https://github.com/mozilla/webextension-polyfill) library. This polyfill provides a consistent API for browser extensions across different browsers, allowing the extension to work seamlessly on Chrome, Firefox, and other supported browsers. @@ -55,11 +52,11 @@ const tabs = await browser.tabs.query({ active: true }); Now, after compiling the extension, the polyfill will be included and make the code access the correct browser API's. -### Webpack +## Webpack The pop-a-loon extension uses [Webpack](https://webpack.js.org/) to compile its JavaScript code. The webpack configuration is set up to compile the background scripts, popup UI and an entry for each content script into separate bundles. This allows for better organization of the code and ensures that each part of the extension is compiled correctly. Configuration can be found in the [webpack.config.js](/webpack.config.js) file. -#### Environment Variables +### Environment Variables The webpack configuration uses environment variables to determine the build mode. The `NODE_ENV` environment variable is used to determine whether the extension is being built for development or production. This allows for different optimizations and settings to be applied based on the build mode. @@ -68,15 +65,15 @@ Webpack also sets some environment variables for the extension. In the source co > [!WARNING] > The `process` namespace is not available in the browser. This is a Node.js specific feature. Webpack replaces the `process` object with the correct values during compilation. (e.g. `process.env.NODE_ENV` is replaced with `production`). -#### Resources folder +### Resources folder The `resources` folder contains all the resources used in the extension. This includes images, icons, and other assets that are used in the extension. These resources are copied to the build directory during the compilation process and are available when the extension is running. -### Managers +## Managers Pop-a-loon has a few custom managers that handle different aspects of the extension. -#### Log +### Log The `log` manager is used to log messages to the console. It provides a simple interface for logging messages with different levels of severity, such as `info`, `warn`, and `error`. @@ -97,7 +94,7 @@ log.softerror( This manager also includes log functionallity from the console namespace. Like `log.time`, `log.timeEnd`, `log.group`, `log.groupEnd`, …. -#### Storage +### Storage The `storage` managers provides a type-safe way to interact with the browser storage via the browser API's. @@ -113,19 +110,19 @@ await storage.sync.set('config', { In this example we update the `popVolume` property of the `config` object in the `sync` storage. -### Background +## Background The background scripts handle events and perform tasks that require access to browser APIs. Read the [background scripts documentation](./architecture/background.md) for more information. -### Content Scripts +## Content Scripts Content scripts are injected into web pages and have access to the DOM. This is used to make the balloons appear on web pages. Read the [content scripts documentation](./architecture/content-scripts.md) for more information. -### Popup +## Popup The popup UI provides a user-friendly interface for accessing the extension's features. It can display information, receive user input. It acts as a bridge between the user and the extension and is internally just a web page. From 4da31b052da3f5732ff95d9c6f63710a53ada2e5 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Mon, 15 Jul 2024 13:09:42 +0200 Subject: [PATCH 098/100] Document the manifests --- docs/Architecture.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/Architecture.md b/docs/Architecture.md index c8e9f246..373089eb 100644 --- a/docs/Architecture.md +++ b/docs/Architecture.md @@ -15,6 +15,7 @@ The pop-a-loon architecture is designed to be modular and extensible. This docum - [Managers](#managers) - [Log](#log) - [Storage](#storage) +- [Manifest](#manifest) - [Background](#background) - [Content Scripts](#content-scripts) - [Popup](#popup) @@ -110,6 +111,14 @@ await storage.sync.set('config', { In this example we update the `popVolume` property of the `config` object in the `sync` storage. +## Manifest + +The [`manifest.json`](/manifest.json) file is the metadata file for the extension. It contains information about the extension, such as its name, version, description, and permissions. The manifest file also specifies the background scripts, content scripts, and popup UI of the extension. + +There are also browser specific manifest files. These are used to specify browser specific settings. For example, the [`manifest.firefox.json`](/manifest.firefox.json) file is used to specify a `browser_specific_settings` key that is only available in Firefox. + +The browser specific manifest files are merged with the base manifest file during the build process. This allows for browser-specific settings to be applied when the extension is compiled. The browser specific manifest file keys can override the options defined in the base manifest file. + ## Background The background scripts handle events and perform tasks that require access to browser APIs. From 4ee2df231d5a060c529489d9374dd0305a258309 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Mon, 15 Jul 2024 13:12:25 +0200 Subject: [PATCH 099/100] Refer to webpack building the manifests --- docs/Architecture.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/Architecture.md b/docs/Architecture.md index 373089eb..b478b763 100644 --- a/docs/Architecture.md +++ b/docs/Architecture.md @@ -12,6 +12,7 @@ The pop-a-loon architecture is designed to be modular and extensible. This docum - [Webpack](#webpack) - [Environment Variables](#environment-variables) - [Resources folder](#resources-folder) + - [Compiling the manifests](#compiling-the-manifests) - [Managers](#managers) - [Log](#log) - [Storage](#storage) @@ -70,6 +71,10 @@ Webpack also sets some environment variables for the extension. In the source co The `resources` folder contains all the resources used in the extension. This includes images, icons, and other assets that are used in the extension. These resources are copied to the build directory during the compilation process and are available when the extension is running. +### Compiling the manifests + +Webpack is used to compile the manifests. More information can be found [here](#manifest) + ## Managers Pop-a-loon has a few custom managers that handle different aspects of the extension. @@ -117,7 +122,7 @@ The [`manifest.json`](/manifest.json) file is the metadata file for the extensio There are also browser specific manifest files. These are used to specify browser specific settings. For example, the [`manifest.firefox.json`](/manifest.firefox.json) file is used to specify a `browser_specific_settings` key that is only available in Firefox. -The browser specific manifest files are merged with the base manifest file during the build process. This allows for browser-specific settings to be applied when the extension is compiled. The browser specific manifest file keys can override the options defined in the base manifest file. +The browser specific manifest files are merged with the base manifest file during the [build process](#webpack). This allows for browser-specific settings to be applied when the extension is compiled. The browser specific manifest file keys can override the options defined in the base manifest file. ## Background From a3fb2e34778e606e22abd558d13292cf9b194216 Mon Sep 17 00:00:00 2001 From: SimonStnn Date: Mon, 15 Jul 2024 13:20:12 +0200 Subject: [PATCH 100/100] Bump package version to 1.12.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2e89f942..0a6dae3e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pop-a-loon", - "version": "1.11.2", + "version": "1.12.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pop-a-loon", - "version": "1.11.2", + "version": "1.12.0", "license": "Apache-2.0", "dependencies": { "@hookform/resolvers": "^3.3.4", diff --git a/package.json b/package.json index 0eb78233..00df365d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pop-a-loon", - "version": "1.11.2", + "version": "1.12.0", "description": "The new rising trend (literally) that changes the browser game completely.", "private": true, "scripts": {