mirror of
https://github.com/lrnselfreliance/wrolpi.git
synced 2026-10-26 19:01:39 -04:00
Handling situation where React Router may not be available for a Tag Label.
This commit is contained in:
parent
0920383963
commit
2cbc6e00e0
8 changed files with 56 additions and 33 deletions
|
|
@ -10,16 +10,16 @@ import {MoreRoute} from "./components/Apps";
|
|||
import {InventoryRoute} from "./components/Inventory";
|
||||
import {ArchiveRoute} from "./components/Archive";
|
||||
import {FilesRoute} from "./components/Files";
|
||||
import {useStatusInterval} from "./hooks/customHooks";
|
||||
import {StatusProvider} from "./hooks/customHooks";
|
||||
import {MapRoute} from "./components/Map";
|
||||
import {MediaContextProvider, mediaStyles, StatusContext, ThemeContext} from "./contexts/contexts";
|
||||
import {Header, ThemeWrapper} from "./components/Theme";
|
||||
import {Header, ThemeProvider} from "./components/Theme";
|
||||
import {Dashboard} from "./Dashboard";
|
||||
import {Donate} from "./components/Donate";
|
||||
import {useEventsInterval} from "./Events";
|
||||
import {SemanticToastContainer} from "react-semantic-toasts-2";
|
||||
import {FilePreviewWrapper} from "./components/FilePreview";
|
||||
import {TagsContext, useTagsInterval} from "./Tags";
|
||||
import {FilePreviewProvider} from "./components/FilePreview";
|
||||
import {TagsProvider} from "./Tags";
|
||||
|
||||
function PageNotFound() {
|
||||
const {t} = useContext(ThemeContext);
|
||||
|
|
@ -76,24 +76,21 @@ const router = createBrowserRouter(createRoutesFromElements(<Route
|
|||
</Route>));
|
||||
|
||||
export default function App() {
|
||||
const statusValue = useStatusInterval();
|
||||
const tagsValue = useTagsInterval();
|
||||
|
||||
useEventsInterval();
|
||||
|
||||
return <ThemeWrapper>
|
||||
<TagsContext.Provider value={tagsValue}>
|
||||
<FilePreviewWrapper>
|
||||
return <ThemeProvider>
|
||||
<TagsProvider>
|
||||
<FilePreviewProvider>
|
||||
{/* Context and style to handle switching between mobile/computer. */}
|
||||
<style>{mediaStyles}</style>
|
||||
{/* Toasts can be on any page. */}
|
||||
<SemanticToastContainer position='top-right'/>
|
||||
<MediaContextProvider>
|
||||
<StatusContext.Provider value={statusValue}>
|
||||
<StatusProvider>
|
||||
<RouterProvider router={router}/>
|
||||
</StatusContext.Provider>
|
||||
</StatusProvider>
|
||||
</MediaContextProvider>
|
||||
</FilePreviewWrapper>
|
||||
</TagsContext.Provider>
|
||||
</ThemeWrapper>
|
||||
</FilePreviewProvider>
|
||||
</TagsProvider>
|
||||
</ThemeProvider>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ import _ from "lodash";
|
|||
import {HexColorPicker} from "react-colorful";
|
||||
import {useRecurringTimeout} from "./hooks/customHooks";
|
||||
import {Media, ThemeContext} from "./contexts/contexts";
|
||||
import {Link} from "react-router-dom";
|
||||
import {Link, useNavigate} from "react-router-dom";
|
||||
|
||||
export const TagsContext = React.createContext({
|
||||
NameToTagLabel: null,
|
||||
|
|
@ -104,16 +104,30 @@ export function useTags() {
|
|||
</Label.Group>
|
||||
}
|
||||
|
||||
const TagLabelLink = ({name, props}) => {
|
||||
const to = `/?tag=${name}`;
|
||||
const style = {marginLeft: '0.3em', marginRight: '0.3em'};
|
||||
try {
|
||||
// We prefer to use Link to avoid reloading the page, check if React Router is available, so we can use it.
|
||||
useNavigate();
|
||||
return <Link to={to} style={style}>
|
||||
<NameToTagLabel name={name} {...props}/>
|
||||
</Link>
|
||||
} catch {
|
||||
// React Router is not available, use anchor.
|
||||
return <a href={to} style={style}>
|
||||
<NameToTagLabel name={name} {...props}/>
|
||||
</a>
|
||||
}
|
||||
}
|
||||
|
||||
const TagsLinkGroup = ({tagNames, ...props}) => {
|
||||
if (!tagNames || tagNames.length === 0) {
|
||||
return <React.Fragment/>;
|
||||
}
|
||||
|
||||
return <Label.Group tag>
|
||||
{tagNames.map(i =>
|
||||
<Link key={i} to={`/?tag=${i}`} style={{marginLeft: '0.3em', marginRight: '0.3em'}}>
|
||||
<NameToTagLabel name={i} {...props}/>
|
||||
</Link>
|
||||
)}
|
||||
{tagNames.map(i => <TagLabelLink key={i} name={i} props={props}/>)}
|
||||
</Label.Group>
|
||||
}
|
||||
|
||||
|
|
@ -227,7 +241,7 @@ function EditTagsModal() {
|
|||
onClose={localOnClose}
|
||||
>
|
||||
<ModalHeader>Edit Tags</ModalHeader>
|
||||
<div className={`scrolling content ${inverted ? 'inverted' : ''}`} id='editModalContent'>
|
||||
<div className={`content scrolling ${inverted}`} id='editModalContent'>
|
||||
<Label.Group tag>
|
||||
<Label size='large' style={{backgroundColor: tagColor, color: textColor}}>
|
||||
{tagName || 'Example Tag'}
|
||||
|
|
@ -459,3 +473,11 @@ export const TagsDropdown = ({value = [], onChange, ...props}) => {
|
|||
{...props}
|
||||
/>
|
||||
}
|
||||
|
||||
export const TagsProvider = (props) => {
|
||||
const tagsValue = useTagsInterval();
|
||||
|
||||
return <TagsContext.Provider value={tagsValue}>
|
||||
{props.children}
|
||||
</TagsContext.Provider>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -440,7 +440,7 @@ function ChannelRow({channel}) {
|
|||
|
||||
const {inverted} = React.useContext(ThemeContext);
|
||||
const editTo = `/videos/channel/${channel.id}/edit`;
|
||||
const buttonClass = `ui button secondary ${inverted ? 'inverted' : ''}`;
|
||||
const buttonClass = `ui button secondary ${inverted}`;
|
||||
|
||||
return <TableRow>
|
||||
<TableCell>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,7 @@
|
|||
import React from "react";
|
||||
import _ from "lodash";
|
||||
import {
|
||||
Grid,
|
||||
Header as SHeader,
|
||||
Image,
|
||||
} from "semantic-ui-react";
|
||||
import {TagsSelector} from "../Tags";
|
||||
import {Grid, Header as SHeader, Image,} from "semantic-ui-react";
|
||||
import {TagsProvider, TagsSelector} from "../Tags";
|
||||
import {Media} from "../contexts/contexts";
|
||||
import {encodeMediaPath} from "./Common";
|
||||
import {addTag, fetchFile, removeTag} from "../api";
|
||||
|
|
@ -152,7 +148,7 @@ export const FilePreviewContext = React.createContext({
|
|||
|
||||
const MAXIMUM_TEXT_SIZE = 5_000_000;
|
||||
|
||||
export function FilePreviewWrapper({children}) {
|
||||
export function FilePreviewProvider({children}) {
|
||||
const [previewFile, setPreviewFile] = React.useState(null);
|
||||
const [previewModal, setPreviewModal] = React.useState(null);
|
||||
const [callbacks, setCallbacks] = React.useState(null);
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ export const defaultTheme = lightTheme;
|
|||
export const systemTheme = 'system';
|
||||
export const themeSessionKey = 'color-scheme';
|
||||
|
||||
export function ThemeWrapper({children, ...props}) {
|
||||
export function ThemeProvider({children, ...props}) {
|
||||
if (!_.isEmpty(props)) {
|
||||
console.log(props);
|
||||
console.error('ThemeWrapper does not support props!');
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ function VideoPage({videoFile, prevFile, nextFile, fetchVideo, ...props}) {
|
|||
>
|
||||
<source src={videoUrl} type="video/mp4"/>
|
||||
{/* Only WebVTT captions can be displayed. */}
|
||||
{captionUrls.map(i => <track kind="captions" label="English" src={i} srcLang="en" default/>)}
|
||||
{captionUrls.map(i => <track key={i} kind="captions" label="English" src={i} srcLang="en" default/>)}
|
||||
</video>
|
||||
|
||||
<Container style={{marginTop: '1em'}}>
|
||||
|
|
|
|||
|
|
@ -717,6 +717,14 @@ export const useStatusInterval = () => {
|
|||
return {status, fetchStatus};
|
||||
}
|
||||
|
||||
export const StatusProvider = (props) => {
|
||||
const value = useStatusInterval();
|
||||
|
||||
return <StatusContext.Provider value={value}>
|
||||
{props.children}
|
||||
</StatusContext.Provider>
|
||||
}
|
||||
|
||||
|
||||
export const useVideoStatistics = () => {
|
||||
const [statistics, setStatistics] = useState({});
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ def download_channel(id_: int):
|
|||
@optional_session
|
||||
def search_channels_by_directory(name: str, limit: int = 5, session: Session = None) -> List[Channel]:
|
||||
channels = session.query(Channel) \
|
||||
.filter(Channel.directory.ilike(f'%{name}%')) \
|
||||
.filter(Channel.name.ilike(f'%{name}%')) \
|
||||
.order_by(asc(Channel.name)) \
|
||||
.limit(limit) \
|
||||
.all()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue