mirror of
https://github.com/mue/mue.git
synced 2026-06-08 14:10:42 +02:00
Improvements
This commit is contained in:
@@ -15,7 +15,7 @@ Fast, open and free-to-use new tab page for most modern browsers.
|
|||||||
* Fast and free
|
* Fast and free
|
||||||
* Supports multiple browsers
|
* Supports multiple browsers
|
||||||
* Actively developed and opensource
|
* 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~~
|
* ~~Multiple language support~~
|
||||||
* ~~Settings feature - enable/disable features!~~
|
* ~~Settings feature - enable/disable features!~~
|
||||||
* Search bar, ~~update modal, copy button and more!~~
|
* Search bar, ~~update modal, copy button and more!~~
|
||||||
|
|||||||
12
manifest/chrome.json
Normal file
12
manifest/chrome.json
Normal file
@@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
14
manifest/firefox.json
Normal file
14
manifest/firefox.json
Normal file
@@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
14
package.json
14
package.json
@@ -3,19 +3,19 @@
|
|||||||
"author": "ohlookitsderpy",
|
"author": "ohlookitsderpy",
|
||||||
"description": "Fast, open and free-to-use new tab page for most modern browsers.",
|
"description": "Fast, open and free-to-use new tab page for most modern browsers.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"version": "2.0.0",
|
"version": "2.0.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@material-ui/core": "^4.4.3",
|
"@material-ui/core": "^4.5.1",
|
||||||
"@material-ui/icons": "^4.4.3",
|
"@material-ui/icons": "^4.5.1",
|
||||||
"react": "^16.10.1",
|
"react": "^16.10.2",
|
||||||
"react-dom": "^16.10.1",
|
"react-dom": "^16.10.2",
|
||||||
"react-scripts": "3.1.2",
|
"react-scripts": "3.2.0",
|
||||||
"unfetch": "^4.1.0"
|
"unfetch": "^4.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint": "^6.5.0",
|
"eslint": "^6.5.0",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"sass": "^1.22.12"
|
"sass": "^1.23.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"start": "react-scripts start",
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset='utf-8' />
|
<meta charset='utf-8' />
|
||||||
<meta name='viewport' content='width=device-width, initial-scale=1' />
|
<meta name='viewport' content='width=device-width, initial-scale=1' />
|
||||||
<link rel='apple-touch-icon' sizes='180x180' href='apple-touch-icon.png'>
|
|
||||||
<link rel='icon' type='image/png' sizes='32x32' href='favicon-32x32.png'>
|
<link rel='icon' type='image/png' sizes='32x32' href='favicon-32x32.png'>
|
||||||
<link rel='icon' type='image/png' sizes='16x16' href='favicon-16x16.png'>
|
<link rel='icon' type='image/png' sizes='16x16' href='favicon-16x16.png'>
|
||||||
<title>New Tab</title>
|
<title>New Tab</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<noscript>You need to enable JavaScript to use Mue.</noscript>
|
<noscript>You need to enable JavaScript to use Mue.</noscript>
|
||||||
<div id='root'></div>
|
<div id='root'></div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
54
src/App.jsx
54
src/App.jsx
@@ -1,27 +1,20 @@
|
|||||||
//* Imports
|
//* Imports
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Fetch from 'unfetch';
|
import Background from './components/Background';
|
||||||
import Clock from './modules/Clock';
|
import Clock from './components/Clock';
|
||||||
import Greeting from './modules/Greeting';
|
import Greeting from './components/Greeting';
|
||||||
import Quote from './modules/Quote';
|
import Quote from './components/Quote';
|
||||||
import Search from './modules/Search';
|
import Search from './components/Search';
|
||||||
import Credit from './modules/Credit';
|
import Credit from './components/Credit';
|
||||||
import './css/index.css';
|
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
|
//* App
|
||||||
export default class App extends React.Component {
|
export default class App extends React.Component {
|
||||||
// Render all the modules
|
// Render all the components
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
|
<Background/>
|
||||||
<Search/>
|
<Search/>
|
||||||
<div id='center'>
|
<div id='center'>
|
||||||
<Greeting/>
|
<Greeting/>
|
||||||
@@ -32,35 +25,4 @@ export default class App extends React.Component {
|
|||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
46
src/components/Background.jsx
Normal file
46
src/components/Background.jsx
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,10 +10,10 @@ export default class Clock extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
startTime() {
|
startTime() {
|
||||||
const today = new Date();
|
const today = new Date(); // Get the current date
|
||||||
let h = today.getHours();
|
let h = today.getHours(); // Get hours
|
||||||
const ampm = h >= 12 ? 'PM' : 'AM';
|
const ampm = h >= 12 ? 'PM' : 'AM'; // Set AM/PM
|
||||||
const m = today.getMinutes();
|
const m = today.getMinutes(); // Get minutes
|
||||||
// const s = today.getSeconds();
|
// const s = today.getSeconds();
|
||||||
|
|
||||||
if (h > 12) h = h - 12;
|
if (h > 12) h = h - 12;
|
||||||
@@ -1 +1 @@
|
|||||||
.App-clock{font-size:4em;margin:0;text-shadow:0 0 25px rgba(0,0,0,.3)}.App-ampm-specifier{font-size:.5em}.App-greeting{margin:0;font-size:1.6em;text-shadow:0 0 25px rgba(0,0,0,.3)}.App-quote{font-size:.8em;text-shadow:0 0 25px rgba(0,0,0,.3)}@media screen and (min-width: 600px){.App-quote{margin-left:30%;margin-right:30%}}.App-quote-author{font-size:.9em;letter-spacing:.5px;margin:0;text-shadow:0 0 25px rgba(0,0,0,.3)}i.material-icons,h1.App-quote-author{display:inline}.search-bar{position:absolute;left:20px;top:20px;display:flex;flex-direction:row;display:block;color:#fff;font-family:"Lexend Deca"}.search-bar button{cursor:pointer;outline:none;display:inline}.search-bar button i.material-icons{text-shadow:0 0 25px rgba(0,0,0,.3)}.search-bar input[type=text]{font-size:calc(5px + 1.2vmin);background:none;border:2px solid #fff;padding:10px;color:#fff;position:absolute;box-shadow:0 0 25px rgba(0,0,0,.3);z-index:1}.input.searchText{border:none}.searchbarform{display:flex;flex-direction:row;box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}#location{margin-bottom:-10px}#location,#photographer{font-size:calc(10px + 1.2vmin);text-shadow:0 0 25px rgba(0,0,0,.3);text-overflow:ellipsis}#photographer{position:absolute;bottom:10px;left:50px;width:1000px}.tooltip{position:absolute;bottom:15px;left:10px}.personicon,.locationicon{font-size:calc(10px + 1.2vmin)}.MuiSvgIcon-root{position:absolute;bottom:2px;left:2px;width:100em;height:100em;font-size:2rem;text-shadow:0 2px 25px rgba(0,0,0,.3)}.credits{bottom:2px;left:0px;position:absolute;text-align:left;min-width:50px}.tooltip{position:relative;display:inline-block;border-bottom:1px dotted #000}.tooltip .tooltiptext{visibility:hidden;background-color:#000;color:#fff;text-align:center;border-radius:6px;padding:20px;position:absolute;z-index:1;position:absolute;bottom:40px;left:60px;margin-left:-60px;opacity:0;transition:opacity 1s}.tooltip:hover .tooltiptext{visibility:visible;opacity:1}#center{margin-left:2vw;margin-right:2vw;display:flex;flex-direction:column;justify-content:center;font-size:calc(10px + 2vmin);text-align:center}::placeholder{color:#fff;opacity:1}:-ms-input-placeholder{color:#fff}#root{background-size:cover;background-repeat:no-repeat;background-position:center center;background-attachment:fixed;min-height:100vh;display:grid;color:#fff}.App-link{color:#61dafb}body{background:#2f3640;margin:0;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:"Lexend Deca";overflow:hidden}@font-face{font-family:"Lexend Deca";src:url("/./fonts/LexendDeca-Regular.woff2") format("woff2"),url("/./fonts/LexendDeca-Regular.woff") format("woff"),url("/./fonts/LexendDeca.ttf") format("truetype")}/*# sourceMappingURL=index.css.map */
|
.App-clock{font-size:4em;margin:0;text-shadow:0 0 25px rgba(0,0,0,.3)}.App-ampm-specifier{font-size:.5em}.App-greeting{margin:0;font-size:1.6em;text-shadow:0 0 25px rgba(0,0,0,.3)}.App-quote{font-size:.8em;text-shadow:0 0 25px rgba(0,0,0,.3)}@media screen and (min-width: 600px){.App-quote{margin-left:30%;margin-right:30%}}.App-quote-author{font-size:.9em;letter-spacing:.5px;margin:0;text-shadow:0 0 25px rgba(0,0,0,.3)}i.material-icons,h1.App-quote-author{display:inline}.search-bar{position:absolute;left:20px;top:20px;display:flex;flex-direction:row;display:block;color:#fff;font-family:"Lexend Deca"}.search-bar button{cursor:pointer;outline:none;display:inline}.search-bar button i.material-icons{text-shadow:0 0 25px rgba(0,0,0,.3)}.search-bar input[type=text]{font-size:calc(5px + 1.2vmin);background:none;border:2px solid #fff;padding:10px;color:#fff;position:absolute;box-shadow:0 0 25px rgba(0,0,0,.3);z-index:1}.input.searchText{border:none}.searchbarform{display:flex;flex-direction:row;box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}#location{margin-bottom:-10px}#location,#photographer{font-size:calc(10px + 1.2vmin);text-shadow:0 0 25px rgba(0,0,0,.3);text-overflow:ellipsis}#photographer{position:absolute;bottom:10px;left:50px;width:1000px}.tooltip{position:absolute;bottom:15px;left:10px}.personicon,.locationicon{font-size:calc(10px + 1.2vmin)}.MuiSvgIcon-root{position:absolute;bottom:2px;left:2px;width:100em;height:100em;font-size:2rem;text-shadow:0 2px 25px rgba(0,0,0,.3)}.credits{bottom:2px;left:0px;position:absolute;text-align:left;min-width:50px}.tooltip{position:relative;display:inline-block;border-bottom:1px dotted #000}.tooltip .tooltiptext{visibility:hidden;background-color:#000;color:#fff;text-align:center;border-radius:6px;padding:20px;position:absolute;z-index:1;position:absolute;bottom:40px;left:60px;margin-left:-60px;opacity:0;transition:opacity 1s}.tooltip:hover .tooltiptext{visibility:visible;opacity:1}#center{margin-left:2vw;margin-right:2vw;display:flex;flex-direction:column;justify-content:center;font-size:calc(10px + 2vmin);text-align:center}::placeholder{color:#fff;opacity:1}:-ms-input-placeholder{color:#fff}#root{background-size:cover;background-repeat:no-repeat;background-position:center center;background-attachment:fixed;min-height:100vh;display:grid;color:#fff}.App-link{color:#61dafb}body{background:#2f3640;margin:0;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:"Lexend Deca";overflow:hidden}@font-face{font-family:"Lexend Deca";src:url("/./fonts/LexendDeca-Regular.woff2") format("woff2")}/*# sourceMappingURL=index.css.map */
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"sourceRoot":"","sources":["../scss/modules/_clock.scss","../scss/modules/_greeting.scss","../scss/modules/_quote.scss","../scss/modules/_search.scss","../scss/modules/_credit.scss","../scss/modules/_miscellaneous.scss","../scss/index.scss"],"names":[],"mappings":"AAAA,WACI,cACA,SACA,oCAGJ,oBACE,eCPF,cACI,SACA,gBACA,oCCHJ,WACE,eACA,oCAGF,qCACE,WACE,gBACA,kBAIJ,kBACE,eACA,oBACA,SACA,oCAGF,qCACE,eCpBF,YACI,kBACA,UACA,SACA,aACA,mBACA,cACA,WACA,0BACA,mBACI,eACA,aAIA,eAHA,oCACI,oCAIR,6BACI,8BACA,gBACA,sBACA,aACA,WACA,kBACA,mCACA,UAIR,kBACI,YAGJ,eACI,aACA,mBACA,6CCnCJ,UACI,oBAGJ,wBACI,+BACA,oCACA,uBAGJ,cACE,kBACA,YACA,UACA,aAGF,SACE,kBACA,YACA,UAGF,0BACE,+BAGF,iBACE,kBACA,WACA,SACA,YACA,aACA,eACA,sCAGF,SACI,WACA,SACA,kBACA,gBACA,eAGJ,SACI,kBACA,qBACA,8BAEA,sBACI,kBACA,sBACA,WACA,kBACA,kBACA,aACA,kBACA,UACA,kBACA,YACA,UACA,kBAEA,UACA,sBAIR,4BACE,mBACA,UCxEF,QACI,gBACA,iBACA,aACA,sBACA,uBACA,6BACA,kBAGJ,cACE,WACA,UAGF,uBACE,WCTF,MACI,sBACA,4BACA,kCACA,4BACA,iBACA,aACA,WAGJ,UACI,cAGJ,KACI,mBACA,SACA,mCACA,kCACA,0BACA,gBAGJ,WACI,0BACA","file":"index.css"}
|
{"version":3,"sourceRoot":"","sources":["../scss/modules/_clock.scss","../scss/modules/_greeting.scss","../scss/modules/_quote.scss","../scss/modules/_search.scss","../scss/modules/_credit.scss","../scss/modules/_miscellaneous.scss","../scss/index.scss"],"names":[],"mappings":"AAAA,WACE,cACA,SACA,oCAGF,oBACE,eCPF,cACI,SACA,gBACA,oCCHJ,WACE,eACA,oCAGF,qCACE,WACE,gBACA,kBAIJ,kBACE,eACA,oBACA,SACA,oCAGF,qCAEE,eCrBF,YACI,kBACA,UACA,SACA,aACA,mBACA,cACA,WACA,0BAEA,mBACI,eACA,aAMA,eAJA,oCACI,oCAMR,6BACI,8BACA,gBACA,sBACA,aACA,WACA,kBACA,mCACA,UAIR,kBACI,YAGJ,eACI,aACA,mBACA,6CCxCJ,UACE,oBAGF,wBAEE,+BACA,oCACA,uBAGF,cACE,kBACA,YACA,UACA,aAGF,SACE,kBACA,YACA,UAGF,0BAEE,+BAGF,iBACE,kBACA,WACA,SACA,YACA,aACA,eACA,sCAGF,SACE,WACA,SACA,kBACA,gBACA,eAGF,SACE,kBACA,qBACA,8BAEA,sBACE,kBACA,sBACA,WACA,kBACA,kBACA,aACA,kBACA,UACA,kBACA,YACA,UACA,kBAEA,UACA,sBAIJ,4BACE,mBACA,UCzEF,QACE,gBACA,iBACA,aACA,sBACA,uBACA,6BACA,kBAGF,cACE,WACA,UAIF,uBAEE,WCXF,MACI,sBACA,4BACA,kCACA,4BACA,iBACA,aACA,WAGJ,UACI,cAGJ,KACI,mBACA,SACA,mCACA,kCACA,0BACA,gBAGJ,WACI,0BACA","file":"index.css"}
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
font-family: 'Lexend Deca';
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Lexend Deca'; /* IE9 Compat Modes */
|
|
||||||
src: url('/src/fonts/LexendDeca-Regular.woff2') format('woff2'), /* Super Modern Browsers */
|
|
||||||
url('/src/fonts/LexendDeca-Regular.woff') format('woff'), /* Pretty Modern Browsers */
|
|
||||||
url('/src/fonts/LexendDeca.ttf') format('truetype'); /* Safari, Android, iOS */
|
|
||||||
}
|
|
||||||
code {
|
|
||||||
font-family: 'Lexend Deca';
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
export default class UpdateModal extends React.Component {
|
|
||||||
|
|
||||||
openModal() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
if (!this.timeout) return;
|
|
||||||
clearTimeout(this.timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user