mirror of
https://github.com/captbaritone/webamp.git
synced 2026-07-23 10:07:35 +00:00
commit
3f9aa0c2cd
6 changed files with 159 additions and 20 deletions
19
src/App.css
19
src/App.css
|
|
@ -197,4 +197,21 @@ body.webamp-loaded #webamp {
|
|||
.tinder-card {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
#zoom button {
|
||||
color: rgba(255, 2550, 2550, 0.9);
|
||||
}
|
||||
#zoom button:active, #zoom button:disabled {
|
||||
color: grey;
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
#zoom {
|
||||
opacity: 0.7;
|
||||
transition: opacity 200ms ease-in-out;
|
||||
}
|
||||
#zoom:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import { useDropzone } from "react-dropzone";
|
|||
import ReviewPage from "./ReviewPage";
|
||||
|
||||
const getTableDimensions = (windowWidth, scale) => {
|
||||
const columnCount = Math.floor(windowWidth / (SCREENSHOT_WIDTH * scale));
|
||||
const columnCount = Math.round(windowWidth / (SCREENSHOT_WIDTH * scale));
|
||||
const columnWidth = windowWidth / columnCount; // TODO: Consider flooring this to get things aligned to the pixel
|
||||
const rowHeight = columnWidth * SKIN_RATIO;
|
||||
return { columnWidth, rowHeight, columnCount };
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@ function Header() {
|
|||
const showFeedbackForm = useActionCreator(Actions.showFeedbackForm);
|
||||
const requestRandomSkin = useActionCreator(Actions.requestedRandomSkin);
|
||||
const requestedAboutPage = useActionCreator(Actions.requestedAboutPage);
|
||||
// const setScale = useActionCreator((scale) => ({ type: "SET_SCALE", scale }));
|
||||
const setInput = useFocusOnSlash();
|
||||
|
||||
return (
|
||||
|
|
@ -122,6 +121,7 @@ function Header() {
|
|||
onClick={() => {
|
||||
requestRandomSkin();
|
||||
}}
|
||||
title="Random Skin"
|
||||
style={{
|
||||
paddingLeft: "0.2rem",
|
||||
paddingRight: "0.2rem",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React from "react";
|
||||
import React, { useMemo } from "react";
|
||||
import "./App.css";
|
||||
import { connect } from "react-redux";
|
||||
import * as Selectors from "./redux/selectors";
|
||||
|
|
@ -6,6 +6,7 @@ import * as Actions from "./redux/actionCreators";
|
|||
import { FixedSizeGrid as Grid } from "react-window";
|
||||
import Cell from "./Cell";
|
||||
import { HEADING_HEIGHT } from "./constants";
|
||||
import Zoom from "./Zoom";
|
||||
|
||||
const SkinTable = ({
|
||||
columnCount,
|
||||
|
|
@ -30,31 +31,56 @@ const SkinTable = ({
|
|||
return skin ? skin.hash : `unfectched-index-${requestToken}`;
|
||||
}
|
||||
const gridRef = React.useRef();
|
||||
const itemRef = React.useRef();
|
||||
React.useLayoutEffect(() => {
|
||||
if (gridRef.current == null) {
|
||||
return;
|
||||
}
|
||||
gridRef.current.scrollTo({ scrollLeft: 0, scrollTop: 0 });
|
||||
}, [skinCount]);
|
||||
|
||||
React.useLayoutEffect(() => {
|
||||
if (gridRef.current == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const itemRow = Math.floor(itemRef.current / columnCount);
|
||||
|
||||
gridRef.current.scrollTo({ scrollLeft: 0, scrollTop: rowHeight * itemRow });
|
||||
}, [rowHeight, columnCount]);
|
||||
|
||||
const showGrid = loadingSearchQuery || skinCount > 0 || searchQuery === "";
|
||||
|
||||
const onScroll = useMemo(() => {
|
||||
const half = Math.round(columnCount / 2);
|
||||
return (scrollData) => {
|
||||
itemRef.current =
|
||||
Math.round(scrollData.scrollTop / rowHeight) * columnCount + half;
|
||||
};
|
||||
}, [columnCount, rowHeight]);
|
||||
|
||||
return (
|
||||
<div id="infinite-skins" style={{ marginTop: HEADING_HEIGHT }}>
|
||||
{showGrid ? (
|
||||
<Grid
|
||||
ref={gridRef}
|
||||
itemKey={itemKey}
|
||||
itemData={{ columnCount, width: columnWidth, height: rowHeight }}
|
||||
columnCount={columnCount}
|
||||
columnWidth={columnWidth}
|
||||
height={windowHeight - HEADING_HEIGHT}
|
||||
rowCount={Math.ceil(skinCount / columnCount)}
|
||||
rowHeight={rowHeight}
|
||||
width={windowWidth}
|
||||
overscanRowsCount={5}
|
||||
style={{ overflowY: "scroll" }}
|
||||
>
|
||||
{Cell}
|
||||
</Grid>
|
||||
<>
|
||||
<Grid
|
||||
ref={gridRef}
|
||||
itemKey={itemKey}
|
||||
itemData={{ columnCount, width: columnWidth, height: rowHeight }}
|
||||
columnCount={columnCount}
|
||||
columnWidth={columnWidth}
|
||||
height={windowHeight - HEADING_HEIGHT}
|
||||
rowCount={Math.ceil(skinCount / columnCount)}
|
||||
rowHeight={rowHeight}
|
||||
width={windowWidth}
|
||||
overscanRowsCount={5}
|
||||
onScroll={onScroll}
|
||||
style={{ overflowY: "scroll" }}
|
||||
>
|
||||
{Cell}
|
||||
</Grid>
|
||||
<Zoom columnCount={columnCount} windowWidth={windowWidth} />
|
||||
</>
|
||||
) : (
|
||||
<div
|
||||
style={{
|
||||
|
|
|
|||
97
src/Zoom.js
Normal file
97
src/Zoom.js
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
import React from "react";
|
||||
import { useActionCreator } from "./hooks";
|
||||
import { SCREENSHOT_WIDTH } from "./constants";
|
||||
|
||||
function getScaleForColumnCount(columnCount, windowWidth) {
|
||||
return windowWidth / (columnCount * SCREENSHOT_WIDTH);
|
||||
}
|
||||
|
||||
const BACKGROUND_COLOR = "#000";
|
||||
|
||||
const Zoom = ({ columnCount, windowWidth }) => {
|
||||
const scaleUp = getScaleForColumnCount(columnCount - 1, windowWidth);
|
||||
const scaleDown = getScaleForColumnCount(columnCount + 1, windowWidth);
|
||||
const zoom = useActionCreator((scale) => ({ type: "SET_SCALE", scale }));
|
||||
const zoomIn = () => zoom(scaleUp);
|
||||
const zoomOut = () => zoom(scaleDown);
|
||||
|
||||
return (
|
||||
<div
|
||||
id="zoom"
|
||||
style={{
|
||||
position: "absolute",
|
||||
backgroundColor: BACKGROUND_COLOR,
|
||||
background: `linear-gradient(
|
||||
0deg,
|
||||
rgba(17, 17, 25, 1) 0%,
|
||||
rgba(40, 39, 66, 1) 66%,
|
||||
rgba(25, 25, 39, 1) 100%
|
||||
)`,
|
||||
boxShadow: "10px 10px 15px 0px rgb(0 0 0 / 85%)",
|
||||
bottom: 5,
|
||||
right: 5,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
border: "1px solid black",
|
||||
borderStyle: "solid",
|
||||
borderWidth: "1px",
|
||||
borderBottomColor: "rgb(87, 86, 102)",
|
||||
borderTopColor: "rgb(32, 31, 51)",
|
||||
borderRadius: 5,
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
title={"Zoom In"}
|
||||
onClick={zoomIn}
|
||||
disabled={scaleUp * SCREENSHOT_WIDTH >= 400}
|
||||
style={{ margin: 0 }}
|
||||
>
|
||||
+
|
||||
</Button>
|
||||
<hr
|
||||
style={{
|
||||
border: "none",
|
||||
backgroundColor: "rgba(255, 2550, 2550, 0.2)",
|
||||
color: "rgba(255, 2550, 2550, 0.4)",
|
||||
height: 1,
|
||||
marginTop: 0,
|
||||
marginBottom: 0,
|
||||
marginLeft: 3,
|
||||
marginRight: 3,
|
||||
padding: 0,
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
onClick={zoomOut}
|
||||
title={"Zoom Out"}
|
||||
disabled={scaleDown * SCREENSHOT_WIDTH <= 100}
|
||||
>
|
||||
{"–"}
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
function Button({ ...props }) {
|
||||
return (
|
||||
<button
|
||||
{...props}
|
||||
title={props.disabled ? `${props.title} (disabled)` : props.title}
|
||||
style={{
|
||||
margin: 0,
|
||||
border: "none",
|
||||
cursor: props.disabled ? "default" : "pointer",
|
||||
font: "inherit",
|
||||
fontWeight: 'bold',
|
||||
outline: "inherit",
|
||||
background: "none",
|
||||
paddingLeft: 14,
|
||||
paddingRight: 14,
|
||||
paddingTop: 9,
|
||||
paddingBottom: 9,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default Zoom;
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
const urlSearchParams = new URLSearchParams(window.location.search);
|
||||
const params = Object.fromEntries(urlSearchParams.entries());
|
||||
console.log(params)
|
||||
|
||||
export const SCREENSHOT_WIDTH = 275;
|
||||
export const SCREENSHOT_HEIGHT = 348;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue