optimizations, added captions

This commit is contained in:
2023-11-02 10:05:34 +01:00
parent 19f9b10844
commit 00b3fccbdc
7 changed files with 107 additions and 21 deletions

View File

@@ -28,6 +28,7 @@ import FreeSpaceIndicator from './components/FreeSpaceIndicator'
import Logout from './components/Logout'
import SocketSubscriber from './components/SocketSubscriber'
import ThemeToggler from './components/ThemeToggler'
import { useI18n } from './hooks/useI18n'
import Toaster from './providers/ToasterProvider'
export default function Layout() {
@@ -50,6 +51,8 @@ export default function Layout() {
const toggleDrawer = () => setOpen(state => !state)
const { i18n } = useI18n()
return (
<ThemeProvider theme={theme}>
<SocketSubscriber>
@@ -88,10 +91,11 @@ export default function Layout() {
display: 'flex',
alignItems: 'center',
flexWrap: 'wrap',
gap: 3,
}}>
<SettingsEthernet />
<span>
&nbsp;{isConnected ? settings.serverAddr : 'not connected'}
{isConnected ? settings.serverAddr : i18n.t('notConnectedText')}
</span>
</div>
</Toolbar>
@@ -121,7 +125,7 @@ export default function Layout() {
<ListItemIcon>
<Dashboard />
</ListItemIcon>
<ListItemText primary="Home" />
<ListItemText primary={i18n.t('homeButtonLabel')} />
</ListItemButton>
</Link>
<Link to={'/archive'} style={
@@ -134,7 +138,7 @@ export default function Layout() {
<ListItemIcon>
<DownloadIcon />
</ListItemIcon>
<ListItemText primary="Archive" />
<ListItemText primary={i18n.t('archiveButtonLabel')} />
</ListItemButton>
</Link>
<Link to={'/settings'} style={
@@ -147,7 +151,7 @@ export default function Layout() {
<ListItemIcon>
<SettingsIcon />
</ListItemIcon>
<ListItemText primary="Settings" />
<ListItemText primary={i18n.t('settingsButtonLabel')} />
</ListItemButton>
</Link>
<ThemeToggler />

View File

@@ -35,6 +35,12 @@ languages:
playlistCheckbox: Download playlist (it will take time, after submitting you may close this window)
restartAppMessage: Needs a page reload to take effect
servedFromReverseProxyCheckbox: Is behind a reverse proxy subfolder
newDownloadButton: New download
homeButtonLabel: Home
archiveButtonLabel: Archive
settingsButtonLabel: Settings
rpcAuthenticationLabel: RPC authentication
themeTogglerLabel: Theme toggler
appTitle: App title
savedTemplates: Saved templates
templatesEditor: Templates editor
@@ -75,6 +81,14 @@ languages:
playlistCheckbox: Télécharger la liste de lecture (cela prendra du temps, vous pouvez fermer cette fenêtre après l'avoir validée)
restartAppMessage: Nécessite un rechargement de la page pour prendre effet
servedFromReverseProxyCheckbox: Est derrière un sous-dossier de proxy inverse
notConnectedText: not connected
settingsLabel: Settings
newDownloadButton: New download
homeButtonLabel: Home
archiveButtonLabel: Archive
settingsButtonLabel: Settings
rpcAuthenticationLabel: RPC authentication
themeTogglerLabel: Theme toggler
appTitle: Nom de l'application
savedTemplates: Saved templates
templatesEditor: Templates editor
@@ -114,6 +128,12 @@ languages:
playlistCheckbox: Download playlist (richiederà tempo, puoi chiudere la finestra dopo l'inoltro)
restartAppMessage: La finestra deve essere ricaricata perché abbia effetto
servedFromReverseProxyCheckbox: Is behind a reverse proxy subfolder
newDownloadButton: Nuovo download
homeButtonLabel: Home
archiveButtonLabel: Archive
settingsButtonLabel: Settings
rpcAuthenticationLabel: RPC authentication
themeTogglerLabel: Theme toggler
appTitle: Titolo applicazione
savedTemplates: Template salvati
templatesEditor: Editor template
@@ -154,6 +174,12 @@ languages:
playlistCheckbox: 下载播放列表(可能需要一段时间,提交后可以关闭页面等待)
restartAppMessage: 需要刷新页面才能生效
servedFromReverseProxyCheckbox: 处于反向代理的子目录后
newDownloadButton: New download
homeButtonLabel: Home
archiveButtonLabel: Archive
settingsButtonLabel: Settings
rpcAuthenticationLabel: RPC authentication
themeTogglerLabel: Theme toggler
appTitle: App 标题
savedTemplates: Saved templates
templatesEditor: Templates editor
@@ -192,6 +218,12 @@ languages:
clipboardAction: Copied URL to clipboard
playlistCheckbox: Download playlist (it will take time, after submitting you may even close this window)
servedFromReverseProxyCheckbox: Is behind a reverse proxy subfolder
newDownloadButton: New download
homeButtonLabel: Home
archiveButtonLabel: Archive
settingsButtonLabel: Settings
rpcAuthenticationLabel: RPC authentication
themeTogglerLabel: Theme toggler
appTitle: App title
savedTemplates: Saved templates
templatesEditor: Templates editor
@@ -230,6 +262,12 @@ languages:
clipboardAction: URL скопирован в буфер обмена
playlistCheckbox: Download playlist (it will take time, after submitting you may even close this window)
servedFromReverseProxyCheckbox: Is behind a reverse proxy subfolder
newDownloadButton: New download
homeButtonLabel: Home
archiveButtonLabel: Archive
settingsButtonLabel: Settings
rpcAuthenticationLabel: RPC authentication
themeTogglerLabel: Theme toggler
appTitle: App title
savedTemplates: Saved templates
templatesEditor: Templates editor
@@ -268,6 +306,12 @@ languages:
clipboardAction: Copied URL to clipboard
playlistCheckbox: Download playlist (it will take time, after submitting you may even close this window)
servedFromReverseProxyCheckbox: Is behind a reverse proxy subfolder
newDownloadButton: New download
homeButtonLabel: Home
archiveButtonLabel: Archive
settingsButtonLabel: Settings
rpcAuthenticationLabel: RPC authentication
themeTogglerLabel: Theme toggler
appTitle: App title
savedTemplates: Saved templates
templatesEditor: Templates editor
@@ -307,6 +351,12 @@ languages:
clipboardAction: Copied URL to clipboard
playlistCheckbox: Download playlist (it will take time, after submitting you may even close this window)
servedFromReverseProxyCheckbox: Is behind a reverse proxy subfolder
newDownloadButton: New download
homeButtonLabel: Home
archiveButtonLabel: Archive
settingsButtonLabel: Settings
rpcAuthenticationLabel: RPC authentication
themeTogglerLabel: Theme toggler
appTitle: App title
savedTemplates: Saved templates
templatesEditor: Templates editor
@@ -345,6 +395,12 @@ languages:
clipboardAction: Copied URL to clipboard
playlistCheckbox: Download playlist (it will take time, after submitting you may even close this window)
servedFromReverseProxyCheckbox: Is behind a reverse proxy subfolder
newDownloadButton: New download
homeButtonLabel: Home
archiveButtonLabel: Archive
settingsButtonLabel: Settings
rpcAuthenticationLabel: RPC authentication
themeTogglerLabel: Theme toggler
appTitle: App title
savedTemplates: Saved templates
templatesEditor: Templates editor
@@ -383,6 +439,12 @@ languages:
clipboardAction: URL скопійовано в буфер обміну
playlistCheckbox: Download playlist (it will take time, after submitting you may even close this window)
servedFromReverseProxyCheckbox: Is behind a reverse proxy subfolder
newDownloadButton: New download
homeButtonLabel: Home
archiveButtonLabel: Archive
settingsButtonLabel: Settings
rpcAuthenticationLabel: RPC authentication
themeTogglerLabel: Theme toggler
appTitle: App title
savedTemplates: Saved templates
templatesEditor: Templates editor
@@ -421,6 +483,12 @@ languages:
clipboardAction: Adres URL zostanie skopiowany do schowka
playlistCheckbox: Download playlist (it will take time, after submitting you may even close this window)
servedFromReverseProxyCheckbox: Is behind a reverse proxy subfolder
newDownloadButton: New download
homeButtonLabel: Home
archiveButtonLabel: Archive
settingsButtonLabel: Settings
rpcAuthenticationLabel: RPC authentication
themeTogglerLabel: Theme toggler
appTitle: App title
savedTemplates: Saved templates
templatesEditor: Templates editor

View File

@@ -48,7 +48,7 @@ const HomeSpeedDial: React.FC<Props> = ({ onDownloadOpen, onEditorOpen }) => {
/>
<SpeedDialAction
icon={<AddCircleIcon />}
tooltipTitle={i18n.t('newDownload')}
tooltipTitle={i18n.t('newDownloadButton')}
onClick={onDownloadOpen}
/>
</SpeedDial>

View File

@@ -1,8 +1,9 @@
import { ListItemButton, ListItemIcon, ListItemText } from '@mui/material'
import LogoutIcon from '@mui/icons-material/Logout'
import { ListItemButton, ListItemIcon, ListItemText } from '@mui/material'
import { useNavigate } from 'react-router-dom'
import { useRecoilValue } from 'recoil'
import { serverURL } from '../atoms/settings'
import { useI18n } from '../hooks/useI18n'
export default function Logout() {
const navigate = useNavigate()
@@ -15,12 +16,14 @@ export default function Logout() {
}
}
const { i18n } = useI18n()
return (
<ListItemButton onClick={logout}>
<ListItemIcon>
<LogoutIcon />
</ListItemIcon>
<ListItemText primary="RPC authentication" />
<ListItemText primary={i18n.t('rpcAuthenticationLabel')} />
</ListItemButton>
)
}

View File

@@ -4,6 +4,7 @@ import BrightnessAuto from '@mui/icons-material/BrightnessAuto'
import { ListItemButton, ListItemIcon, ListItemText } from '@mui/material'
import { useRecoilState } from 'recoil'
import { Theme, themeState } from '../atoms/settings'
import { useI18n } from '../hooks/useI18n'
const ThemeToggler: React.FC = () => {
const [theme, setTheme] = useRecoilState(themeState)
@@ -17,6 +18,8 @@ const ThemeToggler: React.FC = () => {
const themes: Theme[] = ['system', 'light', 'dark']
const currentTheme = themes.indexOf(theme)
const { i18n } = useI18n()
return (
<ListItemButton onClick={() => {
setTheme(themes[(currentTheme + 1) % themes.length])
@@ -24,7 +27,7 @@ const ThemeToggler: React.FC = () => {
<ListItemIcon>
{actions[theme]}
</ListItemIcon>
<ListItemText primary="Toggle theme" />
<ListItemText primary={i18n.t('themeTogglerLabel')} />
</ListItemButton>
)
}

View File

@@ -4,9 +4,10 @@ import i18n from "../assets/i18n.yaml"
export default class I18nBuilder {
private language: string
private textMap = i18n.languages
private current: string[]
constructor(language: string) {
this.language = language
this.setLanguage(language)
}
getLanguage(): string {
@@ -15,13 +16,12 @@ export default class I18nBuilder {
setLanguage(language: string): void {
this.language = language
this.current = this.textMap[this.language]
}
t(key: string): string {
const map = this.textMap[this.language]
if (map) {
const translation = map[key]
return translation ?? 'caption not defined'
if (this.current) {
return this.current[key] ?? 'caption not defined'
}
return 'caption not defined'
}

View File

@@ -27,14 +27,22 @@ type DirectoryEntry struct {
}
func walkDir(root string) (*[]DirectoryEntry, error) {
files := []DirectoryEntry{}
dirs, err := os.ReadDir(root)
if err != nil {
return nil, err
}
var validEntries int
for _, d := range dirs {
if utils.IsValidEntry(d) {
validEntries++
}
}
files := make([]DirectoryEntry, validEntries)
for i, d := range dirs {
if !utils.IsValidEntry(d) {
continue
}
@@ -46,7 +54,7 @@ func walkDir(root string) (*[]DirectoryEntry, error) {
return nil, err
}
files = append(files, DirectoryEntry{
files[i] = DirectoryEntry{
Path: path,
Name: d.Name(),
Size: info.Size(),
@@ -54,7 +62,7 @@ func walkDir(root string) (*[]DirectoryEntry, error) {
IsVideo: utils.IsVideo(d),
IsDirectory: d.IsDir(),
ModTime: info.ModTime(),
})
}
}
return &files, err
@@ -142,18 +150,18 @@ func SendFile(w http.ResponseWriter, r *http.Request) {
return
}
decodedStr := string(decoded)
filename := string(decoded)
root := config.Instance().DownloadPath
// TODO: further path / file validations
if strings.Contains(filepath.Dir(decodedStr), root) {
if strings.Contains(filepath.Dir(filename), root) {
w.Header().Add(
"Content-Disposition",
"inline; filename="+filepath.Base(decodedStr),
"inline; filename="+filepath.Base(filename),
)
http.ServeFile(w, r, decodedStr)
http.ServeFile(w, r, filename)
}
w.WriteHeader(http.StatusUnauthorized)