diff --git a/README.md b/README.md index 5e2910a5..0b763db2 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Fast, open and free-to-use new tab page for most modern browsers. * Fast and free * Supports multiple browsers * Actively developed and opensource -* Automatically updating API (with no tracking!) with new photos and offline mode +* Automatically updating API (with no tracking!) with new photos, quotes and offline mode * ~~Multiple language support~~ * ~~Settings feature - enable/disable features!~~ * Search bar, ~~update modal, copy button and more!~~ diff --git a/manifest/chrome.json b/manifest/chrome.json new file mode 100644 index 00000000..39ca9174 --- /dev/null +++ b/manifest/chrome.json @@ -0,0 +1,12 @@ +{ + "manifest_version": 2, + "offline_enabled": true, + "name": "Mue", + "version": "0.5", + "browser_action": { + "default_icon": "./android-chrome-512x512.png" + }, + "chrome_url_overrides": { + "newtab": "index.html" + } +} \ No newline at end of file diff --git a/manifest/firefox.json b/manifest/firefox.json new file mode 100644 index 00000000..cdad06e4 --- /dev/null +++ b/manifest/firefox.json @@ -0,0 +1,14 @@ +{ + "manifest_version": 2, + "name": "Mue", + "version": "0.5", + "browser_action": { + "default_icon": "./android-chrome-512x512.png" + }, + "chrome_url_overrides": { + "newtab": "index.html" + }, + "chrome_settings_overrides": { + "homepage": "index.html" + } +} \ No newline at end of file diff --git a/package.json b/package.json index c5cecbdd..a7c51bfa 100644 --- a/package.json +++ b/package.json @@ -3,19 +3,19 @@ "author": "ohlookitsderpy", "description": "Fast, open and free-to-use new tab page for most modern browsers.", "license": "MIT", - "version": "2.0.0", + "version": "2.0.1", "dependencies": { - "@material-ui/core": "^4.4.3", - "@material-ui/icons": "^4.4.3", - "react": "^16.10.1", - "react-dom": "^16.10.1", - "react-scripts": "3.1.2", + "@material-ui/core": "^4.5.1", + "@material-ui/icons": "^4.5.1", + "react": "^16.10.2", + "react-dom": "^16.10.2", + "react-scripts": "3.2.0", "unfetch": "^4.1.0" }, "devDependencies": { "eslint": "^6.5.0", "npm-run-all": "^4.1.5", - "sass": "^1.22.12" + "sass": "^1.23.0" }, "scripts": { "start": "react-scripts start", diff --git a/public/index.html b/public/index.html index 9850c4c0..0bf4e0ae 100644 --- a/public/index.html +++ b/public/index.html @@ -1,15 +1,17 @@ - - - - - - - New Tab - - - -
- - + + + + + + + New Tab + + + + +
+ + + \ No newline at end of file diff --git a/src/App.jsx b/src/App.jsx index ef4c89d4..9b7abed2 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,27 +1,20 @@ //* Imports import React from 'react'; -import Fetch from 'unfetch'; -import Clock from './modules/Clock'; -import Greeting from './modules/Greeting'; -import Quote from './modules/Quote'; -import Search from './modules/Search'; -import Credit from './modules/Credit'; +import Background from './components/Background'; +import Clock from './components/Clock'; +import Greeting from './components/Greeting'; +import Quote from './components/Quote'; +import Search from './components/Search'; +import Credit from './components/Credit'; import './css/index.css'; -//* Functions -const getCookie = (cookiename) => { - const cookiestring = RegExp('' + cookiename + '[^;]+').exec(document.cookie); - return unescape(!!cookiestring ? cookiestring.toString().replace(/^[^=]+./,'') : ''); -}; - -const randomInt = (min, max) => { return Math.floor(Math.random() * (max - min + 1)) + min; }; - //* App export default class App extends React.Component { - // Render all the modules + // Render all the components render() { return ( +
@@ -32,35 +25,4 @@ export default class App extends React.Component { ); } - - // Set background: Attempt to get one from the API first, and if that fails then use the offline ones. - async getAndSetBackground() { - const root = document.getElementById('root'); - - try { - let data = await Fetch('https://api.muetab.xyz/getImage?category=Outdoors'); - data = await data.json(); - - const checkRepeat = getCookie('backgroundimageurl'); - document.getElementById('photographer').innerText = `Photo by ${data.photographer}`; - document.getElementById('location').innerText = `${data.location}`; - - if (checkRepeat !== root.style.backgroundImage) root.style.backgroundImage = `url(${data.file})`; - else { - /*let data = await Fetch('https://api.muetab.xyz/getImage?category=Outdoors'); - data = await data.json();*/ - document.cookie = 'backgroundimageurl; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;'; - root.style.backgroundImage = `url(${data.file})`; - document.cookie = `backgroundimageurl=${data.file}`; - } - } catch (e) { - document.getElementById('backgroundCredits').style.display = 'none'; - document.getElementById('photographer').innerText = 'Photo from Pexels'; - root.style.backgroundImage = `url(../offline-images/${randomInt(1, 25)}.jpeg)`; - } - } - - componentDidMount() { - this.getAndSetBackground(); - } } diff --git a/src/components/Background.jsx b/src/components/Background.jsx new file mode 100644 index 00000000..69425261 --- /dev/null +++ b/src/components/Background.jsx @@ -0,0 +1,46 @@ +import React from 'react'; +import Fetch from 'unfetch'; + +const getCookie = (cookiename) => { + const cookiestring = RegExp('' + cookiename + '[^;]+').exec(document.cookie); + return unescape(!!cookiestring ? cookiestring.toString().replace(/^[^=]+./,'') : ''); +}; + +const randomInt = (min, max) => { return Math.floor(Math.random() * (max - min + 1)) + min; }; + +export default class Background extends React.Component { + // Set background: Attempt to get one from the API first, and if that fails then use the offline ones. + async getAndSetBackground() { + const root = document.getElementById('root'); + + try { + let data = await Fetch('https://api.muetab.xyz/getImage?category=Outdoors'); + data = await data.json(); + + const checkRepeat = getCookie('backgroundimageurl'); + document.getElementById('photographer').innerText = `Photo by ${data.photographer}`; + document.getElementById('location').innerText = `${data.location}`; + + if (checkRepeat !== root.style.backgroundImage) root.style.backgroundImage = `url(${data.file})`; + else { + /*let data = await Fetch('https://api.muetab.xyz/getImage?category=Outdoors'); + data = await data.json();*/ + document.cookie = 'backgroundimageurl; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;'; + root.style.backgroundImage = `url(${data.file})`; + document.cookie = `backgroundimageurl=${data.file}`; + } + } catch (e) { + document.getElementById('backgroundCredits').style.display = 'none'; + document.getElementById('photographer').innerText = 'Photo from Pexels'; + root.style.backgroundImage = `url(../offline-images/${randomInt(1, 25)}.jpeg)`; + } + } + + componentDidMount() { + this.getAndSetBackground(); + } + + render() { + return null; + } +} \ No newline at end of file diff --git a/src/modules/Clock.jsx b/src/components/Clock.jsx similarity index 78% rename from src/modules/Clock.jsx rename to src/components/Clock.jsx index dfc2ecb4..91664b4c 100644 --- a/src/modules/Clock.jsx +++ b/src/components/Clock.jsx @@ -1,42 +1,42 @@ -import React from 'react'; - -export default class Clock extends React.Component { - constructor(...args) { - super(...args); - this.state = { - date: ``, - ampm: ``, - }; - } - - startTime() { - const today = new Date(); - let h = today.getHours(); - const ampm = h >= 12 ? 'PM' : 'AM'; - const m = today.getMinutes(); - // const s = today.getSeconds(); - - if (h > 12) h = h - 12; - - this.setState({ date: `${('0' + h).slice(-2)}:${('0' + m).slice(-2)}`, ampm: ampm }); - - this.timeout = setTimeout(() => this.startTime(), 500); - } - - componentDidMount() { - this.startTime(); - } - - componentWillUnmount() { - clearTimeout(this.timeout); - } - - render() { - return

