diff --git a/README.md b/README.md index 3ce17d8..d3bfd51 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,8 @@ PRs welcome! - - Publish NPM Package + + Publish NPM Package

@@ -235,3 +235,21 @@ About [ CI/CD File.yml](https://raw.githubusercontent.com/AlbericoD/overwolf-mod ![label](./doc/ci-2.png) ![label](./doc/ci-3.png) + +## 🤝 Contributing + +Contributions, issues and feature requests are welcome! + +## Projects using OMRB + +> If you are using OMRB in your project, please let me know! I'll be happy to list it here. + +- [Fortmapp](https://www.overwolf.com/app/Alberico_Dias_Barreto_Filho-Fortmapp) + + > A map for Fortnite Battle Royale. + > ![ForFortmapptm preview](./doc/projects/fortmapp.png) + +- [Economy Tool](https://www.overwolf.com/app/Alberico_Dias_Barreto_Filho-Economy_Tool) + + > A tool to help you manage economy in the cs2. + > ![Economy Tool preview](./doc/projects/economy-tool.png) diff --git a/doc/desktop-1.png b/doc/desktop-1.png index 6311018..c25a3ae 100644 Binary files a/doc/desktop-1.png and b/doc/desktop-1.png differ diff --git a/doc/projects/economy-tool.png b/doc/projects/economy-tool.png new file mode 100644 index 0000000..7794295 Binary files /dev/null and b/doc/projects/economy-tool.png differ diff --git a/doc/projects/fortmapp.png b/doc/projects/fortmapp.png new file mode 100644 index 0000000..44d7768 Binary files /dev/null and b/doc/projects/fortmapp.png differ diff --git a/template/README.md b/template/README.md index 3ce17d8..d3bfd51 100644 --- a/template/README.md +++ b/template/README.md @@ -9,8 +9,8 @@ PRs welcome! - - Publish NPM Package + + Publish NPM Package

@@ -235,3 +235,21 @@ About [ CI/CD File.yml](https://raw.githubusercontent.com/AlbericoD/overwolf-mod ![label](./doc/ci-2.png) ![label](./doc/ci-3.png) + +## 🤝 Contributing + +Contributions, issues and feature requests are welcome! + +## Projects using OMRB + +> If you are using OMRB in your project, please let me know! I'll be happy to list it here. + +- [Fortmapp](https://www.overwolf.com/app/Alberico_Dias_Barreto_Filho-Fortmapp) + + > A map for Fortnite Battle Royale. + > ![ForFortmapptm preview](./doc/projects/fortmapp.png) + +- [Economy Tool](https://www.overwolf.com/app/Alberico_Dias_Barreto_Filho-Economy_Tool) + + > A tool to help you manage economy in the cs2. + > ![Economy Tool preview](./doc/projects/economy-tool.png) diff --git a/template/doc/ci-1.png b/template/doc/ci-1.png new file mode 100644 index 0000000..50afd86 Binary files /dev/null and b/template/doc/ci-1.png differ diff --git a/template/doc/ci-2.png b/template/doc/ci-2.png new file mode 100644 index 0000000..4463694 Binary files /dev/null and b/template/doc/ci-2.png differ diff --git a/template/doc/ci-3.png b/template/doc/ci-3.png new file mode 100644 index 0000000..b4b05a2 Binary files /dev/null and b/template/doc/ci-3.png differ diff --git a/template/doc/desktop-1.png b/template/doc/desktop-1.png new file mode 100644 index 0000000..c25a3ae Binary files /dev/null and b/template/doc/desktop-1.png differ diff --git a/template/doc/ingame-1.png b/template/doc/ingame-1.png new file mode 100644 index 0000000..8f05aaf Binary files /dev/null and b/template/doc/ingame-1.png differ diff --git a/template/doc/ingame-2.png b/template/doc/ingame-2.png new file mode 100644 index 0000000..b3128e7 Binary files /dev/null and b/template/doc/ingame-2.png differ diff --git a/template/doc/projects/economy-tool.png b/template/doc/projects/economy-tool.png new file mode 100644 index 0000000..7794295 Binary files /dev/null and b/template/doc/projects/economy-tool.png differ diff --git a/template/doc/projects/fortmapp.png b/template/doc/projects/fortmapp.png new file mode 100644 index 0000000..44d7768 Binary files /dev/null and b/template/doc/projects/fortmapp.png differ diff --git a/template/public/manifest.json b/template/public/manifest.json index 074c9be..2805094 100644 --- a/template/public/manifest.json +++ b/template/public/manifest.json @@ -3,7 +3,7 @@ "type": "WebApp", "meta": { "name": "Overwolf Modern React Boilerplate-v4", - "version": "4.0.0", + "version": "0.1.0", "minimum-overwolf-version": "0.120.0", "author": "Albérico Dias Barreto Filho", "icon": "IconMouseOver.png", @@ -12,30 +12,22 @@ "window_icon": "TaskbarIcon.png", "description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry." }, - "permissions": [ - "GameInfo" - ], + "permissions": ["Extensions", "Streaming", "Profile", "GameInfo"], "data": { "game_targeting": { "type": "dedicated", - "game_ids": [ - 9898 - ] + "game_ids": [9898] }, "launch_events": [ { "event": "GameLaunch", "event_data": { - "game_ids": [ - 9898 - ] + "game_ids": [9898] }, "start_minimized": true } ], - "game_events": [ - 9898 - ], + "game_events": [9898], "start_window": "background", "windows": { "background": { @@ -60,7 +52,10 @@ "width": 1920, "height": 1080 }, - "desktop_only": true + "desktop_only": true, + "block_top_window_navigation": true, + "popup_blocker": true, + "mute": true }, "in_game": { "file": "Files/index.html", @@ -87,9 +82,6 @@ } } }, - "block_top_window_navigation": true, - "popup_blocker": true, - "mute": true, "force_browser": "user", "developer": { "enable_auto_refresh": true, @@ -97,4 +89,4 @@ "filter": "*.*" } } -} \ No newline at end of file +} diff --git a/template/src/app/components/App.tsx b/template/src/app/components/App.tsx index c935270..af35da7 100644 --- a/template/src/app/components/App.tsx +++ b/template/src/app/components/App.tsx @@ -18,7 +18,7 @@ export const App = () => { log( `Request screen: ${currentWindow}`, "src/app/components/App.tsx", - "useEffect" + "useEffect", ); })(); }, []); diff --git a/template/src/app/shared/store.ts b/template/src/app/shared/store.ts index 856bbe0..5ada278 100644 --- a/template/src/app/shared/store.ts +++ b/template/src/app/shared/store.ts @@ -7,9 +7,7 @@ const reduxStore = configureStore({ reducer, devTools: false, enhancers: (getDefaultEnchancers) => - getDefaultEnchancers().concat( - devToolsEnhancer({ port: 8081 }) - ), + getDefaultEnchancers().concat(devToolsEnhancer({ port: 8081 })), }); declare global { diff --git a/template/src/components/Feed/index.ts b/template/src/components/Feed/index.ts index f1fc742..75b8a9a 100644 --- a/template/src/components/Feed/index.ts +++ b/template/src/components/Feed/index.ts @@ -1 +1 @@ -export * from './Feed' +export * from "./Feed"; diff --git a/template/src/components/Loading/Loading.tsx b/template/src/components/Loading/Loading.tsx index 037a805..fed55a1 100644 --- a/template/src/components/Loading/Loading.tsx +++ b/template/src/components/Loading/Loading.tsx @@ -1 +1 @@ -export const Loading = () =>

Loading ...

+export const Loading = () =>

Loading ...

; diff --git a/template/src/components/Loading/index.ts b/template/src/components/Loading/index.ts index 8e9305d..618e384 100644 --- a/template/src/components/Loading/index.ts +++ b/template/src/components/Loading/index.ts @@ -1 +1 @@ -export * from './Loading' +export * from "./Loading"; diff --git a/template/src/components/Title/index.ts b/template/src/components/Title/index.ts index 9a3bed4..2a7f3c5 100644 --- a/template/src/components/Title/index.ts +++ b/template/src/components/Title/index.ts @@ -1 +1 @@ -export * from './Title' +export * from "./Title"; diff --git a/template/src/features/monetization/components/AdsSlot.tsx b/template/src/features/monetization/components/AdsSlot.tsx new file mode 100644 index 0000000..29a78fc --- /dev/null +++ b/template/src/features/monetization/components/AdsSlot.tsx @@ -0,0 +1,43 @@ +import { useOverwolfAds, type UseOverwolfAds } from "../hooks/useOverwolfAds"; +import "./styles/AdsSlot.css"; + +/** + * Renders an ads slot component. + * @see https://overwolf.github.io/start/monetize-your-app/advertising/working-with-ads#list-of-ad-sizes + * A simple, one Container layout + * Dimensions: 400x300 + * Revenue: Baseline + * Show Video Ads: Yes + * Design Constraints: Minimal + * User Friction: Minimal + * Policies: + * As such, you must also keep in mind the following: + * Do not create Ad experiences that are actively intrusive/clash with the app's basic usage. + * No more than one video Ad container may be placed on a single page at any moment. + * Any manipulation of or interference with the ads integration is not allowed - Bots, auto clickers, constant page reloading, faking impressions, etc. + * Ads may not be placed on dead end/empty screens. This includes: "Thank You" pages, "Login" pages, "Dialogue/Error/Notification", pages Etc + * @test How to test: https://overwolf.github.io/start/test-your-app/how-to-test-your-app#testing-ad-visibility + * @returns The rendered ads slot component. + */ +export function AdsSlot(size: UseOverwolfAds) { + const { containerRef, isPlaying } = useOverwolfAds(size); + return ( +
+ {isPlaying ? null : ( + <> +
+

Ads Slot 400x300

+ + )} +
+ ); +} diff --git a/template/src/features/monetization/components/GetPremium.tsx b/template/src/features/monetization/components/GetPremium.tsx new file mode 100644 index 0000000..1680101 --- /dev/null +++ b/template/src/features/monetization/components/GetPremium.tsx @@ -0,0 +1,12 @@ +import { openSubscribeWindow } from "../hooks/useAdRemoval"; +import "./styles/GetPremium.css"; + +export function GetPremium() { + return ( +
+ +
+ ); +} diff --git a/template/src/features/monetization/components/styles/AdsSlot.css b/template/src/features/monetization/components/styles/AdsSlot.css new file mode 100644 index 0000000..83a0740 --- /dev/null +++ b/template/src/features/monetization/components/styles/AdsSlot.css @@ -0,0 +1,12 @@ +.ads-slot { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + width: 100%; + background-color: var(--secondary-color-dark); + padding: 20px; +} +.ads-slot__placeholder { + padding: 10px; +} diff --git a/template/src/features/monetization/components/styles/GetPremium.css b/template/src/features/monetization/components/styles/GetPremium.css new file mode 100644 index 0000000..01bf884 --- /dev/null +++ b/template/src/features/monetization/components/styles/GetPremium.css @@ -0,0 +1,29 @@ +.get-premium { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100%; + width: 100%; + padding: 20px; + box-sizing: border-box; +} +/* //create a beautiful button */ +.get-premium__button { + display: flex; + align-items: center; + justify-content: center; + height: 50px; + width: 100%; + background-color: var(--neutral-1); + color: var(--primary-color-text); + font-size: var(--font-size-medium); + font-weight: var(--font-weight); + border-radius: 5px; + cursor: pointer; + transition: background-color 0.2s ease-in-out; +} + +.get-premium__button:hover { + background-color: var(--neutral-2); +} diff --git a/template/src/features/monetization/constants.ts b/template/src/features/monetization/constants.ts new file mode 100644 index 0000000..02942ba --- /dev/null +++ b/template/src/features/monetization/constants.ts @@ -0,0 +1,4 @@ +export const OWADS_URL = + "https://content.overwolf.com/libs/ads/latest/owads.min.js"; +export const INJECTED_OWADS_ID = "owads-injected"; +export const SUBSCRIPTION_ID = 123; diff --git a/template/src/features/monetization/hooks/useAdRemoval.ts b/template/src/features/monetization/hooks/useAdRemoval.ts new file mode 100644 index 0000000..f5f6686 --- /dev/null +++ b/template/src/features/monetization/hooks/useAdRemoval.ts @@ -0,0 +1,86 @@ +import { useEffect, useState } from "react"; +import { SUBSCRIPTION_ID } from "../constants"; +import { isDev, sleep } from "lib/utils"; +import { log } from "lib/log"; + +async function openSubscribeWindow() { + if (isDev) { + log( + "dev mode, not opening subscribe window", + "src/features/monetization/hooks/useAdRemoval.ts", + "openSubscribeWindow" + ); + return; + } + const UID = await new Promise((resolve, reject) => { + overwolf.extensions.current.getManifest((manifest) => { + if (manifest) { + resolve(manifest.UID); + } else { + reject(null); + } + }); + }); + overwolf.utils.openStore({ + page: "SubscriptionPage" as overwolf.utils.enums.eStorePage.SubscriptionPage, + uid: UID, + }); +} + +const useAdRemoval = () => { + const [isSubscribed, setIsSubscribed] = useState(false); + const [isLoading, setIsLoading] = useState(true); + // Function to handle the subscription change event + + const handleSubscriptionState = () => { + setIsSubscribed(true); + }; + + useEffect(() => { + if (isDev) { + setIsSubscribed(false); + setIsLoading(false); + return; + } + // console.log('plan', subscriptionId) + // Subscribe to the subscription change event + const handleSubscriptionChange = async ( + info: overwolf.profile.subscriptions.SubscriptionChangedEvent + ) => { + setIsLoading(true); + console.log("Subscription changed", info); + if (Array.isArray(info?.plans) && info.plans.includes(SUBSCRIPTION_ID)) { + handleSubscriptionState(); + } + await sleep(3_000); + setIsLoading(false); + }; + + overwolf.profile.subscriptions.getActivePlans(async (info) => { + console.log("Active plans", info); + if ( + info.success && + Array.isArray(info?.plans) && + info.plans.includes(SUBSCRIPTION_ID) + ) { + handleSubscriptionState(); + } + await sleep(3_000); + setIsLoading(false); + }); + overwolf.profile.subscriptions.onSubscriptionChanged.addListener( + handleSubscriptionChange + ); + + // Unsubscribe from the event when the component unmounts + return () => { + overwolf.profile.subscriptions.onSubscriptionChanged.removeListener( + handleSubscriptionChange + ); + }; + }, []); + + return { isSubscribed, isLoading }; +}; + +export { useAdRemoval, openSubscribeWindow }; diff --git a/template/src/features/monetization/hooks/useOverwolfAds.ts b/template/src/features/monetization/hooks/useOverwolfAds.ts new file mode 100644 index 0000000..0fd553c --- /dev/null +++ b/template/src/features/monetization/hooks/useOverwolfAds.ts @@ -0,0 +1,100 @@ +import type { OwAd } from "@overwolf/types/owads"; +import { useEffect, useRef, useState } from "react"; +import { INJECTED_OWADS_ID, OWADS_URL } from "../constants"; +import { log } from "lib/log"; +import { isDev, sleep } from "lib/utils"; + +declare global { + interface Window { + OwAd?: typeof OwAd; + } +} + +export type UseOverwolfAds = Record<"width" | "height", number>; + +export function useOverwolfAds({ width, height }: UseOverwolfAds) { + const containerRef = useRef(null); + const [isLoading, setIsLoading] = useState(true); + const [isPlaying, setIsPlaying] = useState(false); + + useEffect(() => { + if (width === 0 || height === 0) { + log( + "width === 0 || height === 0", + "src/features/monetization/hooks/useOverwolfAds.ts", + "useOverwolfAds" + ); + + return; + } + + let owAds: OwAd | undefined; + function onOwAdReady() { + if ( + typeof window.OwAd === "undefined" || + containerRef.current === null || + isDev + ) { + return setIsLoading(false); + } + owAds = new window.OwAd(containerRef.current, { + size: { width, height }, + }); + + owAds.addEventListener("player_loaded ", () => { + log( + "player_loaded", + "src/features/monetization/hooks/useOverwolfAds.ts", + "useOverwolfAds" + ); + }); + + owAds.addEventListener("play", () => { + setIsPlaying(true); + }); + + // owAds.addEventListener('display_ad_loaded', () => { + // setIsPlaying(true); + // }); + + // owAds.addEventListener('impression', () => { + // setIsPlaying(true); + // }); + + // owAds.addEventListener('complete', async () => { + // await sleep(1000); + // setIsPlaying(false); + // }); + owAds.addEventListener("error", async () => { + await sleep(1000); + setIsPlaying(false); + }); + } + + const script = document.createElement("script"); + script.id = INJECTED_OWADS_ID; + + if (document.getElementById(INJECTED_OWADS_ID)) { + onOwAdReady(); + } else { + script.src = OWADS_URL; + script.async = true; + document.body.appendChild(script); + script.onload = onOwAdReady; + } + return () => { + if (document.getElementById(INJECTED_OWADS_ID)) + document.body.removeChild(script); + //remove event listeners if you enabled them + ["player_loaded", "play", "display_ad_loaded"].forEach((event) => { + owAds?.removeEventListener(event, () => {}); + }); + }; + }, [width, height]); + + return { + isLoading, + containerRef, + isPlaying, + }; +} diff --git a/template/src/features/monetization/index.ts b/template/src/features/monetization/index.ts new file mode 100644 index 0000000..766a5a3 --- /dev/null +++ b/template/src/features/monetization/index.ts @@ -0,0 +1,3 @@ +export * from "./components/AdsSlot"; +export * from "./components/GetPremium"; +export * from "./hooks/useAdRemoval"; diff --git a/template/src/features/overview/components/Overview.tsx b/template/src/features/overview/components/Overview.tsx index b61880f..301b511 100644 --- a/template/src/features/overview/components/Overview.tsx +++ b/template/src/features/overview/components/Overview.tsx @@ -6,7 +6,7 @@ export const Overview = () => { const { events, infos } = useData(); return ( -
+
diff --git a/template/src/features/overview/components/Stats.tsx b/template/src/features/overview/components/Stats.tsx index febf8e4..08e5701 100644 --- a/template/src/features/overview/components/Stats.tsx +++ b/template/src/features/overview/components/Stats.tsx @@ -7,9 +7,9 @@ type StatsProps = { export const Stats = ({ label, value }: StatsProps) => { return ( -
- {label} - {value} +
+ {label} + {value}
); }; diff --git a/template/src/features/overview/hooks/useData.ts b/template/src/features/overview/hooks/useData.ts index f52bea6..63b77d2 100644 --- a/template/src/features/overview/hooks/useData.ts +++ b/template/src/features/overview/hooks/useData.ts @@ -1,6 +1,7 @@ import { RootReducer } from "app/shared/rootReducer"; import { useMemo } from "react"; import { useSelector } from "react-redux"; +import { fromNow } from "lib/utils"; type Attributes = { quantity: number; @@ -9,8 +10,7 @@ type Attributes = { type DataLabel = "events" | "infos"; type Data = Record; -const getAveragePerMinute = (quantity: number) => - `${Math.floor(quantity ?? 1 / 60)} per minute`; +const getUpdatedAt = (date: number): string => `updated: ${fromNow(date)}`; export const useData = () => { const { events, infos } = useSelector( @@ -24,11 +24,15 @@ export const useData = () => { return { events: { quantity: eventsQuantity, - label: `Events (${getAveragePerMinute(eventsQuantity)})`, + label: `Events (${getUpdatedAt( + events[eventsQuantity - 1]?.timestamp ?? Date.now() + )})`, }, infos: { quantity: infosQuantity, - label: `Infos (${getAveragePerMinute(infosQuantity)})`, + label: `Infos (${getUpdatedAt( + infos[infosQuantity - 1]?.timestamp ?? Date.now() + )})`, }, }; }, [events, infos]); diff --git a/template/src/index.tsx b/template/src/index.tsx index cfed71e..d93fbf8 100644 --- a/template/src/index.tsx +++ b/template/src/index.tsx @@ -33,7 +33,7 @@ overwolf.settings.language.get(({ language }) => { }, () => { root.render(); - } + }, ); }); // If you want to start measuring performance in your app, pass a function diff --git a/template/src/lib/games.ts b/template/src/lib/games.ts index 1180aaf..4865a71 100644 --- a/template/src/lib/games.ts +++ b/template/src/lib/games.ts @@ -4,7 +4,7 @@ export function getHearthstoneGame(): Promise { overwolf.games.getRunningGameInfo((result) => { resolve( - result && result.classId === HEARTHSTONE_CLASS_ID ? result : null + result && result.classId === HEARTHSTONE_CLASS_ID ? result : null, ); }); }); diff --git a/template/src/lib/io.ts b/template/src/lib/io.ts index 96919b4..afe76c7 100644 --- a/template/src/lib/io.ts +++ b/template/src/lib/io.ts @@ -23,7 +23,7 @@ const getLocalAppData = (fileName: number | string) => new Promise((resolve) => { overwolf.extensions.current.getManifest(({ UID }) => { const path = `${overwolf.io.paths.localAppData}${getExtensionRootPath( - UID + UID, )}\\${fileName}.json`; resolve(path); }); @@ -64,10 +64,10 @@ const writeFileContents = (path: string, data: T) => (status) => { if (!status.success) resolve(status.error ?? "Unknown error"); const message = `Saved in ${path} with status ${status}, data size: ${getFileSize( - JSON.stringify(data) + JSON.stringify(data), )}`; resolve(message); - } + }, ); }); diff --git a/template/src/lib/log.ts b/template/src/lib/log.ts index 1329233..1084ac7 100644 --- a/template/src/lib/log.ts +++ b/template/src/lib/log.ts @@ -1,7 +1,7 @@ const log = (message: string, component: string, method: string) => { console.info( `%c[🐺 overwolf-modern-react-boilerplate][🧰 ${component}][🔧 ${method}][📃 ${message} ]`, - "background: #262626; color: #e4e4e7; padding: 2px 0; border-radius: 2px; font-weight: bold; border: 1px solid #171717;" + "background: #262626; color: #e4e4e7; padding: 2px 0; border-radius: 2px; font-weight: bold; border: 1px solid #171717;", ); }; diff --git a/template/src/lib/overwolf-essentials.ts b/template/src/lib/overwolf-essentials.ts index d849124..48940d6 100644 --- a/template/src/lib/overwolf-essentials.ts +++ b/template/src/lib/overwolf-essentials.ts @@ -3,7 +3,7 @@ import { isDev } from "./utils"; import { log } from "./log"; async function obtainDeclaredWindow( - windowName: string + windowName: string, ): Promise { return new Promise((resolve, reject) => { overwolf.windows.obtainDeclaredWindow(windowName, (result) => { @@ -21,7 +21,7 @@ async function getCurrentWindow() { log( `Running in dev mode, returning ${WINDOW_NAMES.DESKTOP} window, you can change this in src/lib/overwolf-essentials.ts: getCurrent`, "src/lib/overwolf-essentials.ts", - "getCurrentWindow" + "getCurrentWindow", ); return Promise.resolve(WINDOW_NAMES.DESKTOP); } diff --git a/template/src/lib/utils.ts b/template/src/lib/utils.ts index 495a758..3db4692 100644 --- a/template/src/lib/utils.ts +++ b/template/src/lib/utils.ts @@ -19,18 +19,42 @@ const classNames = (...classes: (string | undefined)[]) => /** * Formats a date input into a string representation. * @param input The date input to format. It can be a string or a number. - * @example const formattedDate = formatDate(new Date()); + * @example const formattedDate = formatDate(Date.now()); * @returns A formatted string representation of the date. */ function formatDate(input: string | number): string { const date = new Date(input); return date.toLocaleDateString("en-US", { - month: "long", + month: "short", day: "numeric", year: "numeric", }); } +/** + * Formats a date input into a relative time representation. + * @param input The date input to format. It can be a string or a number. + * @example const relativeTime = fromNow(Date.now()); + * @returns A string representing the relative time from the input date. + */ +function fromNow(input: string | number): string { + const date = new Date(input); + const now = new Date(); + const seconds = Math.floor((now.getTime() - date.getTime()) / 1000); + const minutes = Math.floor(seconds / 60); + const hours = Math.floor(minutes / 60); + + if (seconds < 60) { + return "now"; + } else if (minutes < 60) { + return `${minutes}m`; + } else if (hours < 24) { + return `${hours}h`; + } else { + return formatDate(input); + } +} + /** * Generates a random number between the specified minimum and maximum values (inclusive). * @param min The minimum value of the range. @@ -105,4 +129,5 @@ export { parseSafeJSON, sleep, isDev, + fromNow, }; diff --git a/template/src/overwolf.dev.mock.ts b/template/src/overwolf.dev.mock.ts index 325f089..c2adb4c 100644 --- a/template/src/overwolf.dev.mock.ts +++ b/template/src/overwolf.dev.mock.ts @@ -18,7 +18,7 @@ class MockCommonMethods { } static simpleRequestInterval( interval: number, - callback: overwolf.CallbackFunction + callback: overwolf.CallbackFunction, ): void { console.info(`Callback interval ${interval}`); callback({ success: true }); @@ -46,7 +46,7 @@ const overwolfMock: typeof overwolf = { requestHardwareInfo: MockCommonMethods.simpleRequestInterval, requestProcessInfo: MockCommonMethods.simpleRequestInterval, requestPermissions: ( - callback: overwolf.CallbackFunction + callback: overwolf.CallbackFunction, ) => { callback({ success: true }); }, @@ -56,7 +56,9 @@ const overwolfMock: typeof overwolf = { settings: { language: { get: ( - callback: (result: overwolf.settings.language.GetLanguageResult) => void + callback: ( + result: overwolf.settings.language.GetLanguageResult, + ) => void, ) => { console.info("get language"); callback({ language: "en", success: true }); @@ -64,16 +66,16 @@ const overwolfMock: typeof overwolf = { onLanguageChanged: { addListener: ( callback: ( - payload: overwolf.settings.language.LanguageChangedEvent - ) => void + payload: overwolf.settings.language.LanguageChangedEvent, + ) => void, ) => { console.log("onLanguageChanged addListener"); callback({ language: "en" }); }, removeListener: ( callback: ( - payload: overwolf.settings.language.LanguageChangedEvent - ) => void + payload: overwolf.settings.language.LanguageChangedEvent, + ) => void, ) => { callback({ language: "en" }); }, @@ -96,7 +98,7 @@ const overwolfMock: typeof overwolf = { //@ts-ignore obtainDeclaredWindow( windowName: string, - callback: (response: any) => void + callback: (response: any) => void, ): void { callback({ window: { name: windowName }, success: true }); }, @@ -148,7 +150,7 @@ const overwolfMock: typeof overwolf = { onMouseDown: MockCommonMethods, onMouseUp: MockCommonMethods, getMousePosition: ( - callback: overwolf.CallbackFunction + callback: overwolf.CallbackFunction, ) => { callback({ success: true, @@ -169,7 +171,7 @@ const overwolfMock: typeof overwolf = { }); }, getActivityInformation: ( - callback: overwolf.CallbackFunction + callback: overwolf.CallbackFunction, ) => { callback({ success: true, @@ -190,7 +192,7 @@ const overwolfMock: typeof overwolf = { }); }, getEyeTrackingInformation: ( - callback: overwolf.CallbackFunction + callback: overwolf.CallbackFunction, ) => { callback({ success: true, diff --git a/template/src/screens/background/components/Screen.tsx b/template/src/screens/background/components/Screen.tsx index 1d6b2e4..c5b62a1 100644 --- a/template/src/screens/background/components/Screen.tsx +++ b/template/src/screens/background/components/Screen.tsx @@ -18,8 +18,20 @@ const BackgroundWindow = () => { const [ingame] = useWindow(INGAME, DISPLAY_OVERWOLF_HOOKS_LOGS); const { start, stop } = useGameEventProvider( { - onInfoUpdates: (info) => store.dispatch(setInfo(info)), - onNewEvents: (events) => store.dispatch(setEvent(events)), + onInfoUpdates: (info) => + store.dispatch( + setInfo({ + ...info, + timestamp: Date.now(), + }) + ), + onNewEvents: (events) => + store.dispatch( + setEvent({ + ...events, + timestamp: Date.now(), + }) + ), }, REQUIRED_FEATURES, RETRY_TIMES, @@ -50,8 +62,9 @@ const BackgroundWindow = () => { startApp("onGameInfoUpdated"); } }); - startApp("onAppLaunchTriggered"); - + overwolf.extensions.onAppLaunchTriggered.addListener(() => { + startApp("onAppLaunchTriggered"); + }); return () => { overwolf.games.onGameInfoUpdated.removeListener(() => {}); overwolf.extensions.onAppLaunchTriggered.removeListener(() => {}); diff --git a/template/src/screens/background/stores/background.ts b/template/src/screens/background/stores/background.ts index 94bdb71..a1538a0 100644 --- a/template/src/screens/background/stores/background.ts +++ b/template/src/screens/background/stores/background.ts @@ -1,15 +1,18 @@ import { createSlice, PayloadAction } from "@reduxjs/toolkit"; +interface Timestamp { + timestamp: number; +} type OwInfo = | overwolf.games.events.InfoUpdates2Event | overwolf.games.InstalledGameInfo; type OwEvent = overwolf.games.events.NewGameEvents; -type InfoPayload = PayloadAction; -type EventPayload = PayloadAction; +type InfoPayload = PayloadAction; +type EventPayload = PayloadAction; interface BackgroundState { - events: Array; - infos: Array; + events: Array; + infos: Array; } const initialState: BackgroundState = { diff --git a/template/src/screens/desktop/components/DesktopHeader.tsx b/template/src/screens/desktop/components/DesktopHeader.tsx index 80fcade..e1263e5 100644 --- a/template/src/screens/desktop/components/DesktopHeader.tsx +++ b/template/src/screens/desktop/components/DesktopHeader.tsx @@ -21,7 +21,7 @@ export const DesktopHeader = () => { const [backgroundWindow] = useWindow(BACKGROUND, DISPLAY_OVERWOLF_HOOKS_LOGS); const { onDragStart, onMouseMove, setCurrentWindowID } = useDrag( null, - DISPLAY_OVERWOLF_HOOKS_LOGS + DISPLAY_OVERWOLF_HOOKS_LOGS, ); const toggleIcon = useCallback(() => { @@ -53,50 +53,50 @@ export const DesktopHeader = () => { onClick={handleDiscordClick} > - + -
diff --git a/template/src/screens/desktop/components/DesktopHeaderSVG.tsx b/template/src/screens/desktop/components/DesktopHeaderSVG.tsx index 19aec43..6f6d5f9 100644 --- a/template/src/screens/desktop/components/DesktopHeaderSVG.tsx +++ b/template/src/screens/desktop/components/DesktopHeaderSVG.tsx @@ -1,5 +1,5 @@ export const SVGComponent = () => ( - + ( /> -) +); diff --git a/template/src/screens/desktop/components/FreeContent.tsx b/template/src/screens/desktop/components/FreeContent.tsx new file mode 100644 index 0000000..991fbaf --- /dev/null +++ b/template/src/screens/desktop/components/FreeContent.tsx @@ -0,0 +1,11 @@ +import { AdsSlot, GetPremium } from "features/monetization"; + +//avoid the use of static text, use i18n instead, each language has its own text, and the text is stored in the +//locales folder in the project root + +export const FreeContent = () => ( + <> + + + +); diff --git a/template/src/screens/desktop/components/PremiumContent.tsx b/template/src/screens/desktop/components/PremiumContent.tsx new file mode 100644 index 0000000..0c8dcff --- /dev/null +++ b/template/src/screens/desktop/components/PremiumContent.tsx @@ -0,0 +1 @@ +export const PremiumContent = () =>

Premium Content

; diff --git a/template/src/screens/desktop/components/Screen.tsx b/template/src/screens/desktop/components/Screen.tsx index 24d22be..4abba48 100644 --- a/template/src/screens/desktop/components/Screen.tsx +++ b/template/src/screens/desktop/components/Screen.tsx @@ -1,12 +1,17 @@ import { Title } from "components/Title/Title"; import { useTranslation } from "react-i18next"; import { DesktopHeader } from "./DesktopHeader"; +import { Overview } from "features/overview"; +import { useAdRemoval } from "features/monetization"; import "./styles/Screen.css"; +import { PremiumContent } from "./PremiumContent"; +import { FreeContent } from "./FreeContent"; //avoid the use of static text, use i18n instead, each language has its own text, and the text is stored in the //locales folder in the project root const Screen = () => { const { t } = useTranslation(); + const { isLoading, isSubscribed } = useAdRemoval(); return (
@@ -19,11 +24,13 @@ const Screen = () => { {t("components.desktop.header")} -
+
{t("components.desktop.main")} +
-