mirror of
https://github.com/captbaritone/webamp.git
synced 2026-07-23 18:17:38 +00:00
Stub out about page
This commit is contained in:
parent
524e7451fd
commit
027bad8a5c
9 changed files with 106 additions and 9 deletions
38
src/About.js
Normal file
38
src/About.js
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
import React from "react";
|
||||
|
||||
function About() {
|
||||
return (
|
||||
<div className="static-content">
|
||||
<h1>About</h1>
|
||||
<p>
|
||||
The Winamp Skin Museum is an attempt to build a <i>fast</i>,{" "}
|
||||
<i>searchable</i>, and <i>shareable</i>, interface for the collection of
|
||||
Winamp Skins amassed by the{" "}
|
||||
<a href="https://archive.org/details/winampskins">Internet Archive</a>.
|
||||
</p>
|
||||
<h2>Features:</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Infinite scroll</strong> preview images.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Experience</strong> skins with integrated{" "}
|
||||
<a href="https://webamp.org">Webamp</a>.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Fast search</strong> of indexed readme.txt texts.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
Made by <a href="https://jordaneldredge.com">Jordan Eldredge</a> (
|
||||
<a href="https://twitter.com/captbaritone">@captbaritone</a>).
|
||||
</p>
|
||||
<p>
|
||||
Come hang out with us in our{" "}
|
||||
<a href="https://discord.gg/fBTDMqR">Discord server</a>.
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default About;
|
||||
16
src/App.css
16
src/App.css
|
|
@ -29,8 +29,12 @@ buton {
|
|||
h1 {
|
||||
font-size: 20px;
|
||||
}
|
||||
h2 {
|
||||
font-size: 17px;
|
||||
}
|
||||
h1 a {
|
||||
text-decoration: none;
|
||||
color: rgba(255, 2550, 2550, 0.9);
|
||||
}
|
||||
|
||||
#search h1 #logo {
|
||||
|
|
@ -39,7 +43,6 @@ h1 a {
|
|||
|
||||
#search h1 .name {
|
||||
margin: 0 30px 0 0px;
|
||||
color: rgba(255, 2550, 2550, 0.9);
|
||||
}
|
||||
|
||||
button {
|
||||
|
|
@ -98,6 +101,7 @@ button:active {
|
|||
flex-direction: row;
|
||||
align-items: center;
|
||||
border-bottom: 2px solid rgb(32, 31, 51);
|
||||
color: rgba(255, 2550, 2550, 0.9);
|
||||
}
|
||||
|
||||
#search input {
|
||||
|
|
@ -204,3 +208,13 @@ body.overlay-open .overlay {
|
|||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.static-content {
|
||||
position: fixed;
|
||||
background-color: white;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
padding: 30px;
|
||||
line-height: 1.4em;
|
||||
}
|
||||
|
|
|
|||
21
src/App.js
21
src/App.js
|
|
@ -1,11 +1,13 @@
|
|||
import React from "react";
|
||||
import { connect } from "react-redux";
|
||||
import Head from "./Head";
|
||||
import About from "./About";
|
||||
import Header from "./Header";
|
||||
import Overlay from "./Overlay";
|
||||
import SkinTable from "./SkinTable";
|
||||
import FocusedSkin from "./FocusedSkin";
|
||||
import * as Selectors from "./redux/selectors";
|
||||
import { ABOUT_PAGE } from "./constants";
|
||||
|
||||
// Render your table
|
||||
|
||||
|
|
@ -34,10 +36,20 @@ class App extends React.Component {
|
|||
this.setState({ rowHeight, columnWidth })
|
||||
}
|
||||
/>
|
||||
{!this._sizeIsSet() || this.props.selectedSkinHash == null || (
|
||||
<Overlay shouldAnimate={this.props.overlayShouldAnimate}>
|
||||
<FocusedSkin initialHeight={rowHeight} initialWidth={columnWidth} />
|
||||
{this.props.aboutPage ? (
|
||||
<Overlay>
|
||||
<About />
|
||||
</Overlay>
|
||||
) : (
|
||||
!this._sizeIsSet() ||
|
||||
this.props.selectedSkinHash == null || (
|
||||
<Overlay shouldAnimate={this.props.overlayShouldAnimate}>
|
||||
<FocusedSkin
|
||||
initialHeight={rowHeight}
|
||||
initialWidth={columnWidth}
|
||||
/>
|
||||
</Overlay>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
|
@ -46,7 +58,8 @@ class App extends React.Component {
|
|||
|
||||
const mapStateToProps = state => ({
|
||||
selectedSkinHash: Selectors.getSelectedSkinHash(state),
|
||||
overlayShouldAnimate: Selectors.overlayShouldAnimate(state)
|
||||
overlayShouldAnimate: Selectors.overlayShouldAnimate(state),
|
||||
aboutPage: Selectors.getActiveContentPage(state) === ABOUT_PAGE
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(App);
|
||||
|
|
|
|||
|
|
@ -54,7 +54,6 @@ class Header extends React.Component {
|
|||
<span style={{ flexGrow: 1 }} />
|
||||
<input
|
||||
type="text"
|
||||
className="zoom-on-hover"
|
||||
onChange={e => this.props.setSearchQuery(e.target.value)}
|
||||
value={this.props.searchQuery || ""}
|
||||
placeholder={"Search..."}
|
||||
|
|
@ -63,13 +62,19 @@ class Header extends React.Component {
|
|||
}}
|
||||
/>
|
||||
<button
|
||||
className="zoom-on-hover"
|
||||
onClick={() => {
|
||||
this.props.requestRandomSkin();
|
||||
}}
|
||||
>
|
||||
Random
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
this.props.requestedAboutPage();
|
||||
}}
|
||||
>
|
||||
?
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -85,6 +90,9 @@ const mapDispatchToProps = dispatch => ({
|
|||
},
|
||||
requestRandomSkin() {
|
||||
dispatch(Actions.requestedRandomSkin());
|
||||
},
|
||||
requestedAboutPage() {
|
||||
dispatch(Actions.requestedAboutPage());
|
||||
}
|
||||
});
|
||||
export default connect(
|
||||
|
|
|
|||
|
|
@ -4,3 +4,4 @@ export const SCALE = 1 / 2;
|
|||
export const SKIN_WIDTH = SCREENSHOT_WIDTH * SCALE;
|
||||
export const SKIN_HEIGHT = SCREENSHOT_HEIGHT * SCALE;
|
||||
export const SKIN_RATIO = SKIN_HEIGHT / SKIN_WIDTH;
|
||||
export const ABOUT_PAGE = "ABOUT_PAGE";
|
||||
|
|
|
|||
|
|
@ -34,3 +34,7 @@ export function selectSkinFile(fileName) {
|
|||
export function gotFocusedSkinFile(content) {
|
||||
return { type: "GOT_FOCUSED_SKIN_FILE", content };
|
||||
}
|
||||
|
||||
export function requestedAboutPage() {
|
||||
return { type: "REQUESTED_ABOUT_PAGE" };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@ const urlChangedEpic = actions =>
|
|||
actions.pipe(
|
||||
filter(action => action.type === "URL_CHANGED"),
|
||||
switchMap(action => {
|
||||
if (action.location.pathname == "/about/") {
|
||||
return of(Actions.requestedAboutPage());
|
||||
}
|
||||
const params = new URLSearchParams(action.location.search);
|
||||
const query = params != null && params.get("query");
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import * as Utils from "../utils";
|
||||
import skins from "../skins.json";
|
||||
import { ABOUT_PAGE } from "../constants";
|
||||
|
||||
export function getSelectedSkinHash(state) {
|
||||
return state.selectedSkinHash;
|
||||
|
|
@ -40,6 +41,9 @@ export function getRandomSkinHash() {
|
|||
}
|
||||
|
||||
export function getUrl(state) {
|
||||
if (state.activeContentPage === ABOUT_PAGE) {
|
||||
return "/about/";
|
||||
}
|
||||
const hash = getSelectedSkinHash(state);
|
||||
const query = getSearchQuery(state);
|
||||
if (hash) {
|
||||
|
|
@ -59,3 +63,7 @@ export function getPreviewImageUrl(state) {
|
|||
const hash = getSelectedSkinHash(state);
|
||||
return hash == null ? null : Utils.screenshotUrlFromHash(hash);
|
||||
}
|
||||
|
||||
export function getActiveContentPage(state) {
|
||||
return state.activeContentPage;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { createStore as createReduxStore, applyMiddleware } from "redux";
|
|||
import { createEpicMiddleware } from "redux-observable";
|
||||
import * as Selectors from "./selectors";
|
||||
import rootEpic from "./epics";
|
||||
import { ABOUT_PAGE } from "../constants";
|
||||
|
||||
const defaultState = {
|
||||
searchQuery: null,
|
||||
|
|
@ -9,7 +10,8 @@ const defaultState = {
|
|||
selectedSkinPosition: null,
|
||||
matchingHashes: null,
|
||||
skinZip: null,
|
||||
focusedSkinFile: null
|
||||
focusedSkinFile: null,
|
||||
activeContentPage: null
|
||||
};
|
||||
|
||||
function reducer(state = defaultState, action) {
|
||||
|
|
@ -26,7 +28,8 @@ function reducer(state = defaultState, action) {
|
|||
...state,
|
||||
selectedSkinHash: null,
|
||||
selectedSkinPosition: null,
|
||||
skinZip: null
|
||||
skinZip: null,
|
||||
activeContentPage: null
|
||||
};
|
||||
case "SEARCH_QUERY_CHANGED":
|
||||
return {
|
||||
|
|
@ -63,6 +66,11 @@ function reducer(state = defaultState, action) {
|
|||
content: action.content
|
||||
}
|
||||
};
|
||||
case "REQUESTED_ABOUT_PAGE":
|
||||
return {
|
||||
...state,
|
||||
activeContentPage: ABOUT_PAGE
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue