From cf36ced2a7c6f3a456684d97b329a9125cc956ea Mon Sep 17 00:00:00 2001 From: David Ralph Date: Fri, 2 Jul 2021 21:29:33 +0100 Subject: [PATCH] feat: new welcome modal, refactor many things, various bug fixes, use material-ui v5 etc Co-authored-by: Alex Sparkes --- package.json | 18 +- public/icons/undraw_add_files_modified.svg | 34 ++++ .../undraw_around_the_world_modified.svg | 40 ++++ public/icons/undraw_by_the_road.svg | 1 + public/icons/undraw_dark_mode.svg | 1 + public/icons/undraw_on_the_way.svg | 1 + public/icons/undraw_private_data_modified.svg | 13 ++ public/icons/undraw_upgrade_modified.svg | 51 +++++ src/App.jsx | 8 +- src/components/modals/Modals.jsx | 6 +- src/components/modals/main/Main.jsx | 6 +- .../modals/main/marketplace/Item.jsx | 2 +- .../modals/main/marketplace/Items.jsx | 2 +- src/components/modals/main/scss/index.scss | 4 + .../modals/main/settings/Checkbox.jsx | 8 +- .../modals/main/settings/Switch.jsx | 6 +- .../modals/main/settings/sections/About.jsx | 4 +- .../main/settings/sections/Advanced.jsx | 16 +- .../main/settings/sections/Changelog.jsx | 2 +- .../modals/main/settings/sections/Order.jsx | 2 - .../main/settings/sections/QuickLinks.jsx | 2 +- .../modals/main/settings/sections/Search.jsx | 1 - .../sections/background/Background.jsx | 2 +- .../settings/sections/background/Colour.jsx | 2 +- src/components/modals/main/tabs/Addons.jsx | 4 +- .../modals/main/tabs/Marketplace.jsx | 6 +- src/components/modals/main/tabs/Settings.jsx | 28 +-- .../modals/main/tabs/backend/Tabs.jsx | 14 +- src/components/modals/welcome/ProgressBar.jsx | 16 ++ src/components/modals/welcome/Welcome.jsx | 85 ++++++--- .../modals/welcome/WelcomeSections.jsx | 156 +++++++++++++++ src/components/modals/welcome/welcome.scss | 177 +++++++++++++----- src/components/widgets/Widgets.jsx | 5 + .../widgets/background/Background.jsx | 15 +- .../widgets/background/Favourite.jsx | 2 +- src/components/widgets/greeting/Greeting.jsx | 6 +- src/components/widgets/navbar/Navbar.jsx | 4 + src/components/widgets/navbar/Notes.jsx | 6 +- src/components/widgets/navbar/Pin.jsx | 24 --- .../widgets/quicklinks/QuickLinks.jsx | 8 +- src/components/widgets/quote/Quote.jsx | 4 + src/components/widgets/time/Clock.jsx | 4 + src/components/widgets/time/Date.jsx | 4 + src/index.js | 3 +- src/modules/constants.js | 4 +- .../{settings.js => settings/index.js} | 81 ++------ src/modules/helpers/settings/modals.js | 40 ++++ src/modules/helpers/stats.js | 128 ++++++------- src/scss/_variables.scss | 4 +- src/scss/index.scss | 2 +- src/scss/modules/_buttons.scss | 24 +++ src/translations/de_DE.json | 2 +- src/translations/en_GB.json | 2 +- src/translations/en_US.json | 2 +- src/translations/es.json | 2 +- src/translations/fr.json | 2 +- src/translations/nl.json | 2 +- src/translations/no.json | 2 +- src/translations/ru.json | 2 +- src/translations/zh_CN.json | 2 +- webpack.config.js | 2 +- 61 files changed, 782 insertions(+), 324 deletions(-) create mode 100644 public/icons/undraw_add_files_modified.svg create mode 100644 public/icons/undraw_around_the_world_modified.svg create mode 100644 public/icons/undraw_by_the_road.svg create mode 100644 public/icons/undraw_dark_mode.svg create mode 100644 public/icons/undraw_on_the_way.svg create mode 100644 public/icons/undraw_private_data_modified.svg create mode 100644 public/icons/undraw_upgrade_modified.svg create mode 100644 src/components/modals/welcome/ProgressBar.jsx create mode 100644 src/components/modals/welcome/WelcomeSections.jsx delete mode 100644 src/components/widgets/navbar/Pin.jsx rename src/modules/helpers/{settings.js => settings/index.js} (71%) create mode 100644 src/modules/helpers/settings/modals.js diff --git a/package.json b/package.json index c5d8c1d1..cc5bd554 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,8 @@ "dependencies": { "@fontsource/lexend-deca": "^4.4.5", "@fontsource/montserrat": "^4.4.5", - "@material-ui/core": "4.11.4", - "@material-ui/icons": "4.11.2", + "@material-ui/core": "5.0.0-beta.0", + "@material-ui/icons": "5.0.0-beta.0", "fetch-jsonp": "^1.1.3", "react": "17.0.2", "react-clock": "3.0.0", @@ -28,26 +28,26 @@ }, "devDependencies": { "@babel/core": "^7.14.6", - "@babel/eslint-parser": "^7.14.5", + "@babel/eslint-parser": "^7.14.7", "@babel/plugin-proposal-class-properties": "^7.14.5", "@babel/plugin-transform-react-constant-elements": "^7.13.15", "@babel/plugin-transform-runtime": "^7.14.5", - "@babel/preset-env": "^7.14.5", + "@babel/preset-env": "^7.14.7", "@babel/preset-react": "^7.14.5", "babel-loader": "^8.2.2", "babel-plugin-transform-react-class-to-function": "^1.2.2", - "copy-webpack-plugin": "^9.0.0", + "copy-webpack-plugin": "^9.0.1", "css-loader": "^5.2.6", - "eslint": "^7.28.0", + "eslint": "^7.29.0", "eslint-config-react-app": "^6.0.0", - "html-webpack-plugin": "^5.3.1", + "html-webpack-plugin": "^5.3.2", "mini-css-extract-plugin": "^1.6.0", "sass": "^1.35.1", "sass-loader": "^12.1.0", "source-map-loader": "^3.0.0", - "webpack": "^5.39.1", + "webpack": "^5.41.1", "webpack-cli": "^4.7.2", - "webpack-dev-server": "^3.11.2" + "webpack-dev-server": "^4.0.0-beta.3" }, "scripts": { "start": "webpack serve", diff --git a/public/icons/undraw_add_files_modified.svg b/public/icons/undraw_add_files_modified.svg new file mode 100644 index 00000000..3d7192ee --- /dev/null +++ b/public/icons/undraw_add_files_modified.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/icons/undraw_around_the_world_modified.svg b/public/icons/undraw_around_the_world_modified.svg new file mode 100644 index 00000000..ea412f5d --- /dev/null +++ b/public/icons/undraw_around_the_world_modified.svg @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/icons/undraw_by_the_road.svg b/public/icons/undraw_by_the_road.svg new file mode 100644 index 00000000..0720b4dc --- /dev/null +++ b/public/icons/undraw_by_the_road.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/icons/undraw_dark_mode.svg b/public/icons/undraw_dark_mode.svg new file mode 100644 index 00000000..e62a3770 --- /dev/null +++ b/public/icons/undraw_dark_mode.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/icons/undraw_on_the_way.svg b/public/icons/undraw_on_the_way.svg new file mode 100644 index 00000000..0602804b --- /dev/null +++ b/public/icons/undraw_on_the_way.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/icons/undraw_private_data_modified.svg b/public/icons/undraw_private_data_modified.svg new file mode 100644 index 00000000..18199c1b --- /dev/null +++ b/public/icons/undraw_private_data_modified.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/icons/undraw_upgrade_modified.svg b/public/icons/undraw_upgrade_modified.svg new file mode 100644 index 00000000..451d0c4a --- /dev/null +++ b/public/icons/undraw_upgrade_modified.svg @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/App.jsx b/src/App.jsx index 4135e71d..72a40f0b 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -11,14 +11,10 @@ import { ToastContainer } from 'react-toastify'; export default class App extends React.PureComponent { componentDidMount() { - if (!localStorage.getItem('firstRun')) { - SettingsFunctions.setDefaultSettings(); - window.location.reload(); - } - // 4.0 -> 5.0 (the key below is only on 5.0) // now featuring 5.0 -> 5.1 - if (!localStorage.getItem('order') || !localStorage.getItem('backgroundFilterAmount')) { + // the firstRun check was moved here because the old function was useless + if (!localStorage.getItem('firstRun') || !localStorage.getItem('order') || !localStorage.getItem('backgroundFilterAmount')) { SettingsFunctions.moveSettings(); window.location.reload(); } diff --git a/src/components/modals/Modals.jsx b/src/components/modals/Modals.jsx index 9948a630..5995adc9 100644 --- a/src/components/modals/Modals.jsx +++ b/src/components/modals/Modals.jsx @@ -1,5 +1,7 @@ import React from 'react'; +import EventBus from '../../modules/helpers/eventbus'; + import Main from './main/Main'; import Navbar from '../widgets/navbar/Navbar'; @@ -39,6 +41,8 @@ export default class Modals extends React.PureComponent { this.setState({ welcomeModal: false }); + EventBus.dispatch('refresh', 'widgets'); + EventBus.dispatch('refresh', 'backgroundwelcome'); } toggleModal(type, action) { @@ -59,7 +63,7 @@ export default class Modals extends React.PureComponent {
this.toggleModal('mainModal', false)}/> - this.closeWelcome()} isOpen={this.state.welcomeModal} className='Modal welcomemodal mainModal' overlayClassName='Overlay' ariaHideApp={false}> + this.closeWelcome()} isOpen={this.state.welcomeModal} className='Modal welcomemodal mainModal' overlayClassName='Overlay welcomeoverlay' shouldCloseOnOverlayClick={false} ariaHideApp={false}> this.closeWelcome()}/> this.toggleModal('feedbackModal', false)} isOpen={this.state.feedbackModal} className='Modal mainModal' overlayClassName='Overlay' ariaHideApp={false}> diff --git a/src/components/modals/main/Main.jsx b/src/components/modals/main/Main.jsx index 8259eee6..cc09c306 100644 --- a/src/components/modals/main/Main.jsx +++ b/src/components/modals/main/Main.jsx @@ -29,17 +29,17 @@ export default function MainModal(props) { <> × -
+
-
+
-
+
diff --git a/src/components/modals/main/marketplace/Item.jsx b/src/components/modals/main/marketplace/Item.jsx index 52a853ee..bb0c806a 100644 --- a/src/components/modals/main/marketplace/Item.jsx +++ b/src/components/modals/main/marketplace/Item.jsx @@ -34,7 +34,7 @@ export default class Item extends React.PureComponent { } // prevent console error - let iconsrc = window.constants.DDG_PROXY + this.props.data.icon; + let iconsrc = window.constants.DDG_IMAGE_PROXY + this.props.data.icon; if (!this.props.data.icon) { iconsrc = null; } diff --git a/src/components/modals/main/marketplace/Items.jsx b/src/components/modals/main/marketplace/Items.jsx index 2fe5d437..02f8a958 100644 --- a/src/components/modals/main/marketplace/Items.jsx +++ b/src/components/modals/main/marketplace/Items.jsx @@ -3,7 +3,7 @@ export default function Items(props) {
{props.items.map((item) => (
props.toggleFunction(item.name)} key={item.name}> - icon + icon

{item.display_name || item.name}

{item.author}

diff --git a/src/components/modals/main/scss/index.scss b/src/components/modals/main/scss/index.scss index 7d85aee9..2c2cdd73 100644 --- a/src/components/modals/main/scss/index.scss +++ b/src/components/modals/main/scss/index.scss @@ -410,3 +410,7 @@ h3 { h5 { font-size: 0.8rem; } + +.checkbox svg { + fill: var(--modal-text) !important; +} diff --git a/src/components/modals/main/settings/Checkbox.jsx b/src/components/modals/main/settings/Checkbox.jsx index 0652d563..034d94b7 100644 --- a/src/components/modals/main/settings/Checkbox.jsx +++ b/src/components/modals/main/settings/Checkbox.jsx @@ -1,7 +1,6 @@ import React from 'react'; import EventBus from '../../../../modules/helpers/eventbus'; -import SettingsFunctions from '../../../../modules/helpers/settings'; import CheckboxUI from '@material-ui/core/Checkbox'; import FormControlLabel from '@material-ui/core/FormControlLabel'; @@ -15,10 +14,11 @@ export default class Checkbox extends React.PureComponent { } handleChange = () => { - SettingsFunctions.setItem(this.props.name); + const value = (this.state.checked === true) ? false : true; + localStorage.setItem(this.props.name, value); this.setState({ - checked: (this.state.checked === true) ? false : true + checked: value }); window.stats.postEvent('setting', `${this.props.name} ${(this.state.checked === true) ? 'enabled' : 'disabled'}`); @@ -45,7 +45,7 @@ export default class Checkbox extends React.PureComponent { return ( <> } + control={} label={text} />
diff --git a/src/components/modals/main/settings/Switch.jsx b/src/components/modals/main/settings/Switch.jsx index f7a295fe..9bb21a41 100644 --- a/src/components/modals/main/settings/Switch.jsx +++ b/src/components/modals/main/settings/Switch.jsx @@ -1,7 +1,6 @@ import React from 'react'; import EventBus from '../../../../modules/helpers/eventbus'; -import SettingsFunctions from '../../../../modules/helpers/settings'; import SwitchUI from '@material-ui/core/Switch'; import FormControlLabel from '@material-ui/core/FormControlLabel'; @@ -15,10 +14,11 @@ export default class Switch extends React.PureComponent { } handleChange = () => { - SettingsFunctions.setItem(this.props.name); + const value = (this.state.checked === true) ? false : true; + localStorage.setItem(this.props.name, value); this.setState({ - checked: (this.state.checked === true) ? false : true + checked: value }); window.stats.postEvent('setting', `${this.props.name} ${(this.state.checked === true) ? 'enabled' : 'disabled'}`); diff --git a/src/components/modals/main/settings/sections/About.jsx b/src/components/modals/main/settings/sections/About.jsx index 3e2bba5c..74d61783 100644 --- a/src/components/modals/main/settings/sections/About.jsx +++ b/src/components/modals/main/settings/sections/About.jsx @@ -3,7 +3,7 @@ import React from 'react'; import Tooltip from '../../../../helpers/tooltip/Tooltip'; import EmailIcon from '@material-ui/icons/Email'; import TwitterIcon from '@material-ui/icons/Twitter'; -import ForumIcon from '@material-ui/icons/Forum'; +import ChatIcon from '@material-ui/icons/Chat'; import InstagramIcon from '@material-ui/icons/Instagram'; import FacebookIcon from '@material-ui/icons/Facebook'; @@ -96,7 +96,7 @@ export default class About extends React.PureComponent { - +

{this.language.support_mue}

diff --git a/src/components/modals/main/settings/sections/Advanced.jsx b/src/components/modals/main/settings/sections/Advanced.jsx index fa64bb6e..2c08af41 100644 --- a/src/components/modals/main/settings/sections/Advanced.jsx +++ b/src/components/modals/main/settings/sections/Advanced.jsx @@ -6,9 +6,8 @@ import Text from '../Text'; import Switch from '../Switch'; import ResetModal from '../ResetModal'; -import SettingsFunctions from '../../../../../modules/helpers/settings'; +import SettingsFunctions from '../../../../../modules/helpers/settings/modals'; -import { toast } from 'react-toastify'; import Modal from 'react-modal'; export default class AdvancedSettings extends React.PureComponent { @@ -20,17 +19,6 @@ export default class AdvancedSettings extends React.PureComponent { this.language = window.language.modals.main.settings; } - settingsImport(e) { - const content = JSON.parse(e.target.result); - - Object.keys(content).forEach((key) => { - localStorage.setItem(key, content[key]); - }); - - toast(window.language.toasts.imported); - window.stats.postEvent('tab', 'Settings imported'); - } - render() { const { advanced } = this.language.sections; @@ -43,7 +31,7 @@ export default class AdvancedSettings extends React.PureComponent { - this.settingsImport(e)}/> + SettingsFunctions.importSettings(e)}/>

{advanced.customisation}

diff --git a/src/components/modals/main/settings/sections/Changelog.jsx b/src/components/modals/main/settings/sections/Changelog.jsx index b63517fc..eea008fa 100644 --- a/src/components/modals/main/settings/sections/Changelog.jsx +++ b/src/components/modals/main/settings/sections/Changelog.jsx @@ -53,7 +53,7 @@ export default class Changelog extends React.PureComponent { lightboxImg: img.src }); }; - } + }; for (let link = 0; link < links.length; link++) { links[link].target = '_blank'; diff --git a/src/components/modals/main/settings/sections/Order.jsx b/src/components/modals/main/settings/sections/Order.jsx index 88b34321..b88ee997 100644 --- a/src/components/modals/main/settings/sections/Order.jsx +++ b/src/components/modals/main/settings/sections/Order.jsx @@ -52,7 +52,6 @@ export default class OrderSettings extends React.PureComponent { } const newArray = [...array]; - const target = newArray[oldIndex]; const inc = newIndex < oldIndex ? -1 : 1; @@ -61,7 +60,6 @@ export default class OrderSettings extends React.PureComponent { } newArray[newIndex] = target; - return newArray; } diff --git a/src/components/modals/main/settings/sections/QuickLinks.jsx b/src/components/modals/main/settings/sections/QuickLinks.jsx index d1c93233..095e252f 100644 --- a/src/components/modals/main/settings/sections/QuickLinks.jsx +++ b/src/components/modals/main/settings/sections/QuickLinks.jsx @@ -8,7 +8,7 @@ export default function QuickLinks() { <>

{language.title}

- + diff --git a/src/components/modals/main/settings/sections/Search.jsx b/src/components/modals/main/settings/sections/Search.jsx index 56e5e4bd..9ab1e62f 100644 --- a/src/components/modals/main/settings/sections/Search.jsx +++ b/src/components/modals/main/settings/sections/Search.jsx @@ -85,7 +85,6 @@ export default class SearchSettings extends React.PureComponent { ))} -

    {search.custom} this.resetSearch()}>{language.buttons.reset}

    diff --git a/src/components/modals/main/settings/sections/background/Background.jsx b/src/components/modals/main/settings/sections/background/Background.jsx index 23c2b1ef..ab7132f5 100644 --- a/src/components/modals/main/settings/sections/background/Background.jsx +++ b/src/components/modals/main/settings/sections/background/Background.jsx @@ -153,7 +153,7 @@ export default class BackgroundSettings extends React.PureComponent { <>

    {background.title}

    - + diff --git a/src/components/modals/main/settings/sections/background/Colour.jsx b/src/components/modals/main/settings/sections/background/Colour.jsx index f075738f..c892a1ef 100644 --- a/src/components/modals/main/settings/sections/background/Colour.jsx +++ b/src/components/modals/main/settings/sections/background/Colour.jsx @@ -55,7 +55,7 @@ export default class ColourSettings extends React.PureComponent { try { gradientSettings = JSON.parse(hex); } catch (e) { - // Disregard exception. + // Disregard exception } } diff --git a/src/components/modals/main/tabs/Addons.jsx b/src/components/modals/main/tabs/Addons.jsx index a36db66a..fa4dc36a 100644 --- a/src/components/modals/main/tabs/Addons.jsx +++ b/src/components/modals/main/tabs/Addons.jsx @@ -8,8 +8,8 @@ export default function Addons() { return ( -
    -
    +
    +
    ); } diff --git a/src/components/modals/main/tabs/Marketplace.jsx b/src/components/modals/main/tabs/Marketplace.jsx index 0f861382..d438ec03 100644 --- a/src/components/modals/main/tabs/Marketplace.jsx +++ b/src/components/modals/main/tabs/Marketplace.jsx @@ -7,9 +7,9 @@ export default function Marketplace() { return ( -
    -
    -
    +
    +
    +
    ); } diff --git a/src/components/modals/main/tabs/Settings.jsx b/src/components/modals/main/tabs/Settings.jsx index 85ab88ff..57bdb4da 100644 --- a/src/components/modals/main/tabs/Settings.jsx +++ b/src/components/modals/main/tabs/Settings.jsx @@ -26,20 +26,20 @@ export default function Settings() { return ( <> -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    {reminder.title}

    diff --git a/src/components/modals/main/tabs/backend/Tabs.jsx b/src/components/modals/main/tabs/backend/Tabs.jsx index 0103bc9e..433f36f0 100644 --- a/src/components/modals/main/tabs/backend/Tabs.jsx +++ b/src/components/modals/main/tabs/backend/Tabs.jsx @@ -8,17 +8,19 @@ export default class Tabs extends React.PureComponent { super(props); this.state = { - currentTab: this.props.children[0].props.label + currentTab: this.props.children[0].props.label, + currentName: this.props.children[0].props.name }; } - onClick = (tab) => { - if (tab !== this.state.currentTab) { - window.stats.postEvent('tab', `Changed ${this.state.currentTab} to ${tab}`); + onClick = (tab, name) => { + if (name !== this.state.currentName) { + window.stats.postEvent('tab', `Changed ${this.state.currentName} to ${name}`); } this.setState({ - currentTab: tab + currentTab: tab, + currentName: name }); }; @@ -42,7 +44,7 @@ export default class Tabs extends React.PureComponent { currentTab={this.state.currentTab} key={tab.props.label || index} label={tab.props.label} - onClick={this.onClick} + onClick={(nextTab) => this.onClick(nextTab, tab.props.name)} navbar={this.props.navbar || false} /> ))} diff --git a/src/components/modals/welcome/ProgressBar.jsx b/src/components/modals/welcome/ProgressBar.jsx new file mode 100644 index 00000000..eb221995 --- /dev/null +++ b/src/components/modals/welcome/ProgressBar.jsx @@ -0,0 +1,16 @@ +export default function ProgressBar(props) { + return ( +
    + {props.count.map((num) => { + let className = 'step'; + + const index = props.count.indexOf(num); + if (index === props.currentTab) { + className = 'step active'; + } + + return
    props.switchTab(index)}>
    + })} +
    + ); +} \ No newline at end of file diff --git a/src/components/modals/welcome/Welcome.jsx b/src/components/modals/welcome/Welcome.jsx index 4a9a266e..1a1e7b0f 100644 --- a/src/components/modals/welcome/Welcome.jsx +++ b/src/components/modals/welcome/Welcome.jsx @@ -1,28 +1,69 @@ -import EmailIcon from '@material-ui/icons/Email'; -import TwitterIcon from '@material-ui/icons/Twitter'; -import ForumIcon from '@material-ui/icons/Forum'; +import React from 'react'; + +import WelcomeSections from './WelcomeSections'; +import ProgressBar from './ProgressBar'; import './welcome.scss'; -export default function WelcomeModal(props) { - const language = window.language.modals.welcome; +export default class WelcomeModal extends React.PureComponent { + constructor() { + super(); + this.state = { + image: './././icons/undraw_celebration.svg', + currentTab: 0, + finalTab: 4, + buttonText: 'Next' + }; + this.language = window.language.modals.welcome; + this.images = ['./././icons/undraw_celebration.svg', './././icons/undraw_around_the_world_modified.svg', './././icons/undraw_add_files_modified.svg', './././icons/undraw_dark_mode.svg', './././icons/undraw_private_data_modified.svg', './././icons/undraw_upgrade_modified.svg'] + } - return ( -
    - × -
    -

    {language.title}

    -

    Mue Tab

    - celebration -

    {language.information}

    -

    {language.thankyoumessage1}
    {language.thankyoumessage2}

    -

    {language.support}

    - - - -
    - + changeTab(minus) { + if (minus) { + return this.setState({ + currentTab: this.state.currentTab - 1, + image: this.images[this.state.currentTab - 1], + buttonText: 'Next' + }); + } + + if (this.state.buttonText === 'Close') { + return this.props.modalClose(); + } + + this.setState({ + currentTab: this.state.currentTab + 1, + image: this.images[this.state.currentTab + 1], + buttonText: (this.state.currentTab !== this.state.finalTab) ? 'Next' : 'Close' + }); + } + + // specific + switchTab(tab) { + this.setState({ + currentTab: tab, + image: this.images[tab], + buttonText: 'Next' + }); + } + + render() { + return ( +
    +
    + celebration + this.switchTab(tab)}/> +
    +
    +
    + this.switchTab(tab)}/> +
    +
    + {(this.state.currentTab !== 0) ? : null} + +
    +
    -
    - ); + ); + } } diff --git a/src/components/modals/welcome/WelcomeSections.jsx b/src/components/modals/welcome/WelcomeSections.jsx new file mode 100644 index 00000000..2d19349e --- /dev/null +++ b/src/components/modals/welcome/WelcomeSections.jsx @@ -0,0 +1,156 @@ +import React from 'react'; + +import Radio from '../main/settings/Radio'; +//import Checkbox from '../main/settings/Checkbox'; +import FileUpload from '../main/settings/FileUpload'; +import UploadIcon from '@material-ui/icons/CloudUpload'; +import AutoIcon from '@material-ui/icons/AutoAwesome'; +import LightModeIcon from '@material-ui/icons/LightMode'; +import DarkModeIcon from '@material-ui/icons/DarkMode'; + +import SettingsFunctions from '../../../modules/helpers/settings'; + +const languages = require('../../../modules/languages.json'); + +export default class WelcomeSections extends React.Component { + constructor() { + super(); + this.state = { + autoClass: 'toggle auto active', + lightClass: 'toggle lightTheme', + darkClass: 'toggle darkTheme', + welcomeImage: 0 + }; + this.changeWelcomeImg = this.changeWelcomeImg.bind(this); + this.welcomeImages = ['https://external-content.duckduckgo.com/iu/?u=example.com/example.png']; + } + + changeTheme(type) { + this.setState({ + autoClass: (type === 'auto') ? 'toggle auto active' : 'toggle auto', + lightClass: (type === 'light') ? 'toggle lightTheme active' : 'toggle lightTheme', + darkClass: (type === 'dark') ? 'toggle darkTheme active': 'toggle darkTheme' + }); + + localStorage.setItem('theme', type); + SettingsFunctions.loadSettings(true); + } + + getSetting(name) { + const value = localStorage.getItem(name).replace('false', 'Off').replace('true', 'On'); + return value.charAt(0).toUpperCase() + value.slice(1); + } + + importSettings(e) { + SettingsFunctions.importSettings(e); + this.props.switchTab(4); + } + + changeWelcomeImg() { + let welcomeImage = this.state.welcomeImage; + this.setState({ + welcomeImage: ++welcomeImage % this.welcomeImages.length + }); + this.timeout = setTimeout(this.changeWelcomeImg, 3 * 1000); + } + + componentDidMount() { + this.timeout = setTimeout(this.changeWelcomeImg, 3 * 1000); + } + + render() { + const language = window.language.modals.welcome; + let tabContent; + + const intro = ( + <> +

    {language.title} Mue Tab

    +

    {language.thankyoumessage1} {language.thankyoumessage2}

    +

    to be added

    +
    + example mue setup +
    + + ); + + const chooseLanguage = ( + <> +

    Choose your language

    +

    to be added

    + + + ); + + const theme = ( + <> +

    Select a theme

    +

    Mue is available in both light and dark theme, or this can be automatically set depending on your system theme.

    +
    +
    this.changeTheme('auto')}> + + Auto +
    +
    +
    this.changeTheme('light')}> + + Light +
    +
    this.changeTheme('dark')}> + + Dark +
    +
    +

    Quick Tip

    +

    Using the Auto settings will use the theme on your computer. This setting will impact the modals and some of the widgets displayed on the screen, such as weather and notes.

    +
    + + ); + + const settings = ( + <> +

    Import Settings

    +

    Installing Mue on a new device? Feel free to import your old settings!

    + + this.importSettings(e)}/> +

    Quick Tip

    +

    You can export your old settings by navigating to the Advanced tab in your old Mue setup. Then you need to click the export button which will download the JSON file. You can upload this file here to carry across your settings and preferences from your previous Mue installation.

    + + ); + + const privacy = ( + <> +

    Privacy Options

    +

    to be added

    + + ); + + const final = ( + <> +

    Final step

    +

    Your Mue Tab experience is finally about to begin.

    +

    Changes

    +

    To change settings later click on the settings icon in the top right corner of your tab.

    +
    +
    this.props.switchTab(1)}>Language: {languages.find((i) => i.value === localStorage.getItem('language')).name}
    +
    this.props.switchTab(3)}>Theme: {this.getSetting('theme')}
    +
    + + ) + + switch (this.props.currentTab) { + case 1: tabContent = chooseLanguage; break; + case 2: tabContent = settings; break; + case 3: tabContent = theme; break; + case 4: tabContent = privacy; break; + case 5: tabContent = final; break; + // 0 + default: tabContent = intro; + } + + return tabContent; + } +} \ No newline at end of file diff --git a/src/components/modals/welcome/welcome.scss b/src/components/modals/welcome/welcome.scss index 5cbe715a..368bfb26 100644 --- a/src/components/modals/welcome/welcome.scss +++ b/src/components/modals/welcome/welcome.scss @@ -1,59 +1,148 @@ @import '../main/scss/index.scss'; .welcomemodal { - margin-top: 40px; -} + position: absolute; + margin: auto; + top: 0; + right: 0; + bottom: 0; + left: 0; + height: 80%; + width: 60%; + padding: 0; -.welcomeModalText { - line-height: 2px; - - h2.subtitle { - font-size: 24px; - color: var(--modal-text); - text-transform: uppercase; + section { + width: 50%; + display: inline; + height: 80vh; } - h1.welcometitle { - font-size: 50px; - } -} + section:nth-child(1) { + float: left; + background: var(--sidebar); + display: flex; + justify-content: center; + align-items: center; -.welcomeContent { - margin-top: 2em; - text-align: center; - padding: 25px; - - a { - text-decoration: none; - line-height: 20px !important; - color: var(--modal-link); - cursor: pointer; - } - - img.icon, - svg { - margin-top: -12px; - padding: 10px; - cursor: pointer; - transition: ease 0.2s; - - &:hover { - transform: scale(1.1); + img { + height: 300px; + width: 400px; } } - p { - margin-top: 0.7rem; - line-height: 1em; - } + section:nth-child(2) { + float: right; - img, - svg { - height: 24px; - width: auto; + .content { + padding: 20px; + } + + .buttons { + position: absolute; + bottom: 2rem; + right: 2rem; + } + + h1 { + font-size: 2.5em; + } + + h3.quicktip { + text-transform: uppercase; + color: #5352ed; + } } } -.welcomeLink { - color: var(--modal-text) !important; +.welcomeoverlay { + background-color: rgba(0, 0, 0, 0.4); +} + +.progressbar { + position: fixed; + bottom: 50px; + text-align: center; + display: inline; + overflow: hidden; + white-space: nowrap; + + .step { + display: inline-block; + width: 50px; + background: #8395a7; + height: 4px; + margin: 10px; + transition: .2s ease; + cursor: pointer; + border-radius: 15px; + } + + .active { + background: #5352ed; + } +} + +.examples { + display: flex; + flex-wrap: wrap; + flex-direction: column; + align-items: center; + + img { + width: 30rem; + height: auto; + display: block; + margin: 30px; + border-radius: 12px; + } +} + +.themesToggleArea { + .active { + background: var(--tab-active) !important; + } + + .toggle { + background: var(--sidebar); + text-align: center; + border-radius: 40px; + padding: 20px; + margin: 10px; + + &:hover { + background: var(--tab-active); + cursor: pointer; + } + } + + .auto { + svg { + font-size: 12px; + padding-right: 5px; + } + } + + .options { + display: flex; + justify-content: space-between; + + .lightTheme, + .darkTheme { + width: 40%; + padding: 50px; + + span { + display: block; + } + } + } +} + +a.privacy { + text-decoration: none; + color: var(--modal-text); + + &:hover { + color: #5352ed; + } } diff --git a/src/components/widgets/Widgets.jsx b/src/components/widgets/Widgets.jsx index 19dd5500..29b7e4d1 100644 --- a/src/components/widgets/Widgets.jsx +++ b/src/components/widgets/Widgets.jsx @@ -43,6 +43,11 @@ export default class Widgets extends React.PureComponent { } render() { + // don't hide when welcome is there + if (localStorage.getItem('showWelcome') === 'true') { + return
    + } + // allow for re-ordering widgets let elements = []; diff --git a/src/components/widgets/background/Background.jsx b/src/components/widgets/background/Background.jsx index 36bb903e..9ff74050 100644 --- a/src/components/widgets/background/Background.jsx +++ b/src/components/widgets/background/Background.jsx @@ -68,7 +68,7 @@ export default class Background extends React.PureComponent { const backgroundImage = document.getElementById('backgroundImage'); if (this.state.url !== '') { - const url = (localStorage.getItem('ddgProxy') === 'true' && this.state.photoInfo.offline !== true) ? window.constants.DDG_PROXY + this.state.url : this.state.url; + const url = (localStorage.getItem('ddgProxy') === 'true' && this.state.photoInfo.offline !== true) ? window.constants.DDG_IMAGE_PROXY + this.state.url : this.state.url; const photoInformation = document.querySelector('.photoInformation'); // just set the background @@ -116,7 +116,10 @@ export default class Background extends React.PureComponent { // Main background getting function async getBackground() { - const offline = (localStorage.getItem('offlineMode') === 'true'); + let offline = (localStorage.getItem('offlineMode') === 'true'); + if (localStorage.getItem('showWelcome') === 'true') { + offline = true; + } switch (localStorage.getItem('backgroundType')) { case 'api': @@ -302,7 +305,9 @@ export default class Background extends React.PureComponent { // fix bug try { document.querySelector('.photoInformation').style.display = 'block'; - } catch (e) {} + } catch (e) { + // Disregard exception + } } element.style.display = 'block'; @@ -328,7 +333,7 @@ export default class Background extends React.PureComponent { } // uninstall photo pack reverts your background to what you had previously - if (data === 'marketplacebackgrounduninstall') { + if (data === 'marketplacebackgrounduninstall' || data === 'backgroundwelcome') { refresh(); } }); @@ -362,7 +367,7 @@ export default class Background extends React.PureComponent { return ( <> -
    +
    {(this.state.photoInfo.credit !== '') ? : null} diff --git a/src/components/widgets/background/Favourite.jsx b/src/components/widgets/background/Favourite.jsx index 8bb094a3..3b4a682d 100644 --- a/src/components/widgets/background/Favourite.jsx +++ b/src/components/widgets/background/Favourite.jsx @@ -9,7 +9,7 @@ export default class Favourite extends React.PureComponent { constructor() { super(); this.state = { - favourited: (localStorage.getItem('favourite')) ? : + favourited: (localStorage.getItem('favourite')) ? : }; } diff --git a/src/components/widgets/greeting/Greeting.jsx b/src/components/widgets/greeting/Greeting.jsx index 965a6290..8a8e9fae 100644 --- a/src/components/widgets/greeting/Greeting.jsx +++ b/src/components/widgets/greeting/Greeting.jsx @@ -114,7 +114,7 @@ export default class Greeting extends React.PureComponent { this.getGreeting(0); element.style.display = 'block'; - element.style.fontSize = `${1.6 * Number(localStorage.getItem('zoomGreeting') / 100)}em`; + element.style.fontSize = `${1.6 * Number((localStorage.getItem('zoomGreeting') || 100) / 100)}em`; } }); @@ -125,6 +125,10 @@ export default class Greeting extends React.PureComponent { this.getGreeting(0); } + componentWillUnmount() { + EventBus.remove('refresh'); + } + render() { return

    {this.state.greeting} diff --git a/src/components/widgets/navbar/Navbar.jsx b/src/components/widgets/navbar/Navbar.jsx index 522bc5ce..ef531c66 100644 --- a/src/components/widgets/navbar/Navbar.jsx +++ b/src/components/widgets/navbar/Navbar.jsx @@ -13,6 +13,10 @@ import Tooltip from '../../helpers/tooltip/Tooltip'; import './scss/index.scss'; export default function Navbar(props) { + if (localStorage.getItem('showWelcome') === 'true') { + return null; + } + const backgroundEnabled = (localStorage.getItem('background') === 'true'); return ( diff --git a/src/components/widgets/navbar/Notes.jsx b/src/components/widgets/navbar/Notes.jsx index f221138b..adc128e7 100644 --- a/src/components/widgets/navbar/Notes.jsx +++ b/src/components/widgets/navbar/Notes.jsx @@ -4,7 +4,7 @@ import TextareaAutosize from '@material-ui/core/TextareaAutosize'; import CopyIcon from '@material-ui/icons/FileCopyRounded'; import NotesIcon from '@material-ui/icons/AssignmentRounded'; -import Pin from './Pin'; +import Pin from '@material-ui/icons/PushPin'; import { toast } from 'react-toastify'; @@ -37,7 +37,7 @@ export default class Notes extends React.PureComponent { copy() { window.stats.postEvent('feature', 'Notes copied'); - // this.state.notes doesnt work for some reason + // this.state.notes doesn't work for some reason navigator.clipboard.writeText(localStorage.getItem('notes')); toast(window.language.toasts.notes); } @@ -61,7 +61,7 @@ export default class Notes extends React.PureComponent {

    {this.language.title}

    - + diff --git a/src/components/widgets/navbar/Pin.jsx b/src/components/widgets/navbar/Pin.jsx deleted file mode 100644 index f525e0a8..00000000 --- a/src/components/widgets/navbar/Pin.jsx +++ /dev/null @@ -1,24 +0,0 @@ -// License for original pin SVG below -/* - Copyright 2020 Google Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ -export default function Pin() { - return ( - - - - - ); -} diff --git a/src/components/widgets/quicklinks/QuickLinks.jsx b/src/components/widgets/quicklinks/QuickLinks.jsx index 4561e487..ff4a7dae 100644 --- a/src/components/widgets/quicklinks/QuickLinks.jsx +++ b/src/components/widgets/quicklinks/QuickLinks.jsx @@ -119,6 +119,10 @@ export default class QuickLinks extends React.PureComponent { }; } + componentWillUnmount() { + EventBus.remove('refresh'); + } + render() { let target, rel = null; if (localStorage.getItem('quicklinksnewtab') === 'true') { @@ -154,9 +158,9 @@ export default class QuickLinks extends React.PureComponent {

    {this.language.new}

    - this.setState({ name: e.target.value })} /> + this.setState({ name: e.target.value })} />

    {this.state.nameError}

    - this.setState({ url: e.target.value })} /> + this.setState({ url: e.target.value })} />

    {this.state.urlError}

    diff --git a/src/components/widgets/quote/Quote.jsx b/src/components/widgets/quote/Quote.jsx index 3c8024d8..7a4f9af9 100644 --- a/src/components/widgets/quote/Quote.jsx +++ b/src/components/widgets/quote/Quote.jsx @@ -223,6 +223,10 @@ export default class Quote extends React.PureComponent { this.init(); } + componentWillUnmount() { + EventBus.remove('refresh'); + } + render() { return (
    diff --git a/src/components/widgets/time/Clock.jsx b/src/components/widgets/time/Clock.jsx index 4920933b..f5cffa82 100644 --- a/src/components/widgets/time/Clock.jsx +++ b/src/components/widgets/time/Clock.jsx @@ -111,6 +111,10 @@ export default class Clock extends React.PureComponent { this.startTime(0); } + componentWillUnmount() { + EventBus.remove('refresh'); + } + render() { let clockHTML =

    {this.state.time}{this.state.ampm}

    ; diff --git a/src/components/widgets/time/Date.jsx b/src/components/widgets/time/Date.jsx index b69c572d..7f9fd0f4 100644 --- a/src/components/widgets/time/Date.jsx +++ b/src/components/widgets/time/Date.jsx @@ -118,6 +118,10 @@ export default class DateWidget extends React.PureComponent { this.getDate(); } + componentWillUnmount() { + EventBus.remove('refresh'); + } + render() { return {this.state.date}
    {this.state.weekNumber}
    ; } diff --git a/src/index.js b/src/index.js index 7e921a67..4b99b150 100644 --- a/src/index.js +++ b/src/index.js @@ -39,7 +39,8 @@ if (window.languagecode !== 'en_GB' || window.languagecode !== 'en_US') { } window.constants = Constants; -if (localStorage.getItem('stats') === 'true' && localStorage.getItem('offlineMode') !== 'true') { +// doesn't send to umami when offline mode is on +if (localStorage.getItem('stats') === 'true') { window.stats = new Stats(window.constants.UMAMI_ID); } else { window.stats = { diff --git a/src/modules/constants.js b/src/modules/constants.js index 9dfdfcd6..e9b1804d 100644 --- a/src/modules/constants.js +++ b/src/modules/constants.js @@ -6,7 +6,7 @@ export const MARKETPLACE_URL = 'https://marketplace.muetab.com'; export const WEATHER_URL = 'https://weather.muetab.com'; export const SPONSORS_URL = 'https://sponsors.muetab.com'; export const GITHUB_URL = 'https://api.github.com'; -export const DDG_PROXY = 'https://external-content.duckduckgo.com/iu/?u='; +export const DDG_IMAGE_PROXY = 'https://external-content.duckduckgo.com/iu/?u='; // Mue URLs export const WEBSITE_URL = 'https://muetab.com'; @@ -22,4 +22,4 @@ export const OFFLINE_IMAGES = 20; // Version export const BETA_VERSION = false; -export const VERSION = '5.1.0'; +export const VERSION = '5.1.1'; diff --git a/src/modules/helpers/settings.js b/src/modules/helpers/settings/index.js similarity index 71% rename from src/modules/helpers/settings.js rename to src/modules/helpers/settings/index.js index 441e09c3..feaf90f8 100644 --- a/src/modules/helpers/settings.js +++ b/src/modules/helpers/settings/index.js @@ -1,52 +1,9 @@ -import experimentalInit from './experimental'; +import experimentalInit from '../experimental'; -const defaultSettings = require('../default_settings.json'); -const languages = require('../languages.json'); - -const saveFile = (data, filename = 'file') => { - if (typeof data === 'object') { - data = JSON.stringify(data, undefined, 4); - } - - const blob = new Blob([data], { type: 'text/json' }); - let e = document.createEvent('MouseEvents'); - let a = document.createElement('a'); - - a.href = window.URL.createObjectURL(blob); - a.download = filename; - a.dataset.downloadurl = ['text/json', a.download, a.href].join(':'); - - e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); - a.dispatchEvent(e); -}; +const defaultSettings = require('../../default_settings.json'); +const languages = require('../../languages.json'); export default class SettingsFunctions { - static exportSettings() { - let settings = {}; - Object.keys(localStorage).forEach((key) => { - settings[key] = localStorage.getItem(key); - }); - saveFile(settings, 'mue-settings.json'); - window.stats.postEvent('tab', 'Settings exported'); - } - - static setItem(key, value) { - const old = localStorage.getItem(key); - let val = true; - - if (old !== null && !value) { - if (old === 'true') { - val = false; - } - - if (old === 'false') { - val = true; - } - } - - localStorage.setItem(key, val); - } - static setDefaultSettings(reset) { localStorage.clear(); defaultSettings.forEach((element) => localStorage.setItem(element.name, element.value)); @@ -82,6 +39,8 @@ export default class SettingsFunctions { case 'auto': if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { document.body.classList.add('dark'); + } else { + document.body.classList.remove('dark'); } break; default: @@ -96,7 +55,9 @@ export default class SettingsFunctions { custom.forEach((element) => { try { document.head.removeChild(document.getElementById(element)); - } catch (e) {} + } catch (e) { + // Disregard exception + } }); } @@ -107,38 +68,24 @@ export default class SettingsFunctions { const font = localStorage.getItem('font'); if (font) { - const google = localStorage.getItem('fontGoogle'); - let url = ''; - let fontweight = ''; - let fontstyle = ''; - - if (google === 'true') { + if (localStorage.getItem('fontGoogle') === 'true') { url = `@import url('https://fonts.googleapis.com/css2?family=${font}&display=swap');`; } - const fontWeight = localStorage.getItem('fontweight'); - if (fontWeight) { - fontweight = `font-weight: ${fontWeight};`; - } - - const fontStyle = localStorage.getItem('fontstyle'); - if (fontStyle) { - fontstyle = `font-style: ${fontStyle};`; - } - document.head.insertAdjacentHTML('beforeend', ` `); } + // everything below this either doesn't support hot reload (custom js) or shouldn't run on a hot reload event if (hotreload === true) { return; } @@ -164,7 +111,7 @@ export default class SettingsFunctions { ██ ██ ██ ██████ ███████ ██ ██ ██ ██ ██ - ██ Copyright 2018-2021 The Mue Authors ██ + ██ Copyright 2018-${new Date().getFullYear()} The Mue Authors ██ ██ GitHub: https://github.com/mue/mue ██ ██ ██ ██ Thank you for using Mue! ██ diff --git a/src/modules/helpers/settings/modals.js b/src/modules/helpers/settings/modals.js new file mode 100644 index 00000000..7b26a810 --- /dev/null +++ b/src/modules/helpers/settings/modals.js @@ -0,0 +1,40 @@ +import { toast } from 'react-toastify'; + +const saveFile = (data, filename = 'file') => { + if (typeof data === 'object') { + data = JSON.stringify(data, undefined, 4); + } + + const blob = new Blob([data], { type: 'text/json' }); + let e = document.createEvent('MouseEvents'); + let a = document.createElement('a'); + + a.href = window.URL.createObjectURL(blob); + a.download = filename; + a.dataset.downloadurl = ['text/json', a.download, a.href].join(':'); + + e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); + a.dispatchEvent(e); +}; + +export default class ModalSettingsFunctions { + static exportSettings() { + let settings = {}; + Object.keys(localStorage).forEach((key) => { + settings[key] = localStorage.getItem(key); + }); + saveFile(settings, 'mue-settings.json'); + window.stats.postEvent('tab', 'Settings exported'); + } + + static importSettings(e) { + const content = JSON.parse(e.target.result); + + Object.keys(content).forEach((key) => { + localStorage.setItem(key, content[key]); + }); + + toast(window.language.toasts.imported); + window.stats.postEvent('tab', 'Settings imported'); + } +} \ No newline at end of file diff --git a/src/modules/helpers/stats.js b/src/modules/helpers/stats.js index d5e182ad..4bcbf13b 100644 --- a/src/modules/helpers/stats.js +++ b/src/modules/helpers/stats.js @@ -1,71 +1,73 @@ export default class Stats { - constructor(id) { - this.id = id; - this.domain = window.constants.UMAMI_DOMAIN; + constructor(id) { + this.id = id; + this.url = window.constants.UMAMI_DOMAIN + '/api/collect'; + this.offline = (localStorage.getItem('offlineMode') !== 'true'); + } + + async postEvent(type, name) { + const value = name.toLowerCase().replaceAll(' ', '-'); + + if (!this.offline) { + // umami + await fetch(this.url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + type: 'event', + payload: { + website: this.id, + url: '/', + event_type: type, + event_value: value + } + }) + }); } - async postEvent(type, name) { - const value = name.toLowerCase().replaceAll(' ', '-'); + // local + let data = JSON.parse(localStorage.getItem('statsData')); + // tl;dr this creates the objects if they don't exist + // this really needs a cleanup at some point + if (!data[type] || !data[type][value]) { + if (!data[type]) { + data[type] = {}; + } - await fetch(this.domain + '/api/collect', { - method: 'POST', - headers: { - 'Accept': 'application/json', - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ - type: 'event', - payload: { - website: this.id, - url: '/', - event_type: type, - event_value: value, - hostname: 'localhost', - language: localStorage.getItem('language').replace('_', '-'), - screen: `${window.screen.width}x${window.screen.height}` - } - }) - }); + if (!data[type][value]) { + data[type][value] = 1; + } + } else { + data[type][value] = data[type][value] + 1; + } + localStorage.setItem('statsData', JSON.stringify(data)); + } - let data = JSON.parse(localStorage.getItem('statsData')); - // tl;dr this creates the objects if they don't exist - // this really needs a cleanup at some point - if (!data[type] || !data[type][value]) { - if (!data[type]) { - data[type] = {}; - } - - if (!data[type][value]) { - data[type][value] = 1; - } - } else { - data[type][value] = data[type][value] + 1; - } - localStorage.setItem('statsData', JSON.stringify(data)); + async tabLoad() { + if (!this.offline) { + // umami + await fetch(this.url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + type: 'pageview', + payload: { + website: this.id, + url: '/', + language: localStorage.getItem('language').replace('_', '-'), + screen: `${window.screen.width}x${window.screen.height}` + } + }) + }); } - async tabLoad() { - await fetch(this.domain + '/api/collect', { - method: 'POST', - headers: { - 'Accept': 'application/json', - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ - type: 'pageview', - payload: { - website: this.id, - url: '/', - referrer: '', - hostname: 'localhost', - language: localStorage.getItem('language').replace('_', '-'), - screen: `${window.screen.width}x${window.screen.height}` - } - }) - }); - - let data = JSON.parse(localStorage.getItem('statsData')); - data['tabs-opened'] = data['tabs-opened'] + 1 || 1; - localStorage.setItem('statsData', JSON.stringify(data)); - } + // local + let data = JSON.parse(localStorage.getItem('statsData')); + data['tabs-opened'] = data['tabs-opened'] + 1 || 1; + localStorage.setItem('statsData', JSON.stringify(data)); + } } \ No newline at end of file diff --git a/src/scss/_variables.scss b/src/scss/_variables.scss index a830a5d2..7c0877c8 100644 --- a/src/scss/_variables.scss +++ b/src/scss/_variables.scss @@ -16,9 +16,9 @@ $modal: ( 'tab-underline': rgba(204, 204, 204, 1), 'tab-underline-active': rgba(0, 0, 0, 1), 'border-radius': 12px, - 'sidebar': #f0f0f0, + 'sidebar': rgb(240, 240, 240), 'tab-active': rgba(219, 219, 219, 0.72), - 'sidebar-dark': #353b48, + 'sidebar-dark': rgb(53, 59, 72), 'tab-active-dark': rgba(65, 71, 84, 0.9), 'modal-link': #5352ed, 'modal-link-dark': #3498db diff --git a/src/scss/index.scss b/src/scss/index.scss index c17a4ddc..9ffc13ab 100644 --- a/src/scss/index.scss +++ b/src/scss/index.scss @@ -11,7 +11,7 @@ body { } * { - font-family: 'Lexend Deca', 'Montserrat' !important; + font-family: 'Lexend Deca', 'Montserrat', sans-serif !important; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; outline: none; diff --git a/src/scss/modules/_buttons.scss b/src/scss/modules/_buttons.scss index a3c75e09..fbebc862 100644 --- a/src/scss/modules/_buttons.scss +++ b/src/scss/modules/_buttons.scss @@ -56,3 +56,27 @@ color: map-get($button-colours, 'other'); } } + +.upload { + width: 100%; + height: 100%; + border-radius: 20px; + border: none; + outline: none; + padding: 50px; + background: var(--sidebar); + color: var(--modal-text); + cursor: pointer; + + &:hover { + background: var(--tab-active); + } + + svg { + font-size: 4em; + } + + span { + font-size: 2em; + } +} \ No newline at end of file diff --git a/src/translations/de_DE.json b/src/translations/de_DE.json index 36c3dfed..08864006 100644 --- a/src/translations/de_DE.json +++ b/src/translations/de_DE.json @@ -130,7 +130,7 @@ }, "background": { "title": "Hintergrund", - "ddg_proxy": "DuckDuckGo Bilder Proxy verwenden", + "ddg_image_proxy": "DuckDuckGo Bilder Proxy verwenden", "transition": "Weicher übergang", "photo_information": "Show photo information", "category": "Kategorie", diff --git a/src/translations/en_GB.json b/src/translations/en_GB.json index ad43cfb3..7aa2e517 100644 --- a/src/translations/en_GB.json +++ b/src/translations/en_GB.json @@ -130,7 +130,7 @@ }, "background": { "title": "Background", - "ddg_proxy": "Use DuckDuckGo image proxy", + "ddg_image_proxy": "Use DuckDuckGo image proxy", "transition": "Fade-in transition", "photo_information": "Show photo information", "category": "Category", diff --git a/src/translations/en_US.json b/src/translations/en_US.json index 3ef42bd8..2e62f899 100644 --- a/src/translations/en_US.json +++ b/src/translations/en_US.json @@ -130,7 +130,7 @@ }, "background": { "title": "Background", - "ddg_proxy": "Use DuckDuckGo image proxy", + "ddg_image_proxy": "Use DuckDuckGo image proxy", "transition": "Fade-in transition", "photo_information": "Show photo information", "category": "Category", diff --git a/src/translations/es.json b/src/translations/es.json index 010745d7..eadfbe16 100644 --- a/src/translations/es.json +++ b/src/translations/es.json @@ -130,7 +130,7 @@ }, "background": { "title": "Fondo", - "ddg_proxy": "Utilizar el proxy de imágenes de DuckDuckGo", + "ddg_image_proxy": "Utilizar el proxy de imágenes de DuckDuckGo", "transition": "Transición fade-in", "photo_information": "Ver información de la foto", "category": "Categoría", diff --git a/src/translations/fr.json b/src/translations/fr.json index a80376e8..ea13d625 100644 --- a/src/translations/fr.json +++ b/src/translations/fr.json @@ -130,7 +130,7 @@ }, "background": { "title": "Fond", - "ddg_proxy": "Utiliser le proxy d'image DuckDuckGo", + "ddg_image_proxy": "Utiliser le proxy d'image DuckDuckGo", "transition": "Transition en fondu", "photo_information": "Show photo information", "category": "Catégorie", diff --git a/src/translations/nl.json b/src/translations/nl.json index eb15853a..062ba051 100644 --- a/src/translations/nl.json +++ b/src/translations/nl.json @@ -130,7 +130,7 @@ }, "background": { "title": "Achtergrond", - "ddg_proxy": "Use DuckDuckGo image proxy", + "ddg_image_proxy": "Use DuckDuckGo image proxy", "transition": "Fade-in transition", "photo_information": "Show photo information", "category": "Category", diff --git a/src/translations/no.json b/src/translations/no.json index 9abad357..10f0e46e 100644 --- a/src/translations/no.json +++ b/src/translations/no.json @@ -130,7 +130,7 @@ }, "background": { "title": "Bakgrunn", - "ddg_proxy": "Use DuckDuckGo image proxy", + "ddg_image_proxy": "Use DuckDuckGo image proxy", "transition": "Fade-in transition", "photo_information": "Show photo information", "category": "Category", diff --git a/src/translations/ru.json b/src/translations/ru.json index f8ad9a69..a21a4310 100644 --- a/src/translations/ru.json +++ b/src/translations/ru.json @@ -130,7 +130,7 @@ }, "background": { "title": "Фон", - "ddg_proxy": "Use DuckDuckGo image proxy", + "ddg_image_proxy": "Use DuckDuckGo image proxy", "transition": "Fade-in transition", "photo_information": "Show photo information", "category": "Category", diff --git a/src/translations/zh_CN.json b/src/translations/zh_CN.json index 6f56d984..8e073d19 100644 --- a/src/translations/zh_CN.json +++ b/src/translations/zh_CN.json @@ -130,7 +130,7 @@ }, "background": { "title": "背景", - "ddg_proxy": "使用 DuckDuckGo 图像代理", + "ddg_image_proxy": "使用 DuckDuckGo 图像代理", "transition": "渐变", "photo_information": "Show photo information", "category": "分类", diff --git a/webpack.config.js b/webpack.config.js index 74cf9ea9..f728eebb 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -48,7 +48,7 @@ module.exports = { clean: true }, devServer: { - contentBase: path.resolve(__dirname, './build'), + static: path.resolve(__dirname, './build'), open: true, port: 3000 },