Fix translations + fix build reload + more Typescript
This commit is contained in:
parent
34a411be9d
commit
f09ba14a0e
|
@ -21,6 +21,7 @@ node_modules/
|
|||
.cache/
|
||||
dist/
|
||||
build/
|
||||
*.tsbuildinfo
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
|
|
|
@ -16,7 +16,6 @@ module.exports = function (api) {
|
|||
'i18next-extract',
|
||||
{
|
||||
locales: ['en', 'da'],
|
||||
discardOldKeys: true,
|
||||
defaultValue: null,
|
||||
},
|
||||
])
|
||||
|
|
|
@ -69,7 +69,9 @@ if (watchMode) {
|
|||
bs.watch('src/**/*.@(js|tsx|ts)').on('change', async args => {
|
||||
console.log('reloading', args)
|
||||
builderPromise = (await builderPromise).rebuild()
|
||||
setTimeout(() => {
|
||||
bs.reload(args)
|
||||
}, 1000)
|
||||
})
|
||||
} else {
|
||||
const build = async () => {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"album_filter": {
|
||||
"only_favorites": null,
|
||||
"sort_by": null,
|
||||
"only_favorites": "Vis kun favoritter",
|
||||
"sort_by": "Sorter efter",
|
||||
"sorting_options": {
|
||||
"date_imported": null,
|
||||
"date_shot": null,
|
||||
"title": null,
|
||||
"type": null
|
||||
"date_imported": "Dato for importering",
|
||||
"date_shot": "Dato",
|
||||
"title": "Titel",
|
||||
"type": "Type"
|
||||
}
|
||||
},
|
||||
"albums_page": {
|
||||
|
@ -14,33 +14,33 @@
|
|||
},
|
||||
"general": {
|
||||
"action": {
|
||||
"add": null,
|
||||
"cancel": null,
|
||||
"delete": null,
|
||||
"remove": null,
|
||||
"save": null
|
||||
"add": "Tilføj",
|
||||
"cancel": "Annuller",
|
||||
"delete": "Slet",
|
||||
"remove": "Fjern",
|
||||
"save": "Gem"
|
||||
},
|
||||
"loading": {
|
||||
"album": null,
|
||||
"album": "Loader album",
|
||||
"default": "Loader...",
|
||||
"media": null,
|
||||
"media": "Loader medier",
|
||||
"page": "Loader side",
|
||||
"paginate": {
|
||||
"faces": "Loader flere personer",
|
||||
"media": "Loader flere medier"
|
||||
},
|
||||
"shares": null,
|
||||
"shares": "Loader delinger...",
|
||||
"timeline": "Loader tidslinje"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"search": {
|
||||
"loading": null,
|
||||
"no_results": null,
|
||||
"placeholder": null,
|
||||
"loading": "Loader resultater...",
|
||||
"no_results": "Fandt ingen resultater",
|
||||
"placeholder": "Søg",
|
||||
"result_type": {
|
||||
"albums": null,
|
||||
"photos": null
|
||||
"albums": "Albums",
|
||||
"photos": "Billeder"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -62,6 +62,9 @@
|
|||
},
|
||||
"welcome": "Velkommen til Photoview"
|
||||
},
|
||||
"meta": {
|
||||
"description": null
|
||||
},
|
||||
"people_page": {
|
||||
"face_group": {
|
||||
"label_placeholder": "Navn",
|
||||
|
@ -74,24 +77,24 @@
|
|||
},
|
||||
"settings": {
|
||||
"concurrent_workers": {
|
||||
"description": null,
|
||||
"title": null
|
||||
"description": "Det maksimale antal medier som må skannes samtidig",
|
||||
"title": "Samtidige scanner-arbejdere"
|
||||
},
|
||||
"logout": null,
|
||||
"periodic_scanner": {
|
||||
"checkbox_label": null,
|
||||
"checkbox_label": "Aktiver periodiske scanner",
|
||||
"field": {
|
||||
"description": null,
|
||||
"label": null
|
||||
"description": "Hvor ofte scanneren bør udføre automatiske scanninger af alle brugere",
|
||||
"label": "Periodiske scanningsintervaller"
|
||||
},
|
||||
"interval_unit": {
|
||||
"days": null,
|
||||
"hour": null,
|
||||
"minutes": null,
|
||||
"months": null,
|
||||
"seconds": null
|
||||
"days": "Dage",
|
||||
"hour": "Timer",
|
||||
"minutes": "Minutter",
|
||||
"months": "Måneder",
|
||||
"seconds": "Sekunder"
|
||||
},
|
||||
"title": null
|
||||
"title": "Periodisk scanner"
|
||||
},
|
||||
"scanner": {
|
||||
"description": "Vil scanne alle brugere for nye eller opdaterede medier",
|
||||
|
@ -106,21 +109,21 @@
|
|||
},
|
||||
"users": {
|
||||
"add_user": {
|
||||
"submit": null
|
||||
"submit": "Tilføj bruger"
|
||||
},
|
||||
"confirm_delete_user": {
|
||||
"action": null,
|
||||
"description": null,
|
||||
"title": null
|
||||
"action": "Slet {user}",
|
||||
"description": "<0>Er du sikker på at du vil slette <1></1>?</0><p>Denne handling kan ikke fortrydes</p>",
|
||||
"title": "Slet bruger"
|
||||
},
|
||||
"password_reset": {
|
||||
"description": null,
|
||||
"description": "Ændre adgangskode for <1></1>",
|
||||
"form": {
|
||||
"label": null,
|
||||
"placeholder": null,
|
||||
"submit": null
|
||||
"label": "Ny adgangskode",
|
||||
"placeholder": "adgangskode",
|
||||
"submit": "Ændre adgangskode"
|
||||
},
|
||||
"title": null
|
||||
"title": "Ændre adgangskode"
|
||||
},
|
||||
"table": {
|
||||
"column_names": {
|
||||
|
@ -132,10 +135,10 @@
|
|||
"new_user": "Ny bruger",
|
||||
"row": {
|
||||
"action": {
|
||||
"change_password": null,
|
||||
"delete": null,
|
||||
"edit": null,
|
||||
"scan": null
|
||||
"change_password": "Ændre adgangskode",
|
||||
"delete": "Slet",
|
||||
"edit": "Rediger",
|
||||
"scan": "Scan"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -143,6 +146,9 @@
|
|||
}
|
||||
},
|
||||
"share_page": {
|
||||
"media": {
|
||||
"title": null
|
||||
},
|
||||
"protected_share": {
|
||||
"description": "Denne deling er låst med en adgangskode.",
|
||||
"title": "Beskyttet deling"
|
||||
|
@ -153,72 +159,72 @@
|
|||
},
|
||||
"sidebar": {
|
||||
"album": {
|
||||
"title": null
|
||||
"title": "Album indstillinger"
|
||||
},
|
||||
"download": {
|
||||
"filesize": {
|
||||
"byte": null,
|
||||
"byte_plural": null,
|
||||
"giga_byte": null,
|
||||
"kilo_byte": null,
|
||||
"mega_byte": null,
|
||||
"tera_byte": null
|
||||
"byte": "{{count}} Byte",
|
||||
"byte_plural": "{{count}} Bytes",
|
||||
"giga_byte": "{{count}} GB",
|
||||
"kilo_byte": "{{count}} KB",
|
||||
"mega_byte": "{{count}} MB",
|
||||
"tera_byte": "{{count}} TB"
|
||||
},
|
||||
"table_columns": {
|
||||
"dimensions": null,
|
||||
"file_size": null,
|
||||
"file_type": null,
|
||||
"name": null
|
||||
"dimensions": "Dimension",
|
||||
"file_size": "Størrelse",
|
||||
"file_type": "Type",
|
||||
"name": "Navn"
|
||||
},
|
||||
"title": null
|
||||
"title": "Download"
|
||||
},
|
||||
"media": {
|
||||
"exif": {
|
||||
"exposure_program": {
|
||||
"action_program": null,
|
||||
"aperture_priority": null,
|
||||
"bulb": null,
|
||||
"creative_program": null,
|
||||
"landscape_mode": null,
|
||||
"manual": null,
|
||||
"normal_program": null,
|
||||
"not_defined": null,
|
||||
"portrait_mode": null,
|
||||
"shutter_priority": null
|
||||
"action_program": "Actionprogram",
|
||||
"aperture_priority": "Blændeprioritet",
|
||||
"bulb": "Bulb",
|
||||
"creative_program": "Kreativ program",
|
||||
"landscape_mode": "Landskabsmode",
|
||||
"manual": "Manuel",
|
||||
"normal_program": "Normal program",
|
||||
"not_defined": "Ikke defineret",
|
||||
"portrait_mode": "Portræt mode",
|
||||
"shutter_priority": "Lukkerprioritet"
|
||||
},
|
||||
"flash": {
|
||||
"auto": null,
|
||||
"did_not_fire": null,
|
||||
"fired": null,
|
||||
"no_flash": null,
|
||||
"no_flash_function": null,
|
||||
"off": null,
|
||||
"on": null,
|
||||
"red_eye_reduction": null,
|
||||
"return_detected": null,
|
||||
"return_not_detected": null
|
||||
"auto": "Auto",
|
||||
"did_not_fire": "Blitz affyrede ikke",
|
||||
"fired": "Affyrede",
|
||||
"no_flash": "Ingen blitz",
|
||||
"no_flash_function": "Ingen blitz-funktion",
|
||||
"off": "Slukket",
|
||||
"on": "Tændt",
|
||||
"red_eye_reduction": "Røde øjne reduktion",
|
||||
"return_detected": "Retur registreret",
|
||||
"return_not_detected": "Retur ikke registreret"
|
||||
},
|
||||
"name": {
|
||||
"aperture": null,
|
||||
"camera": null,
|
||||
"date_shot": null,
|
||||
"exposure": null,
|
||||
"exposure_program": null,
|
||||
"flash": null,
|
||||
"focal_length": null,
|
||||
"iso": null,
|
||||
"lens": null,
|
||||
"maker": null
|
||||
"aperture": "Blænde",
|
||||
"camera": "Kamera",
|
||||
"date_shot": "Dato",
|
||||
"exposure": "Lukketid",
|
||||
"exposure_program": "Lukketid program",
|
||||
"flash": "Blitz",
|
||||
"focal_length": "Fokallængde",
|
||||
"iso": "ISO",
|
||||
"lens": "Lense",
|
||||
"maker": "Mærke"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sharing": {
|
||||
"add_share": null,
|
||||
"copy_link": null,
|
||||
"no_shares_found": null,
|
||||
"public_link": null,
|
||||
"table_header": null,
|
||||
"title": null
|
||||
"add_share": "Tilføj deling",
|
||||
"copy_link": "Kopier link",
|
||||
"no_shares_found": "Ingen delinger fundet",
|
||||
"public_link": "Offentligt link",
|
||||
"table_header": "Offentlige delinger",
|
||||
"title": "Indstillinger for deling"
|
||||
}
|
||||
},
|
||||
"sidemenu": {
|
||||
|
|
|
@ -62,6 +62,9 @@
|
|||
},
|
||||
"welcome": "Welcome to Photoview"
|
||||
},
|
||||
"meta": {
|
||||
"description": "Simple and User-friendly Photo Gallery for Personal Servers"
|
||||
},
|
||||
"people_page": {
|
||||
"face_group": {
|
||||
"label_placeholder": "Label",
|
||||
|
@ -143,6 +146,9 @@
|
|||
}
|
||||
},
|
||||
"share_page": {
|
||||
"media": {
|
||||
"title": "Shared media"
|
||||
},
|
||||
"protected_share": {
|
||||
"description": "This share is protected with a password.",
|
||||
"title": "Protected share"
|
||||
|
@ -158,7 +164,7 @@
|
|||
"download": {
|
||||
"filesize": {
|
||||
"byte": "{{count}} Byte",
|
||||
"byte_plural": null,
|
||||
"byte_plural": "{{count}} Bytes",
|
||||
"giga_byte": "{{count}} GB",
|
||||
"kilo_byte": "{{count}} KB",
|
||||
"mega_byte": "{{count}} MB",
|
||||
|
|
|
@ -44,6 +44,7 @@ const SITE_TRANSLATION = gql`
|
|||
`
|
||||
|
||||
const loadTranslations = () => {
|
||||
console.log('load translation')
|
||||
const [loadLang, { data }] = useLazyQuery<siteTranslation>(SITE_TRANSLATION)
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -53,13 +54,22 @@ const loadTranslations = () => {
|
|||
}, [authToken()])
|
||||
|
||||
useEffect(() => {
|
||||
console.log('loading translations', data)
|
||||
switch (data?.myUserPreferences.language) {
|
||||
case LanguageTranslation.Danish:
|
||||
import('../extractedTranslations/da/translation.json').then(danish => {
|
||||
console.log('loading danish')
|
||||
i18n.addResourceBundle('da', 'translation', danish)
|
||||
i18n.changeLanguage('da')
|
||||
})
|
||||
break
|
||||
case LanguageTranslation.English:
|
||||
import('../extractedTranslations/en/translation.json').then(english => {
|
||||
console.log('loading english')
|
||||
i18n.addResourceBundle('en', 'translation', english)
|
||||
i18n.changeLanguage('en')
|
||||
})
|
||||
break
|
||||
default:
|
||||
i18n.changeLanguage('en')
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { ReactChild, ReactChildren } from 'react'
|
||||
import React, { ReactChild } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import styled from 'styled-components'
|
||||
import { NavLink } from 'react-router-dom'
|
||||
|
@ -143,7 +143,7 @@ export const SideMenu = () => {
|
|||
}
|
||||
|
||||
type LayoutProps = {
|
||||
children: ReactChild | ReactChildren
|
||||
children: React.ReactNode
|
||||
title: string
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import ScannerSection from './ScannerSection'
|
|||
import UserPreferences from './UserPreferences'
|
||||
import UsersTable from './Users/UsersTable'
|
||||
|
||||
export const SectionTitle = styled.h2`
|
||||
export const SectionTitle = styled.h2<{ nospace: boolean }>`
|
||||
margin-top: ${({ nospace }) => (nospace ? '0' : '1.4em')} !important;
|
||||
padding-bottom: 0.3em;
|
||||
border-bottom: 1px solid #ddd;
|
|
@ -4,12 +4,17 @@ import React from 'react'
|
|||
import { useTranslation } from 'react-i18next'
|
||||
import { Dropdown } from 'semantic-ui-react'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import { LanguageTranslation } from '../../../__generated__/globalTypes'
|
||||
import { SectionTitle } from './SettingsPage'
|
||||
import {
|
||||
changeUserPreferences,
|
||||
changeUserPreferencesVariables,
|
||||
} from './__generated__/changeUserPreferences'
|
||||
import { myUserPreferences } from './__generated__/myUserPreferences'
|
||||
|
||||
const languagePreferences = [
|
||||
{ key: 1, text: 'English', value: 'en' },
|
||||
{ key: 2, text: 'Dansk', value: 'da' },
|
||||
{ key: 1, text: 'English', value: LanguageTranslation.English },
|
||||
{ key: 2, text: 'Dansk', value: LanguageTranslation.Danish },
|
||||
]
|
||||
|
||||
const CHANGE_USER_PREFERENCES = gql`
|
||||
|
@ -37,14 +42,15 @@ const UserPreferencesWrapper = styled.div`
|
|||
const UserPreferences = () => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const { data } = useQuery(MY_USER_PREFERENCES)
|
||||
const { data } = useQuery<myUserPreferences>(MY_USER_PREFERENCES)
|
||||
|
||||
const [changePrefs, { loading: loadingPrefs, error }] = useMutation(
|
||||
CHANGE_USER_PREFERENCES
|
||||
)
|
||||
const [changePrefs, { loading: loadingPrefs, error }] = useMutation<
|
||||
changeUserPreferences,
|
||||
changeUserPreferencesVariables
|
||||
>(CHANGE_USER_PREFERENCES)
|
||||
|
||||
if (error) {
|
||||
return error.message
|
||||
return <div>{error.message}</div>
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -62,12 +68,12 @@ const UserPreferences = () => {
|
|||
onChange={(event, { value: language }) => {
|
||||
changePrefs({
|
||||
variables: {
|
||||
language,
|
||||
language: language as LanguageTranslation,
|
||||
},
|
||||
})
|
||||
}}
|
||||
selection
|
||||
value={data?.myUserPreferences.language}
|
||||
value={data?.myUserPreferences.language || undefined}
|
||||
loading={loadingPrefs}
|
||||
disabled={loadingPrefs}
|
||||
/>
|
|
@ -29,7 +29,7 @@ const UsersTable = () => {
|
|||
const { loading, error, data, refetch } = useQuery(USERS_QUERY)
|
||||
|
||||
if (error) {
|
||||
return `Users table error: ${error.message}`
|
||||
return <div>{`Users table error: ${error.message}`}</div>
|
||||
}
|
||||
|
||||
let userRows = []
|
||||
|
|
|
@ -50,7 +50,7 @@ const ALBUM_PATH_QUERY = gql`
|
|||
`
|
||||
|
||||
type AlbumTitleProps = {
|
||||
album: {
|
||||
album?: {
|
||||
id: string
|
||||
title: string
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import AlbumFilter from '../AlbumFilter'
|
|||
import { albumQuery_album } from '../../Pages/AlbumPage/__generated__/albumQuery'
|
||||
|
||||
type AlbumGalleryProps = {
|
||||
album: albumQuery_album
|
||||
album?: albumQuery_album
|
||||
loading?: boolean
|
||||
customAlbumLink?(albumID: string): string
|
||||
showFilter?: boolean
|
||||
|
@ -64,10 +64,13 @@ const AlbumGallery = React.forwardRef(
|
|||
}
|
||||
|
||||
const nextImage = () => {
|
||||
if (album === undefined) return
|
||||
setActiveImage((imageState.activeImage + 1) % album.media.length)
|
||||
}
|
||||
|
||||
const previousImage = () => {
|
||||
if (album === undefined) return
|
||||
|
||||
if (imageState.activeImage <= 0) {
|
||||
setActiveImage(album.media.length - 1)
|
||||
} else {
|
||||
|
@ -131,7 +134,7 @@ const AlbumGallery = React.forwardRef(
|
|||
}
|
||||
<PhotoGallery
|
||||
loading={loading}
|
||||
media={album && album.media}
|
||||
media={album?.media || []}
|
||||
activeIndex={imageState.activeImage}
|
||||
presenting={imageState.presenting}
|
||||
onSelectImage={index => {
|
||||
|
|
|
@ -4,6 +4,10 @@ import styled from 'styled-components'
|
|||
import { Icon } from 'semantic-ui-react'
|
||||
import { ProtectedImage } from './ProtectedMedia'
|
||||
import { MediaType } from '../../../__generated__/globalTypes'
|
||||
import {
|
||||
markMediaFavorite,
|
||||
markMediaFavoriteVariables,
|
||||
} from './__generated__/markMediaFavorite'
|
||||
|
||||
const markFavoriteMutation = gql`
|
||||
mutation markMediaFavorite($mediaId: ID!, $favorite: Boolean!) {
|
||||
|
@ -130,7 +134,10 @@ export const MediaThumbnail = ({
|
|||
setPresenting,
|
||||
onFavorite,
|
||||
}: MediaThumbnailProps) => {
|
||||
const [markFavorite] = useMutation(markFavoriteMutation)
|
||||
const [markFavorite] = useMutation<
|
||||
markMediaFavorite,
|
||||
markMediaFavoriteVariables
|
||||
>(markFavoriteMutation)
|
||||
|
||||
let heartIcon = null
|
||||
if (media.favorite !== undefined) {
|
||||
|
|
|
@ -3,7 +3,7 @@ import styled from 'styled-components'
|
|||
import { Loader } from 'semantic-ui-react'
|
||||
import { MediaThumbnail, PhotoThumbnail } from './MediaThumbnail'
|
||||
import PresentView from './presentView/PresentView'
|
||||
import { SidebarContext, UpdateSidebarFn } from '../sidebar/Sidebar'
|
||||
import { SidebarContext } from '../sidebar/Sidebar'
|
||||
import MediaSidebar from '../sidebar/MediaSidebar'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { PresentMediaProps_Media } from './presentView/PresentMedia'
|
||||
|
@ -65,17 +65,8 @@ const PhotoGallery = ({
|
|||
const { t } = useTranslation()
|
||||
const { updateSidebar } = useContext(SidebarContext)
|
||||
|
||||
if (
|
||||
media === undefined ||
|
||||
activeIndex === -1 ||
|
||||
media[activeIndex] === undefined
|
||||
) {
|
||||
return null
|
||||
}
|
||||
const activeImage: PhotoGalleryProps_Media | undefined = media[activeIndex]
|
||||
|
||||
const activeImage = media[activeIndex]
|
||||
|
||||
const getPhotoElements = (updateSidebar: UpdateSidebarFn) => {
|
||||
let photoElements = []
|
||||
if (media) {
|
||||
photoElements = media.map((photo, index) => {
|
||||
|
@ -102,16 +93,13 @@ const PhotoGallery = ({
|
|||
}
|
||||
}
|
||||
|
||||
return photoElements
|
||||
}
|
||||
|
||||
return (
|
||||
<ClearWrap>
|
||||
<Gallery>
|
||||
<Loader active={loading}>
|
||||
{t('general.loading.media', 'Loading media')}
|
||||
</Loader>
|
||||
{getPhotoElements(updateSidebar)}
|
||||
{photoElements}
|
||||
<PhotoFiller />
|
||||
</Gallery>
|
||||
{presenting && (
|
||||
|
|
|
@ -26,6 +26,7 @@ export interface ProtectedImageProps
|
|||
src?: string
|
||||
key?: string
|
||||
lazyLoading?: boolean
|
||||
loaded?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -38,6 +39,7 @@ export const ProtectedImage = ({
|
|||
src,
|
||||
key,
|
||||
lazyLoading,
|
||||
loaded,
|
||||
...props
|
||||
}: ProtectedImageProps) => {
|
||||
const lazyLoadProps: { 'data-src'?: string; loading?: 'lazy' | 'eager' } = {}
|
||||
|
@ -55,11 +57,15 @@ export const ProtectedImage = ({
|
|||
? placeholder
|
||||
: getProtectedUrl(src) || placeholder
|
||||
|
||||
const loadedProp =
|
||||
loaded !== undefined ? { loaded: loaded.toString() } : undefined
|
||||
|
||||
return (
|
||||
<img
|
||||
key={key}
|
||||
{...props}
|
||||
{...lazyLoadProps}
|
||||
{...loadedProp}
|
||||
src={imgSrc}
|
||||
crossOrigin="use-credentials"
|
||||
/>
|
||||
|
|
|
@ -6,10 +6,10 @@ import { authToken } from '../../helpers/authentication'
|
|||
import { ADMIN_QUERY } from '../../Layout'
|
||||
|
||||
export const useIsAdmin = (enabled = true) => {
|
||||
const [fetchAdminQuery, { data }] = useLazyQuery(ADMIN_QUERY)
|
||||
const [fetchAdminQuery, { data, called }] = useLazyQuery(ADMIN_QUERY)
|
||||
|
||||
useEffect(() => {
|
||||
if (authToken() && !data && enabled) {
|
||||
if (authToken() && !called && enabled) {
|
||||
fetchAdminQuery()
|
||||
}
|
||||
}, [authToken(), enabled])
|
||||
|
|
Loading…
Reference in New Issue