Skip to content

Commit

Permalink
initial localization code / english translations
Browse files Browse the repository at this point in the history
  • Loading branch information
vgmoose committed Mar 23, 2024
1 parent 8c60ce1 commit 9f7c81b
Show file tree
Hide file tree
Showing 12 changed files with 258 additions and 97 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"@fortawesome/free-solid-svg-icons": "^5.9.0",
"@fortawesome/react-fontawesome": "^0.1.4",
"filesaver.js": "^1.3.4",
"i18next": "^23.10.1",
"jszip": "^3.7.1",
"jszip-utils": "^0.1.0",
"moment": "^2.27.0",
Expand All @@ -18,6 +19,7 @@
"react-day-picker": "^7.4.8",
"react-dom": "^16.8.3",
"react-fontawesome": "^1.6.1",
"react-i18next": "^14.1.0",
"react-portal-tooltip": "^2.4.7",
"react-responsive-modal": "^4.0.1",
"react-router-dom": "^5.0.1",
Expand Down
4 changes: 2 additions & 2 deletions src/AppDetails.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { Fragment, Component } from 'react';
import loading from './img/loader.gif';
import AppList from './AppList';
import {fetchPackages} from './AppList';
import noscreen from './img/noscreen.png';
import './MainDisplay.css';
import { getParams, Spacer, Mobile, getFirstPixelFromImage, platformIcons } from './Utils';
Expand All @@ -25,7 +25,7 @@ class AppDetails extends Component {

async componentDidMount() {

const packages = await AppList.fetchPackages(this.state.platform);
const packages = await fetchPackages(this.state.platform);
this.pkg = packages.find(pkg => pkg.name.toLowerCase() === this.curPkg && pkg.platform === this.state.platform);

if (!this.pkg) return this.setState({ loading: false });
Expand Down
114 changes: 66 additions & 48 deletions src/AppList.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,57 @@
import React, { Component, Fragment } from 'react';
import { Trans } from 'react-i18next';
import AppCard from './AppCard';
import LibGet from './LibGet';
import loader from './img/loader.gif';
import Sidebar from './Sidebar';
import { getCurrentCategory, getAllCategories } from './Sidebar';
import { getParams, Spacer, Mobile, stringDateToTimestamp } from './Utils';
import PlatformPicker from './PlatformPicker';
import icon from './img/icon.png';

import { withTranslation } from 'react-i18next';

export async function fetchPackages(platform) {
const repos = LibGet.getRepos(platform);

const repoPackages = await Promise.all(
(await LibGet.getApps(repos)).map(
async (response) => await response.json()
));

return repoPackages.reduce(
(acc, cur, idx) => acc.concat(
cur["packages"].map(pkg => ({
...pkg,
repo: repos[idx].url,
platform: repos[idx].platform
}))
), []);
}

export async function fetchCredits() {
const creditsResp = await fetch(`https://fortheusers.github.io/meta-repo/credits.json`);
const { credits } = await creditsResp.json();
return credits;
}

let sorts = [{
flavor: "by most recent",
flavor: "listing.sort.recent",
order: (b, a) => stringDateToTimestamp(a.updated) - stringDateToTimestamp(b.updated)
},
{
flavor: "by download count",
flavor: "listing.sort.download",
order: (b, a) => a.app_dls - b.app_dls
},
{
flavor: "randomly",
flavor: "listing.sort.alpha",
order: (a, b) => a.title.localeCompare(b.title)
},
{
flavor: "listing.sort.random",
order: () => 0.5 - Math.random()
},
{
flavor: "by file size",
flavor: "listing.sort.size",
order: (b, a) => (a.filesize + a.filesize) - (b.filesize + b.filesize)
}];

Expand All @@ -32,7 +63,7 @@ class AppList extends Component {

constructor(props) {
super(props);
this.category = Sidebar.getCurrentCategory();
this.category = getCurrentCategory();
const { platform, query } = getParams(props);
this.platform = platform;
this.query = query;
Expand All @@ -50,42 +81,18 @@ class AppList extends Component {
await me.sortLogic(me);
}

static async fetchPackages(platform) {
const repos = LibGet.getRepos(platform);

const repoPackages = await Promise.all(
(await LibGet.getApps(repos)).map(
async (response) => await response.json()
));

return repoPackages.reduce(
(acc, cur, idx) => acc.concat(
cur["packages"].map(pkg => ({
...pkg,
repo: repos[idx].url,
platform: repos[idx].platform
}))
), []);
}

static async fetchCredits() {
const creditsResp = await fetch(`https://fortheusers.github.io/meta-repo/credits.json`);
const { credits } = await creditsResp.json();
return credits;
}

async componentDidMount() {
await this.sortLogic(this);
}

async sortLogic(me) {

let packages = await AppList.fetchPackages(this.platform);
let packages = await fetchPackages(this.platform);

// perform the actual sort of packages, based on current sort / category
packages = packages.sort(sorts[me.state.curSort].order);

const cats = new Set(Sidebar.getAllCategories().map(cat => cat.short));
const cats = new Set(getAllCategories().map(cat => cat.short));

const { short } = me.category;
// let through for all and search, and misc only if not in any others
Expand All @@ -103,6 +110,7 @@ class AppList extends Component {
render() {
const { packages, curSort } = this.state;
const { name } = this.category;
const { t } = this.props;

if (!packages) {
return (<div className="AppList">
Expand All @@ -120,27 +128,37 @@ class AppList extends Component {

const isOnHome = window.location.pathname === "" || window.location.pathname === "/";

const platformPicker = isOnHome ? <div id="homeBlurb" style={{
marginBottom: 10,
marginLeft: 50,
marginRight: 50,
marginTop: 10}}>
<div style={{padding: 10, textAlign: "center"}}>
<img src={icon} alt="AppStore Logo" />
<span style={{
padding: 10
}}>Homebrew App Store</span>
const platformPicker = isOnHome ? (
<div id="homeBlurb" style={{
marginBottom: 10,
marginLeft: 50,
marginRight: 50,
marginTop: 10
}}>
<div style={{padding: 10, textAlign: "center"}}>
<img src={icon} alt="AppStore Logo" />
<span style={{padding: 10}}>Homebrew App Store</span>
</div>
<p>
<Trans i18nKey="homebrewDescription">
<a href="https://en.wikipedia.org/wiki/Homebrew_(video_games)">homebrew apps</a>
</Trans>
</p>
<p>
<Trans i18nKey="submitRequest">
<a href="/submit-or-request">Submit</a>
<a href="/about">About</a>
</Trans>
</p>
<PlatformPicker />
</div>
<p>Homebrew App Store is a free and open-source repository of <a href="https://en.wikipedia.org/wiki/Homebrew_(video_games)">homebrew apps</a> for the Wii U and Switch consoles. The apps, tools, and games distributed here are all made by independent software developers within the community.</p>
<p>If you would like to list your own open-source app here, or request an existing one to add to this index, please see the <a href="/submit-or-request">Submit</a> page. For other info about the team and project, see our <a href="/about">About</a> page.</p>
<PlatformPicker />
</div> : null;
) : null;

let headerText = (<Fragment>
{platformPicker}
<div className="catTitle">
<div className="menuspan">
{name} <br className="mobilebr"></br><span className="sort">{sortFlavor}</span>
{name} <br className="mobilebr"></br><span className="sort">{t(sortFlavor)}</span>
</div>
<div className="menu">
<button onClick={() => this.adjustSort(this)}>Adjust Sort</button>
Expand Down Expand Up @@ -194,4 +212,4 @@ class AppList extends Component {
}
}

export default AppList;
export default withTranslation()(AppList);
4 changes: 2 additions & 2 deletions src/AppStatsChart.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import LibGet from './LibGet';
import loader from './img/loader.gif';
import moment from 'moment';
import Select from 'react-select';
import AppList from './AppList';
import {fetchPackages} from './AppList';
import { TinyColor } from '@ctrl/tinycolor';
import DayPickerInput from 'react-day-picker/DayPickerInput';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
Expand All @@ -33,7 +33,7 @@ export default class AppStatsChart extends PureComponent {
async componentDidMount() {
// fetch async and save to state
const statsProper = await LibGet.getStats().then(response => response.json());
const allPackages = await AppList.fetchPackages();
const allPackages = await fetchPackages();

const { start: ogStart, end: ogEnd } = this.state;

Expand Down
62 changes: 42 additions & 20 deletions src/InfoPage.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React, { Component, Fragment } from 'react';
import { Trans } from 'react-i18next';

import { Spacer, Mobile } from './Utils';
import AppList from './AppList';
import {fetchCredits, fetchPackages} from './AppList';
import twitterImg from './img/twitter.png';
import githubImg from './img/github.png';
import gitlabImg from './img/gitlab.png';
Expand Down Expand Up @@ -30,12 +32,12 @@ class InfoPage extends Component {
const location = window.location.pathname;

if (location === "/about") {
let credits = await AppList.fetchCredits();
let credits = await fetchCredits();
this.setState({ credits });
}

if (location !== "/submit-or-request") {
let allPackages = await AppList.fetchPackages();
let allPackages = await fetchPackages();
allPackages.sort((a, b) => a.title.localeCompare(b.title));
this.setState({ allPackages })

Expand Down Expand Up @@ -192,40 +194,55 @@ class InfoPage extends Component {
</table>;

pageText = <div>
<h1>About hb-appstore</h1>
<h1><Trans i18nKey="aboutTitle" /></h1>
<p className="pNormalWidth">
<Trans i18nKey="aboutDescription1">
<a href="https://en.wikipedia.org/wiki/Homebrew_(video_games)">Homebrew</a>
<a href="https://fortheusers.org">ForTheUsers</a>
</Trans>
</p>
<p className="pNormalWidth">
Homebrew App Store is a free and open-source repository of <a href="https://en.wikipedia.org/wiki/Homebrew_(video_games)">homebrew apps</a> for the Wii U and Switch consoles. This listing is maintained by the <a href="https://fortheusers.org">ForTheUsers team</a>, with the goal of making accessible and preserving the efforts of independent developers and hobbyists to end users.
</p><p className="pNormalWidth">
If you would like to list your own open-source app here, or request an existing one to add to this index, please see the <a href="/submit-or-request">Submit</a> page. For already listed apps, an <a href="/api-info">API</a> is available.
<Trans i18nKey="aboutDescription2">
<a href="/submit-or-request">Submit</a>
<a href="/api-info">API Info</a>
</Trans>
</p>
<p className="pNormalWidth">
If you are a copyright holder and are concerned some of your work is being infringed upon, please fill out this <a href="/dmca-request">DMCA Form</a> to submit a takedown request. This also applies if you are an open-source developer and don't want us to distribute your project here.
<Trans i18nKey="aboutDescription3">
<a href="/dmca-request">DMCA Page</a>
</Trans>
</p>
<h3>How It Works</h3>
<h3><Trans i18nKey="howItWorksTitle" /></h3>
<p className="pNormalWidth">
The content in our repositories is available both as a website and as a <a href="https://github.com/fortheusers/hb-appstore">native homebrew app</a> for the Wii U and Switch consoles. These console apps try to provide a similar experience to using a web browser, and can be downloaded <a href="https://github.com/fortheusers/hb-appstore/releases">here</a>.
<Trans i18nKey="howItWorksDescription1">
<a href="https://github.com/fortheusers/hb-appstore">Github</a>
<a href="https://github.com/fortheusers/hb-appstore/releases">Download</a>
</Trans>
</p>
<p className="pNormalWidth">
The individual hosted packages are updated regularly with new apps and updates. These are maintained by ForTheUsers staff and volunteers from the community. If you would like to help or report and outdated package, please contact us on <a href="https://discord.gg/F2PKpEj">Discord</a>.
<Trans i18nKey="howItWorksDescription2">
<a href="https://discord.gg/F2PKpEj">Discord</a>
</Trans>
</p>
<p className="pNormalWidth">
The Switch and Wii U platform icons were designed by <a href="https://dribbble.com/shots/10302424-Nintendo-Controllers">Fred Corbin</a>.
<Trans i18nKey="howItWorksDescription3">
<a href="https://dribbble.com/shots/10302424-Nintendo-Controllers">Art Credit</a>
</Trans>
</p>
<p style={{marginTop: -40}} className="pNormalWidth creditsContainer" dangerouslySetInnerHTML={{__html: hbasCreditsHTML}}>
</p>
<h3>App Authors</h3>
<p className="pNormalWidth">
Of course, this project wouldn't exist without the developers of the apps themselves. Thank you to all of the developers who have contributed to the homebrew community!
<br/><br/>
<Trans i18nKey="appAuthorsDescription" /><br/><br/>
{authorList}
</p>

<h3>Donations</h3>
<h3><Trans i18nKey="donationsTitle" /></h3>
<p className="pNormalWidth">
Thank you for your interest in supporting this project! We are not accepting donations, but if you would like to support the developers of the apps listed here, please visit their respective Github pages or websites as listed above.
<Trans i18nKey="donationsDescription1" />
</p>
<p className="pNormalWidth">
Otherwise, if you are still interested in supporting the project directly, we can recommend that you consider looking into and donating to one of the following causes instead:
<Trans i18nKey="donationsDescription2" />
<br/><br/>
<table className="donationList">
<tr>
Expand All @@ -241,12 +258,17 @@ class InfoPage extends Component {
</tr>
</table>
</p>
<h3>Licensing Info</h3>
<h3><Trans i18nKey="licensingTitle" /></h3>
<p className="pNormalWidth">
This website and the console clients are licensed under the <a href="https://www.gnu.org/licenses/gpl-3.0.en.html">GPLv3</a>. The content on the repositories we host is also available to use under a <a href="https://creativecommons.org/licenses/by-sa/4.0/deed.en">CC-BY-SA license</a>.
<Trans i18nKey="licensingDescription">
<a href="https://www.gnu.org/licenses/gpl-3.0.en.html">GPLv3 License</a>
<a href="https://creativecommons.org/licenses/by-sa/4.0/deed.en">CC License</a>
</Trans>
</p>
<p className="pNormalWidth">
That's pretty much everything! For other questions, reach out to one of the developers listed above, or join our <a href="https://discord.gg/F2PKpEj">Discord</a> server.
<Trans i18nKey="finalNote">
<a href="https://discord.gg/F2PKpEj">Discord Link</a>
</Trans>
</p>
<br/><br/><br/><br/><br/><br/><br/><br/><br/>
</div>;
Expand Down
4 changes: 2 additions & 2 deletions src/QuickStore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { faGithub } from '@fortawesome/free-brands-svg-icons';
import JSZip from 'jszip';
import { urlToPromise, saveAs } from './LibGet';
import PlatformPicker from './PlatformPicker';
import AppList from './AppList';
import {fetchPackages} from './AppList';
import loader from './img/loader.gif';
import noicon from './img/noicon.png';
import './Quickstore.css';
Expand Down Expand Up @@ -44,7 +44,7 @@ const QuickStore = (props: { platform: Platform }) => {

useEffect(() => {
const fetchData = async () => {
const allPackages = await AppList.fetchPackages();
const allPackages = await fetchPackages();
setAllApps(allPackages);
}
fetchData();
Expand Down
Loading

0 comments on commit 9f7c81b

Please sign in to comment.