mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 04:14:39 +03:00
Make mobile menu behavior more consistent, and stats styles responsive (#391)
This commit is contained in:
@@ -111,6 +111,7 @@ func Start() {
|
|||||||
r.Mount("/studio", studioRoutes{}.Routes())
|
r.Mount("/studio", studioRoutes{}.Routes())
|
||||||
|
|
||||||
r.HandleFunc("/css", func(w http.ResponseWriter, r *http.Request) {
|
r.HandleFunc("/css", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Set("Content-Type", "text/css")
|
||||||
if !config.GetCSSEnabled() {
|
if !config.GetCSSEnabled() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,6 @@
|
|||||||
"length-zero-no-unit": true,
|
"length-zero-no-unit": true,
|
||||||
"max-empty-lines": 1,
|
"max-empty-lines": 1,
|
||||||
"max-nesting-depth": 4,
|
"max-nesting-depth": 4,
|
||||||
"max-line-length": 100,
|
|
||||||
"media-feature-colon-space-after": "always",
|
"media-feature-colon-space-after": "always",
|
||||||
"media-feature-colon-space-before": "never",
|
"media-feature-colon-space-before": "never",
|
||||||
"media-feature-range-operator-space-after": "always",
|
"media-feature-range-operator-space-after": "always",
|
||||||
|
|||||||
@@ -107,7 +107,11 @@ export const ListFilter: React.FC<IListFilterProps> = (
|
|||||||
|
|
||||||
function renderSortByOptions() {
|
function renderSortByOptions() {
|
||||||
return props.filter.sortByOptions.map(option => (
|
return props.filter.sortByOptions.map(option => (
|
||||||
<Dropdown.Item onClick={onChangeSortBy} key={option} className="bg-secondary text-white">
|
<Dropdown.Item
|
||||||
|
onClick={onChangeSortBy}
|
||||||
|
key={option}
|
||||||
|
className="bg-secondary text-white"
|
||||||
|
>
|
||||||
{option}
|
{option}
|
||||||
</Dropdown.Item>
|
</Dropdown.Item>
|
||||||
));
|
));
|
||||||
@@ -186,7 +190,11 @@ export const ListFilter: React.FC<IListFilterProps> = (
|
|||||||
function renderSelectAll() {
|
function renderSelectAll() {
|
||||||
if (props.onSelectAll) {
|
if (props.onSelectAll) {
|
||||||
return (
|
return (
|
||||||
<Dropdown.Item key="select-all" className="bg-secondary text-white" onClick={() => onSelectAll()}>
|
<Dropdown.Item
|
||||||
|
key="select-all"
|
||||||
|
className="bg-secondary text-white"
|
||||||
|
onClick={() => onSelectAll()}
|
||||||
|
>
|
||||||
Select All
|
Select All
|
||||||
</Dropdown.Item>
|
</Dropdown.Item>
|
||||||
);
|
);
|
||||||
@@ -196,7 +204,11 @@ export const ListFilter: React.FC<IListFilterProps> = (
|
|||||||
function renderSelectNone() {
|
function renderSelectNone() {
|
||||||
if (props.onSelectNone) {
|
if (props.onSelectNone) {
|
||||||
return (
|
return (
|
||||||
<Dropdown.Item key="select-none" className="bg-secondary text-white" onClick={() => onSelectNone()}>
|
<Dropdown.Item
|
||||||
|
key="select-none"
|
||||||
|
className="bg-secondary text-white"
|
||||||
|
onClick={() => onSelectNone()}
|
||||||
|
>
|
||||||
Select None
|
Select None
|
||||||
</Dropdown.Item>
|
</Dropdown.Item>
|
||||||
);
|
);
|
||||||
@@ -209,7 +221,11 @@ export const ListFilter: React.FC<IListFilterProps> = (
|
|||||||
if (props.otherOperations) {
|
if (props.otherOperations) {
|
||||||
props.otherOperations.forEach(o => {
|
props.otherOperations.forEach(o => {
|
||||||
options.push(
|
options.push(
|
||||||
<Dropdown.Item key={o.text} className="bg-secondary text-white" onClick={o.onClick}>
|
<Dropdown.Item
|
||||||
|
key={o.text}
|
||||||
|
className="bg-secondary text-white"
|
||||||
|
onClick={o.onClick}
|
||||||
|
>
|
||||||
{o.text}
|
{o.text}
|
||||||
</Dropdown.Item>
|
</Dropdown.Item>
|
||||||
);
|
);
|
||||||
@@ -222,7 +238,9 @@ export const ListFilter: React.FC<IListFilterProps> = (
|
|||||||
<Dropdown.Toggle variant="secondary" id="more-menu">
|
<Dropdown.Toggle variant="secondary" id="more-menu">
|
||||||
<Icon icon="ellipsis-h" />
|
<Icon icon="ellipsis-h" />
|
||||||
</Dropdown.Toggle>
|
</Dropdown.Toggle>
|
||||||
<Dropdown.Menu className="bg-secondary text-white">{options}</Dropdown.Menu>
|
<Dropdown.Menu className="bg-secondary text-white">
|
||||||
|
{options}
|
||||||
|
</Dropdown.Menu>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -278,7 +296,9 @@ export const ListFilter: React.FC<IListFilterProps> = (
|
|||||||
<Dropdown.Toggle split variant="secondary" id="more-menu">
|
<Dropdown.Toggle split variant="secondary" id="more-menu">
|
||||||
{props.filter.sortBy}
|
{props.filter.sortBy}
|
||||||
</Dropdown.Toggle>
|
</Dropdown.Toggle>
|
||||||
<Dropdown.Menu className="bg-secondary text-white">{renderSortByOptions()}</Dropdown.Menu>
|
<Dropdown.Menu className="bg-secondary text-white">
|
||||||
|
{renderSortByOptions()}
|
||||||
|
</Dropdown.Menu>
|
||||||
<OverlayTrigger
|
<OverlayTrigger
|
||||||
overlay={
|
overlay={
|
||||||
<Tooltip id="sort-direction-tooltip">
|
<Tooltip id="sort-direction-tooltip">
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
import { FormattedMessage } from "react-intl";
|
import { FormattedMessage } from "react-intl";
|
||||||
import { Nav, Navbar, Button } from "react-bootstrap";
|
import { Nav, Navbar, Button } from "react-bootstrap";
|
||||||
import { IconName } from "@fortawesome/fontawesome-svg-core";
|
import { IconName } from "@fortawesome/fontawesome-svg-core";
|
||||||
@@ -48,6 +48,31 @@ const menuItems: IMenuItem[] = [
|
|||||||
|
|
||||||
export const MainNavbar: React.FC = () => {
|
export const MainNavbar: React.FC = () => {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
const [expanded, setExpanded] = useState(false);
|
||||||
|
// react-bootstrap typing bug
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
const navbarRef = useRef<any>();
|
||||||
|
|
||||||
|
const maybeCollapse = (event: Event) => {
|
||||||
|
if (
|
||||||
|
navbarRef.current &&
|
||||||
|
event.target instanceof Node &&
|
||||||
|
!navbarRef.current.contains(event.target)
|
||||||
|
) {
|
||||||
|
setExpanded(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (expanded) {
|
||||||
|
document.addEventListener("click", maybeCollapse);
|
||||||
|
document.addEventListener("touchstart", maybeCollapse);
|
||||||
|
}
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener("click", maybeCollapse);
|
||||||
|
document.removeEventListener("touchstart", maybeCollapse);
|
||||||
|
};
|
||||||
|
}, [expanded]);
|
||||||
|
|
||||||
const path =
|
const path =
|
||||||
location.pathname === "/performers"
|
location.pathname === "/performers"
|
||||||
@@ -74,8 +99,15 @@ export const MainNavbar: React.FC = () => {
|
|||||||
bg="dark"
|
bg="dark"
|
||||||
className="top-nav"
|
className="top-nav"
|
||||||
expand="md"
|
expand="md"
|
||||||
|
expanded={expanded}
|
||||||
|
onToggle={setExpanded}
|
||||||
|
ref={navbarRef}
|
||||||
>
|
>
|
||||||
<Navbar.Brand as="div" className="order-1 order-md-0">
|
<Navbar.Brand
|
||||||
|
as="div"
|
||||||
|
className="order-1 order-md-0"
|
||||||
|
onClick={() => setExpanded(false)}
|
||||||
|
>
|
||||||
<Link to="/">
|
<Link to="/">
|
||||||
<Button className="minimal brand-link d-none d-md-inline-block">
|
<Button className="minimal brand-link d-none d-md-inline-block">
|
||||||
Stash
|
Stash
|
||||||
@@ -109,8 +141,8 @@ export const MainNavbar: React.FC = () => {
|
|||||||
</Navbar.Collapse>
|
</Navbar.Collapse>
|
||||||
<Nav className="order-2">
|
<Nav className="order-2">
|
||||||
<div className="d-none d-sm-block">{newButton}</div>
|
<div className="d-none d-sm-block">{newButton}</div>
|
||||||
<LinkContainer exact to="/settings">
|
<LinkContainer exact to="/settings" onClick={() => setExpanded(false)}>
|
||||||
<Button className="minimal">
|
<Button className="minimal settings-button">
|
||||||
<Icon icon="cog" />
|
<Icon icon="cog" />
|
||||||
</Button>
|
</Button>
|
||||||
</LinkContainer>
|
</LinkContainer>
|
||||||
|
|||||||
@@ -236,7 +236,8 @@ export const SceneCard: React.FC<ISceneCardProps> = (
|
|||||||
</h5>
|
</h5>
|
||||||
<span>{props.scene.date}</span>
|
<span>{props.scene.date}</span>
|
||||||
<p>
|
<p>
|
||||||
{props.scene.details && TextUtils.truncate(props.scene.details, 100, "... (continued)")}
|
{props.scene.details &&
|
||||||
|
TextUtils.truncate(props.scene.details, 100, "... (continued)")}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -137,10 +137,7 @@ export const Scene: React.FC = () => {
|
|||||||
>
|
>
|
||||||
<SceneFileInfoPanel scene={scene} />
|
<SceneFileInfoPanel scene={scene} />
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab
|
<Tab eventKey="scene-edit-panel" title="Edit">
|
||||||
eventKey="scene-edit-panel"
|
|
||||||
title="Edit"
|
|
||||||
>
|
|
||||||
<SceneEditPanel
|
<SceneEditPanel
|
||||||
scene={scene}
|
scene={scene}
|
||||||
onUpdate={newScene => setScene(newScene)}
|
onUpdate={newScene => setScene(newScene)}
|
||||||
|
|||||||
@@ -344,7 +344,9 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
|
|||||||
<td>Studio</td>
|
<td>Studio</td>
|
||||||
<td>
|
<td>
|
||||||
<StudioSelect
|
<StudioSelect
|
||||||
onSelect={items => setStudioId(items.length > 0 ? items[0]?.id : undefined)}
|
onSelect={items =>
|
||||||
|
setStudioId(items.length > 0 ? items[0]?.id : undefined)
|
||||||
|
}
|
||||||
ids={studioId ? [studioId] : []}
|
ids={studioId ? [studioId] : []}
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@@ -168,7 +168,11 @@ export const SettingsTasksPanel: React.FC = () => {
|
|||||||
<Form.Group>
|
<Form.Group>
|
||||||
<h5>Status: {status}</h5>
|
<h5>Status: {status}</h5>
|
||||||
{!!status && status !== "Idle" ? (
|
{!!status && status !== "Idle" ? (
|
||||||
<ProgressBar animated now={progress} label={`${progress.toFixed(0)}%`} />
|
<ProgressBar
|
||||||
|
animated
|
||||||
|
now={progress}
|
||||||
|
label={`${progress.toFixed(0)}%`}
|
||||||
|
/>
|
||||||
) : (
|
) : (
|
||||||
""
|
""
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -73,7 +73,9 @@ export const SceneGallerySelect: React.FC<ISceneGallerySelect> = props => {
|
|||||||
|
|
||||||
const onChange = (selectedItems: ValueType<Option>) => {
|
const onChange = (selectedItems: ValueType<Option>) => {
|
||||||
const selectedItem = getSelectedValues(selectedItems)[0];
|
const selectedItem = getSelectedValues(selectedItems)[0];
|
||||||
props.onSelect(selectedItem ? galleries.find(g => g.id === selectedItem) : undefined);
|
props.onSelect(
|
||||||
|
selectedItem ? galleries.find(g => g.id === selectedItem) : undefined
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const selectedOptions: Option[] = props.initialId
|
const selectedOptions: Option[] = props.initialId
|
||||||
@@ -211,7 +213,7 @@ export const StudioSelect: React.FC<IFilterProps> = props => {
|
|||||||
const { data, loading } = StashService.useAllStudiosForFilter();
|
const { data, loading } = StashService.useAllStudiosForFilter();
|
||||||
|
|
||||||
const normalizedData = data?.allStudios ?? [];
|
const normalizedData = data?.allStudios ?? [];
|
||||||
|
|
||||||
const items = (normalizedData.length > 0
|
const items = (normalizedData.length > 0
|
||||||
? [{ name: "None", id: "0" }, ...normalizedData]
|
? [{ name: "None", id: "0" }, ...normalizedData]
|
||||||
: []
|
: []
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export const Stats: React.FC = () => {
|
|||||||
return (
|
return (
|
||||||
<div className="mt-5">
|
<div className="mt-5">
|
||||||
<div className="col col-sm-8 m-sm-auto row stats">
|
<div className="col col-sm-8 m-sm-auto row stats">
|
||||||
<div className="flex-grow-1">
|
<div className="stats-element">
|
||||||
<p className="title">
|
<p className="title">
|
||||||
<FormattedNumber value={data.stats.scene_count} />
|
<FormattedNumber value={data.stats.scene_count} />
|
||||||
</p>
|
</p>
|
||||||
@@ -21,7 +21,7 @@ export const Stats: React.FC = () => {
|
|||||||
<FormattedMessage id="scenes" defaultMessage="Scenes" />
|
<FormattedMessage id="scenes" defaultMessage="Scenes" />
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-grow-1">
|
<div className="stats-element">
|
||||||
<p className="title">
|
<p className="title">
|
||||||
<FormattedNumber value={data.stats.gallery_count} />
|
<FormattedNumber value={data.stats.gallery_count} />
|
||||||
</p>
|
</p>
|
||||||
@@ -29,7 +29,7 @@ export const Stats: React.FC = () => {
|
|||||||
<FormattedMessage id="galleries" defaultMessage="Galleries" />
|
<FormattedMessage id="galleries" defaultMessage="Galleries" />
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-grow-1">
|
<div className="stats-element">
|
||||||
<p className="title">
|
<p className="title">
|
||||||
<FormattedNumber value={data.stats.performer_count} />
|
<FormattedNumber value={data.stats.performer_count} />
|
||||||
</p>
|
</p>
|
||||||
@@ -37,7 +37,7 @@ export const Stats: React.FC = () => {
|
|||||||
<FormattedMessage id="performers" defaultMessage="Performers" />
|
<FormattedMessage id="performers" defaultMessage="Performers" />
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-grow-1">
|
<div className="stats-element">
|
||||||
<p className="title">
|
<p className="title">
|
||||||
<FormattedNumber value={data.stats.studio_count} />
|
<FormattedNumber value={data.stats.studio_count} />
|
||||||
</p>
|
</p>
|
||||||
@@ -45,7 +45,7 @@ export const Stats: React.FC = () => {
|
|||||||
<FormattedMessage id="studios" defaultMessage="Studios" />
|
<FormattedMessage id="studios" defaultMessage="Studios" />
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-grow-1">
|
<div className="stats-element">
|
||||||
<p className="title">
|
<p className="title">
|
||||||
<FormattedNumber value={data.stats.tag_count} />
|
<FormattedNumber value={data.stats.tag_count} />
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export class StashService {
|
|||||||
public static client: ApolloClient<NormalizedCacheObject>;
|
public static client: ApolloClient<NormalizedCacheObject>;
|
||||||
private static cache: InMemoryCache;
|
private static cache: InMemoryCache;
|
||||||
|
|
||||||
public static getPlatformURL(ws? : boolean) {
|
public static getPlatformURL(ws?: boolean) {
|
||||||
const platformUrl = new URL(window.location.origin);
|
const platformUrl = new URL(window.location.origin);
|
||||||
|
|
||||||
if (!process.env.NODE_ENV || process.env.NODE_ENV === "development") {
|
if (!process.env.NODE_ENV || process.env.NODE_ENV === "development") {
|
||||||
@@ -36,7 +36,7 @@ export class StashService {
|
|||||||
if (platformUrl.protocol === "https:") {
|
if (platformUrl.protocol === "https:") {
|
||||||
wsPlatformUrl.protocol = "wss:";
|
wsPlatformUrl.protocol = "wss:";
|
||||||
}
|
}
|
||||||
|
|
||||||
const url = `${platformUrl.toString().slice(0, -1)}/graphql`;
|
const url = `${platformUrl.toString().slice(0, -1)}/graphql`;
|
||||||
const wsUrl = `${wsPlatformUrl.toString().slice(0, -1)}/graphql`;
|
const wsUrl = `${wsPlatformUrl.toString().slice(0, -1)}/graphql`;
|
||||||
|
|
||||||
|
|||||||
@@ -41,8 +41,7 @@ function useLocalForage(
|
|||||||
if (!Object.is(parsed, null)) {
|
if (!Object.is(parsed, null)) {
|
||||||
setData(parsed);
|
setData(parsed);
|
||||||
Cache[key] = parsed;
|
Cache[key] = parsed;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
setData({});
|
setData({});
|
||||||
Cache[key] = {};
|
Cache[key] = {};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,27 +29,31 @@ a {
|
|||||||
color: $primary;
|
color: $primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
code, .code {
|
code,
|
||||||
|
.code {
|
||||||
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace;
|
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-control, .text-input {
|
.input-control,
|
||||||
color: $text-color;
|
.text-input {
|
||||||
border: 0;
|
border: 0;
|
||||||
box-shadow:0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4);
|
box-shadow: 0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), inset 0 0 0 1px rgba(16, 22, 26, .3), inset 0 1px 1px rgba(16, 22, 26, .4);
|
||||||
|
color: $text-color;
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
color: $text-color;
|
|
||||||
border: 0;
|
border: 0;
|
||||||
box-shadow: 0 0 0 1px $primary, 0 0 0 1px $primary, 0 0 0 3px rgba(19,124,189,.3), inset 0 0 0 1px rgba(16,22,26,.3), inset 0 1px 1px rgba(16,22,26,.4);
|
box-shadow: 0 0 0 1px $primary, 0 0 0 1px $primary, 0 0 0 3px rgba(19, 124, 189, .3), inset 0 0 0 1px rgba(16, 22, 26, .3), inset 0 1px 1px rgba(16, 22, 26, .4);
|
||||||
|
color: $text-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-input, .text-input:focus {
|
.text-input,
|
||||||
|
.text-input:focus {
|
||||||
background-color: $textfield-bg;
|
background-color: $textfield-bg;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-control, .input-control:focus {
|
.input-control,
|
||||||
|
.input-control:focus {
|
||||||
background-color: $secondary;
|
background-color: $secondary;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,6 +89,7 @@ code, .code {
|
|||||||
.scene-card-video {
|
.scene-card-video {
|
||||||
max-height: 180px;
|
max-height: 180px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.previewable.portrait {
|
.previewable.portrait {
|
||||||
height: 180px;
|
height: 180px;
|
||||||
}
|
}
|
||||||
@@ -96,6 +101,7 @@ code, .code {
|
|||||||
.scene-card-video {
|
.scene-card-video {
|
||||||
max-height: 240px;
|
max-height: 240px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.previewable.portrait {
|
.previewable.portrait {
|
||||||
height: 240px;
|
height: 240px;
|
||||||
}
|
}
|
||||||
@@ -107,6 +113,7 @@ code, .code {
|
|||||||
.scene-card-video {
|
.scene-card-video {
|
||||||
max-height: 360px;
|
max-height: 360px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.previewable.portrait {
|
.previewable.portrait {
|
||||||
height: 360px;
|
height: 360px;
|
||||||
}
|
}
|
||||||
@@ -118,6 +125,7 @@ code, .code {
|
|||||||
.scene-card-video {
|
.scene-card-video {
|
||||||
max-height: 480px;
|
max-height: 480px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.portrait {
|
.portrait {
|
||||||
height: 480px;
|
height: 480px;
|
||||||
}
|
}
|
||||||
@@ -131,13 +139,15 @@ code, .code {
|
|||||||
|
|
||||||
/* this is a bit of a hack, because we can't supply direct class names
|
/* this is a bit of a hack, because we can't supply direct class names
|
||||||
to the react-select controls */
|
to the react-select controls */
|
||||||
|
/* stylelint-disable selector-class-pattern */
|
||||||
div.react-select__control {
|
div.react-select__control {
|
||||||
background-color: $secondary;
|
background-color: $secondary;
|
||||||
border-color: $secondary;
|
border-color: $secondary;
|
||||||
color: $text-color;
|
color: $text-color;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
.react-select__single-value, .react-select__input {
|
.react-select__single-value,
|
||||||
|
.react-select__input {
|
||||||
color: $text-color;
|
color: $text-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,6 +170,7 @@ div.react-select__menu {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* stylelint-enable selector-class-pattern */
|
||||||
|
|
||||||
.image-thumbnail {
|
.image-thumbnail {
|
||||||
height: 100px;
|
height: 100px;
|
||||||
@@ -221,9 +232,9 @@ div.react-select__menu {
|
|||||||
|
|
||||||
.filter-container,
|
.filter-container,
|
||||||
.operation-container {
|
.operation-container {
|
||||||
|
align-items: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
|
||||||
margin: 0 auto 10px;
|
margin: 0 auto 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -375,6 +386,11 @@ div.react-select__menu {
|
|||||||
.btn {
|
.btn {
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.settings-button {
|
||||||
|
padding-left: 1rem;
|
||||||
|
padding-right: 1rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -383,9 +399,18 @@ div.react-select__menu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.stats {
|
.stats {
|
||||||
|
&-element {
|
||||||
|
flex-grow: 1;
|
||||||
|
margin: auto .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-size: 3vw;
|
font-size: 3vw;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
|
@media (max-width: 576px) {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.heading {
|
.heading {
|
||||||
|
|||||||
@@ -7,16 +7,20 @@ import { StashService } from "./core/StashService";
|
|||||||
import "./index.scss";
|
import "./index.scss";
|
||||||
import * as serviceWorker from "./serviceWorker";
|
import * as serviceWorker from "./serviceWorker";
|
||||||
|
|
||||||
ReactDOM.render((
|
ReactDOM.render(
|
||||||
<>
|
<>
|
||||||
<link rel="stylesheet" type="text/css" href={StashService.getPlatformURL() + "css"}/>
|
<link
|
||||||
<BrowserRouter>
|
rel="stylesheet"
|
||||||
<ApolloProvider client={StashService.initialize()!}>
|
type="text/css"
|
||||||
<App />
|
href={`${StashService.getPlatformURL()}css`}
|
||||||
</ApolloProvider>
|
/>
|
||||||
</BrowserRouter>
|
<BrowserRouter>
|
||||||
</>
|
<ApolloProvider client={StashService.initialize()!}>
|
||||||
), document.getElementById("root")
|
<App />
|
||||||
|
</ApolloProvider>
|
||||||
|
</BrowserRouter>
|
||||||
|
</>,
|
||||||
|
document.getElementById("root")
|
||||||
);
|
);
|
||||||
|
|
||||||
// If you want your app to work offline and load faster, you can change
|
// If you want your app to work offline and load faster, you can change
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ $pre-color: $text-color;
|
|||||||
$navbar-dark-color: rgb(245, 248, 250);
|
$navbar-dark-color: rgb(245, 248, 250);
|
||||||
$popover-bg: $secondary;
|
$popover-bg: $secondary;
|
||||||
$dark-text: #182026;
|
$dark-text: #182026;
|
||||||
$textfield-bg: rgba(16,22,26,.3);
|
$textfield-bg: rgba(16, 22, 26, .3);
|
||||||
|
|
||||||
@import "node_modules/bootstrap/scss/bootstrap";
|
@import "node_modules/bootstrap/scss/bootstrap";
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user