mirror of
https://github.com/captbaritone/webamp.git
synced 2026-07-23 18:17:38 +00:00
Always get permalink from state
Also: Fetch skin data from Algolia as a stop gap
This commit is contained in:
parent
deb8d8c245
commit
79ede7e26c
7 changed files with 109 additions and 42 deletions
12
src/Cell.js
12
src/Cell.js
|
|
@ -14,7 +14,8 @@ const Cell = React.memo(props => {
|
|||
skin,
|
||||
requestToken,
|
||||
setSelectedSkin,
|
||||
requestUnloadedSkin
|
||||
requestUnloadedSkin,
|
||||
permalinkUrl
|
||||
} = props;
|
||||
const { width, height } = data;
|
||||
React.useEffect(() => {
|
||||
|
|
@ -51,7 +52,8 @@ const Cell = React.memo(props => {
|
|||
width={width}
|
||||
selectSkin={setSelectedSkin}
|
||||
color={color}
|
||||
permalink={Utils.getPermalinkUrlFromHashAndFilename(hash, skin.fileName)}
|
||||
// TODO: This is werid because there is an implicit assumption that this is always avaliable if we have the skin
|
||||
permalink={permalinkUrl}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
|
@ -65,9 +67,13 @@ const mapStateToProps = (state, ownProps) => {
|
|||
rowIndex,
|
||||
columnIndex
|
||||
});
|
||||
const getPermalinkUrlFromHash = Selectors.getPermalinkUrlFromHashGetter(
|
||||
state
|
||||
);
|
||||
return {
|
||||
requestToken,
|
||||
skin
|
||||
skin,
|
||||
permalinkUrl: skin == null ? null : getPermalinkUrlFromHash(skin.hash)
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -6,10 +6,11 @@ import DownloadLink from "./DownloadLink";
|
|||
import * as Utils from "./utils";
|
||||
import * as Selectors from "./redux/selectors";
|
||||
import * as Actions from "./redux/actionCreators";
|
||||
import { SCREENSHOT_HEIGHT, SCREENSHOT_WIDTH, SKIN_WIDTH } from "./constants";
|
||||
import { SCREENSHOT_HEIGHT, SCREENSHOT_WIDTH } from "./constants";
|
||||
import { delay } from "rxjs/operators";
|
||||
import { Subject, combineLatest, timer, fromEvent } from "rxjs";
|
||||
import { Subject, combineLatest, timer, fromEvent, from } from "rxjs";
|
||||
import Disposable from "./Disposable";
|
||||
import { search } from "./algolia";
|
||||
|
||||
class FocusedSkin extends React.Component {
|
||||
constructor(props) {
|
||||
|
|
@ -64,7 +65,40 @@ class FocusedSkin extends React.Component {
|
|||
);
|
||||
}
|
||||
|
||||
_fetchSkinData() {
|
||||
if (this.props.skinData != null) {
|
||||
return;
|
||||
}
|
||||
// OMG Giant hack. Kill this please. We should be able to get this data from our own server.
|
||||
from(
|
||||
search(this.props.hash, { hitsPerPage: 2, typoTolerance: 0 })
|
||||
).subscribe(results => {
|
||||
if (results.nbHits.length === 1) {
|
||||
console.error(
|
||||
"Failed to get skin data for hash",
|
||||
this.props.hash,
|
||||
results
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (results.nbHits.length > 1) {
|
||||
console.error(
|
||||
"Failed to uniquely get skin data for hash",
|
||||
this.props.hash
|
||||
);
|
||||
return;
|
||||
}
|
||||
const { fileName, color } = results.hits[0];
|
||||
this.props.gotSkinData(this.props.hash, {
|
||||
md5: this.props.hash,
|
||||
fileName,
|
||||
color
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this._fetchSkinData();
|
||||
this._disposable.add(
|
||||
fromEvent(window.document, "keydown").subscribe(e => {
|
||||
if (e.key === "ArrowRight") {
|
||||
|
|
@ -183,7 +217,7 @@ class FocusedSkin extends React.Component {
|
|||
}}
|
||||
onLoad={() => this.setState({ previewLoaded: true })}
|
||||
src={Utils.screenshotUrlFromHash(this.props.hash)}
|
||||
alt={this.props.fileName}
|
||||
alt={this.props.skinData && this.props.skinData.fileName}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
|
@ -204,7 +238,7 @@ class FocusedSkin extends React.Component {
|
|||
e.target.setSelectionRange(0, e.target.value.length)
|
||||
}
|
||||
className="permalink-input"
|
||||
value={Utils.getAbsolutePermalinkUrlFromHash(this.props.hash)}
|
||||
value={this.props.absolutePermalink}
|
||||
readOnly
|
||||
autoFocus
|
||||
/>
|
||||
|
|
@ -220,7 +254,9 @@ class FocusedSkin extends React.Component {
|
|||
</span>
|
||||
</div>
|
||||
)}
|
||||
{this.props.fileName}
|
||||
{this.props.skinData
|
||||
? this.props.skinData.fileName
|
||||
: "Filename loading..."}
|
||||
{" ["}
|
||||
<DownloadLink
|
||||
href={Utils.skinUrlFromHash(this.props.hash)}
|
||||
|
|
@ -240,7 +276,7 @@ class FocusedSkin extends React.Component {
|
|||
</a>
|
||||
{"] ["}
|
||||
<a
|
||||
href={Utils.getAbsolutePermalinkUrlFromHash(this.props.hash)}
|
||||
href={this.props.absolutePermalink}
|
||||
onClick={e => {
|
||||
this.setState({ showLink: !this.state.showLink });
|
||||
e.preventDefault();
|
||||
|
|
@ -264,14 +300,22 @@ class FocusedSkin extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state, ownProps) => ({
|
||||
hash: Selectors.getSelectedSkinHash(state),
|
||||
initialPosition: Selectors.getSelectedSkinPosition(state),
|
||||
fileExplorerOpen: Selectors.getFileExplorerOpen(state),
|
||||
fileName: state.skins[ownProps.hash].fileName
|
||||
});
|
||||
const mapStateToProps = (state, ownProps) => {
|
||||
return {
|
||||
hash: Selectors.getSelectedSkinHash(state),
|
||||
initialPosition: Selectors.getSelectedSkinPosition(state),
|
||||
fileExplorerOpen: Selectors.getFileExplorerOpen(state),
|
||||
skinData: state.skins[ownProps.hash] || null,
|
||||
absolutePermalink: Selectors.getAbsolutePermalinkUrlFromHashGetter(state)(
|
||||
ownProps.hash
|
||||
)
|
||||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
gotSkinData(hash, data) {
|
||||
dispatch({ type: "GOT_SKIN_DATA", hash, data });
|
||||
},
|
||||
selectRelativeSkin(offset) {
|
||||
dispatch(Actions.selectRelativeSkin(offset));
|
||||
},
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ var client = algoliasearch("HQ9I5Z6IM5", "6466695ec3f624a5fccf46ec49680e51");
|
|||
|
||||
var index = client.initIndex("Skins");
|
||||
|
||||
export function search(query) {
|
||||
export function search(query, options = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
index.search(
|
||||
{
|
||||
|
|
@ -13,7 +13,8 @@ export function search(query) {
|
|||
hitsPerPage: 1000,
|
||||
// https://www.algolia.com/doc/api-reference/api-parameters/typoTolerance/
|
||||
// min: Retrieve records with the smallest number of typos.
|
||||
typoTolerance: "min"
|
||||
typoTolerance: "min",
|
||||
...options
|
||||
},
|
||||
(err, content) => {
|
||||
if (err != null) {
|
||||
|
|
|
|||
|
|
@ -3,14 +3,7 @@ import { of, from, empty } from "rxjs";
|
|||
import * as Actions from "./actionCreators";
|
||||
import * as Selectors from "./selectors";
|
||||
import * as Utils from "../utils";
|
||||
import {
|
||||
filter,
|
||||
switchMap,
|
||||
map,
|
||||
ignoreElements,
|
||||
mergeMap,
|
||||
tap
|
||||
} from "rxjs/operators";
|
||||
import { filter, switchMap, map, mergeMap } from "rxjs/operators";
|
||||
import { search } from "../algolia";
|
||||
|
||||
const urlChangedEpic = actions =>
|
||||
|
|
|
|||
|
|
@ -25,6 +25,12 @@ const defaultState = {
|
|||
|
||||
export default function reducer(state = defaultState, action) {
|
||||
switch (action.type) {
|
||||
case "GOT_SKIN_DATA": {
|
||||
return {
|
||||
...state,
|
||||
skins: { ...state.skins, [action.hash]: action.data }
|
||||
};
|
||||
}
|
||||
case "GOT_SKIN_CHUNK": {
|
||||
const newSkins = { ...state.skins };
|
||||
const newDefaultSkins = [...state.defaultSkins];
|
||||
|
|
|
|||
|
|
@ -94,19 +94,50 @@ export function getRandomSkinHash(state) {
|
|||
return skinHashes[randomIndex];
|
||||
}
|
||||
|
||||
export const getPermalinkUrlFromHashGetter = createSelector(
|
||||
getSkins,
|
||||
skins => {
|
||||
return hash => {
|
||||
const skin = skins[hash];
|
||||
if (skin == null) {
|
||||
return `/skin/${hash}/`;
|
||||
}
|
||||
return `/skin/${hash}/${skin.fileName}/`;
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
export const getAbsolutePermalinkUrlFromHashGetter = createSelector(
|
||||
getPermalinkUrlFromHashGetter,
|
||||
getPermalinkUrlFromHash => {
|
||||
return hash => {
|
||||
return window.location.origin + getPermalinkUrlFromHash(hash);
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
export const getUrl = createSelector(
|
||||
getActiveContentPage,
|
||||
getSelectedSkinHash,
|
||||
getSearchQuery,
|
||||
getFileExplorerOpen,
|
||||
getFocusedSkinFile,
|
||||
(activeContentPage, hash, query, fileExplorerOpen, focusedSkinFile) => {
|
||||
getSkins,
|
||||
getPermalinkUrlFromHashGetter,
|
||||
(
|
||||
activeContentPage,
|
||||
hash,
|
||||
query,
|
||||
fileExplorerOpen,
|
||||
focusedSkinFile,
|
||||
skins,
|
||||
getPermalinkUrlFromHash
|
||||
) => {
|
||||
if (activeContentPage === ABOUT_PAGE) {
|
||||
return "/about/";
|
||||
}
|
||||
if (hash) {
|
||||
// TODO: Add a human readable version
|
||||
const skinUrl = Utils.getPermalinkUrlFromHash(hash);
|
||||
const skinUrl = getPermalinkUrlFromHash(hash);
|
||||
if (fileExplorerOpen && focusedSkinFile) {
|
||||
return `${skinUrl}files/${encodeURIComponent(
|
||||
focusedSkinFile.fileName
|
||||
|
|
|
|||
14
src/utils.js
14
src/utils.js
|
|
@ -6,20 +6,6 @@ export function skinUrlFromHash(hash) {
|
|||
return `https://s3.amazonaws.com/webamp-uploaded-skins/skins/${hash}.wsz`;
|
||||
}
|
||||
|
||||
export function getPermalinkUrlFromHash(hash) {
|
||||
// TODO: Make this a selector
|
||||
return `/skin/${hash}/${hash}/`;
|
||||
}
|
||||
|
||||
export function getPermalinkUrlFromHashAndFilename(hash, fileName) {
|
||||
// TODO: Make this a selector
|
||||
return `/skin/${hash}/${fileName}/`;
|
||||
}
|
||||
|
||||
export function getAbsolutePermalinkUrlFromHash(hash) {
|
||||
return window.location.origin + getPermalinkUrlFromHash(hash);
|
||||
}
|
||||
|
||||
export function getWindowSize() {
|
||||
var w = window,
|
||||
d = document,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue