diff --git a/website/src/App.tsx b/website/src/App.tsx index 9de524e..2a0bc3f 100644 --- a/website/src/App.tsx +++ b/website/src/App.tsx @@ -124,6 +124,7 @@ class App extends Component { wordlistReviewLanguage: "Pashto", wordlistReviewBadge: true, searchBarPosition: "top", + showPlayStoreButton: false, }, searchValue: "", page: 1, @@ -132,7 +133,7 @@ class App extends Component { wordlist: [], reviewTasks: [], user: readUser(), - inflectionSearchResults: undefined, + inflectionSearchResults: undefined }; this.handleOptionsUpdate = this.handleOptionsUpdate.bind(this); this.handleTextOptionsUpdate = this.handleTextOptionsUpdate.bind(this); @@ -145,9 +146,24 @@ class App extends Component { this.handleRefreshReviewTasks = this.handleRefreshReviewTasks.bind(this); this.handleDictionaryUpdate = this.handleDictionaryUpdate.bind(this); this.handleInflectionSearch = this.handleInflectionSearch.bind(this); + this.handlePlayStoreClick = this.handlePlayStoreClick.bind(this); } public componentDidMount() { + window.addEventListener('DOMContentLoaded', () => { + let displayMode = 'browser tab'; + if (window.matchMedia('(display-mode: standalone)').matches) { + displayMode = 'standalone'; + } + const userAgent = navigator.userAgent.toLowerCase(); + const isAndroid = userAgent.indexOf("android") > -1; + if (isAndroid && displayMode !== "standalone") { + saveOptions(optionsReducer(this.state.options, { + type: "setShowPlayStoreButton", + payload: true, + })); + } + }); window.addEventListener("scroll", this.handleScroll); if (!possibleLandingPages.includes(this.props.location.pathname)) { this.props.history.replace("/"); @@ -386,6 +402,13 @@ class App extends Component { }); } + private handlePlayStoreClick() { + saveOptions(optionsReducer(this.state.options, { + type: "setShowPlayStoreButton", + payload: false, + })); + } + private handleOptionsUpdate(action: OptionsAction) { if (action.type === "changeTheme") { document.documentElement.setAttribute("data-theme", action.payload); @@ -567,6 +590,11 @@ class App extends Component { Grammar + {this.state.options.showPlayStoreButton &&
+ + Get it on Google Play + +
} diff --git a/website/src/lib/local-storage.ts b/website/src/lib/local-storage.ts index a99be9e..2c88c01 100644 --- a/website/src/lib/local-storage.ts +++ b/website/src/lib/local-storage.ts @@ -27,6 +27,9 @@ export const readOptions = (): undefined | Options => { // compatibility with legacy options options.searchBarStickyFocus = false; } + if (!("showPlayStoreButton" in options)) { + options.showPlayStoreButton = false; + } return options; } catch (e) { console.error("error parsing saved state JSON", e); diff --git a/website/src/lib/options-reducer.ts b/website/src/lib/options-reducer.ts index 8e01f1c..18088a4 100644 --- a/website/src/lib/options-reducer.ts +++ b/website/src/lib/options-reducer.ts @@ -60,6 +60,12 @@ export function optionsReducer(options: Options, action: OptionsAction): Options searchBarStickyFocus: action.payload, } } + if (action.type === "setShowPlayStoreButton") { + return { + ...options, + showPlayStoreButton: action.payload, + } + } throw new Error("action type not recognized in options reducer"); } diff --git a/website/src/types/dictionary-types.ts b/website/src/types/dictionary-types.ts index 4e081a1..f9ff202 100644 --- a/website/src/types/dictionary-types.ts +++ b/website/src/types/dictionary-types.ts @@ -65,6 +65,7 @@ export type Options = { wordlistReviewBadge: boolean, searchBarPosition: SearchBarPosition, searchBarStickyFocus: boolean, + showPlayStoreButton: boolean, } export type Language = "Pashto" | "English"; @@ -109,7 +110,10 @@ export type OptionsAction = { } | { type: "changeSearchBarStickyFocus", payload: boolean, -} +} | { + type: "setShowPlayStoreButton", + payload: boolean, +}; export type TextOptionsAction = { type: "changePTextSize",