- {this.state.date} - - {this.state.ampm} - -

; - } -} +import React from 'react'; + +export default class Clock extends React.Component { + constructor(...args) { + super(...args); + this.state = { + date: ``, + ampm: ``, + }; + } + + startTime() { + const today = new Date(); // Get the current date + let h = today.getHours(); // Get hours + const ampm = h >= 12 ? 'PM' : 'AM'; // Set AM/PM + const m = today.getMinutes(); // Get minutes + // const s = today.getSeconds(); + + if (h > 12) h = h - 12; + + this.setState({ date: `${('0' + h).slice(-2)}:${('0' + m).slice(-2)}`, ampm: ampm }); + + this.timeout = setTimeout(() => this.startTime(), 500); + } + + componentDidMount() { + this.startTime(); + } + + componentWillUnmount() { + clearTimeout(this.timeout); + } + + render() { + return

+ {this.state.date} + + {this.state.ampm} + +

; + } +} diff --git a/src/modules/Credit.jsx b/src/components/Credit.jsx similarity index 96% rename from src/modules/Credit.jsx rename to src/components/Credit.jsx index 89d7c6a4..369f2453 100644 --- a/src/modules/Credit.jsx +++ b/src/components/Credit.jsx @@ -1,17 +1,17 @@ -/* eslint-disable */ -import RoomIcon from '@material-ui/icons/Room'; -import React from 'react'; - -export default class Search extends React.Component { - render() { - return ( -
- {/*

*/} -

-
- -
-
- ); - } +/* eslint-disable */ +import RoomIcon from '@material-ui/icons/Room'; +import React from 'react'; + +export default class Search extends React.Component { + render() { + return ( +
+ {/*

*/} +

+
+ +
+
+ ); + } } \ No newline at end of file diff --git a/src/modules/Greeting.jsx b/src/components/Greeting.jsx similarity index 66% rename from src/modules/Greeting.jsx rename to src/components/Greeting.jsx index 185a500e..a695b2e4 100644 --- a/src/modules/Greeting.jsx +++ b/src/components/Greeting.jsx @@ -1,26 +1,26 @@ -import React from 'react'; - -export default class Greeting extends React.Component { - constructor(...args) { - super(...args); - this.state = { - greeting: `` - }; - } - - getGreeting() { - const h = new Date().getHours(); - let t = 'Good evening'; // Set the default time string to "Good evening" - if (h < 12) t = 'Good morning'; // If it's before 12am, set the time string to "Good morning" - else if (h < 18) t = 'Good afternoon'; // If it's before 6pm, set the time string to "Good afternoon" - this.setState({ greeting: t }); // Set the state to the time string - } - - componentDidMount() { - this.getGreeting(); - } - - render() { - return

{this.state.greeting}

; - } +import React from 'react'; + +export default class Greeting extends React.Component { + constructor(...args) { + super(...args); + this.state = { + greeting: `` + }; + } + + getGreeting() { + const h = new Date().getHours(); + let t = 'Good evening'; // Set the default time string to "Good evening" + if (h < 12) t = 'Good morning'; // If it's before 12am, set the time string to "Good morning" + else if (h < 18) t = 'Good afternoon'; // If it's before 6pm, set the time string to "Good afternoon" + this.setState({ greeting: t }); // Set the state to the time string + } + + componentDidMount() { + this.getGreeting(); + } + + render() { + return

{this.state.greeting}

; + } } \ No newline at end of file diff --git a/src/modules/Quote.jsx b/src/components/Quote.jsx similarity index 88% rename from src/modules/Quote.jsx rename to src/components/Quote.jsx index 17a58258..2a234618 100644 --- a/src/modules/Quote.jsx +++ b/src/components/Quote.jsx @@ -1,37 +1,37 @@ -import React from 'react'; -import Fetch from 'unfetch'; -import quotes from '../quotes.json'; - -export default class Quote extends React.Component { - constructor(...args) { - super(...args); - this.state = { - quote: ``, - author: `` - }; - } - - async getQuote() { - try { - let data = await Fetch('https://api.muetab.xyz/getQuote'); - data = await data.json(); - this.setState({ quote: data.quote, author: data.author }); - } catch (e) { - const randomInt = (min, max) => { return Math.floor(Math.random() * (max - min + 1)) + min; }; - const num = randomInt(1, 20); - this.setState({ quote: quotes[num].quote, author: quotes[num].author }); - } - } - - componentDidMount() { - this.getQuote(); - } - - render() { - return [ -

{`"${this.state.quote}"`}

, - // perm_identity, -

{`${this.state.author}`}

, - ]; - } -} +import React from 'react'; +import Fetch from 'unfetch'; +import quotes from '../quotes.json'; + +export default class Quote extends React.Component { + constructor(...args) { + super(...args); + this.state = { + quote: ``, + author: `` + }; + } + + async getQuote() { + try { + let data = await Fetch('https://api.muetab.xyz/getQuote'); + data = await data.json(); + this.setState({ quote: data.quote, author: data.author }); + } catch (e) { + const randomInt = (min, max) => { return Math.floor(Math.random() * (max - min + 1)) + min; }; + const num = randomInt(1, 20); + this.setState({ quote: quotes[num].quote, author: quotes[num].author }); + } + } + + componentDidMount() { + this.getQuote(); + } + + render() { + return [ +

{`"${this.state.quote}"`}

, + // perm_identity, +

{`${this.state.author}`}

, + ]; + } +} diff --git a/src/modules/Search.jsx b/src/components/Search.jsx similarity index 96% rename from src/modules/Search.jsx rename to src/components/Search.jsx index c951c534..32f778c6 100644 --- a/src/modules/Search.jsx +++ b/src/components/Search.jsx @@ -1,14 +1,14 @@ -import React from 'react'; - -export default class Search extends React.Component { - render() { - return ( -