Simplify I18N api
This commit is contained in:
parent
7c6f4bfdeb
commit
cd69e6e3ab
@ -9,7 +9,7 @@ import {
|
||||
absolutePathForCamera,
|
||||
absolutePathForCameraImage,
|
||||
} from '@/app/paths';
|
||||
import { I18NState } from '@/i18n/state';
|
||||
import { AppTextState } from '@/i18n/state';
|
||||
|
||||
// Meta functions moved to separate file to avoid
|
||||
// dependencies (camelcase-keys) found in photo/index.ts
|
||||
@ -18,7 +18,7 @@ import { I18NState } from '@/i18n/state';
|
||||
export const titleForCamera = (
|
||||
camera: Camera,
|
||||
photos: Photo[],
|
||||
appText: I18NState,
|
||||
appText: AppTextState,
|
||||
explicitCount?: number,
|
||||
) => [
|
||||
appText.category.cameraTitle(
|
||||
@ -30,7 +30,7 @@ export const titleForCamera = (
|
||||
export const shareTextForCamera = (
|
||||
camera: Camera,
|
||||
photos: Photo[],
|
||||
appText: I18NState,
|
||||
appText: AppTextState,
|
||||
) =>
|
||||
appText.category.cameraShare(
|
||||
formatCameraText(cameraFromPhoto(photos[0], camera)),
|
||||
@ -38,7 +38,7 @@ export const shareTextForCamera = (
|
||||
|
||||
export const descriptionForCameraPhotos = (
|
||||
photos: Photo[],
|
||||
appText: I18NState,
|
||||
appText: AppTextState,
|
||||
dateBased?: boolean,
|
||||
explicitCount?: number,
|
||||
explicitDateRange?: PhotoDateRange,
|
||||
@ -55,7 +55,7 @@ export const descriptionForCameraPhotos = (
|
||||
export const generateMetaForCamera = (
|
||||
camera: Camera,
|
||||
photos: Photo[],
|
||||
appText: I18NState,
|
||||
appText: AppTextState,
|
||||
explicitCount?: number,
|
||||
explicitDateRange?: PhotoDateRange,
|
||||
) => ({
|
||||
|
||||
@ -19,7 +19,7 @@ import {
|
||||
} from '@/utility/string';
|
||||
import { AnnotatedTag } from '@/photo/form';
|
||||
import PhotoFilmIcon from './PhotoFilmIcon';
|
||||
import { I18NState } from '@/i18n/state';
|
||||
import { AppTextState } from '@/i18n/state';
|
||||
|
||||
export type FilmWithCount = {
|
||||
film: string
|
||||
@ -59,7 +59,7 @@ export const sortFilmsWithCount = (
|
||||
export const titleForFilm = (
|
||||
film: string,
|
||||
photos: Photo[],
|
||||
appText: I18NState,
|
||||
appText: AppTextState,
|
||||
explicitCount?: number,
|
||||
) => [
|
||||
labelForFilm(film).large,
|
||||
@ -68,13 +68,13 @@ export const titleForFilm = (
|
||||
|
||||
export const shareTextForFilm = (
|
||||
film: string,
|
||||
appText: I18NState,
|
||||
appText: AppTextState,
|
||||
) =>
|
||||
appText.category.filmShare(labelForFilm(film).large);
|
||||
|
||||
export const descriptionForFilmPhotos = (
|
||||
photos: Photo[],
|
||||
appText: I18NState,
|
||||
appText: AppTextState,
|
||||
dateBased?: boolean,
|
||||
explicitCount?: number,
|
||||
explicitDateRange?: PhotoDateRange,
|
||||
@ -91,7 +91,7 @@ export const descriptionForFilmPhotos = (
|
||||
export const generateMetaForFilm = (
|
||||
film: string,
|
||||
photos: Photo[],
|
||||
appText: I18NState,
|
||||
appText: AppTextState,
|
||||
explicitCount?: number,
|
||||
explicitDateRange?: PhotoDateRange,
|
||||
) => ({
|
||||
|
||||
@ -8,7 +8,7 @@ import {
|
||||
absolutePathForFocalLength,
|
||||
absolutePathForFocalLengthImage,
|
||||
} from '@/app/paths';
|
||||
import { I18NState } from '@/i18n/state';
|
||||
import { AppTextState } from '@/i18n/state';
|
||||
|
||||
export type FocalLengths = {
|
||||
focal: number
|
||||
@ -30,7 +30,7 @@ export const formatFocalLengthSafe = (focal = 0) =>
|
||||
export const titleForFocalLength = (
|
||||
focal: number,
|
||||
photos: Photo[],
|
||||
appText: I18NState,
|
||||
appText: AppTextState,
|
||||
explicitCount?: number,
|
||||
) => [
|
||||
appText.category.focalLengthTitle(formatFocalLengthSafe(focal)),
|
||||
@ -39,13 +39,13 @@ export const titleForFocalLength = (
|
||||
|
||||
export const shareTextFocalLength = (
|
||||
focal: number,
|
||||
appText: I18NState,
|
||||
appText: AppTextState,
|
||||
) =>
|
||||
appText.category.focalLengthShare(formatFocalLengthSafe(focal));
|
||||
|
||||
export const descriptionForFocalLengthPhotos = (
|
||||
photos: Photo[],
|
||||
appText: I18NState,
|
||||
appText: AppTextState,
|
||||
dateBased?: boolean,
|
||||
explicitCount?: number,
|
||||
explicitDateRange?: PhotoDateRange,
|
||||
@ -62,7 +62,7 @@ export const descriptionForFocalLengthPhotos = (
|
||||
export const generateMetaForFocalLength = (
|
||||
focal: number,
|
||||
photos: Photo[],
|
||||
appText: I18NState,
|
||||
appText: AppTextState,
|
||||
explicitCount?: number,
|
||||
explicitDateRange?: PhotoDateRange,
|
||||
) => ({
|
||||
|
||||
@ -10,8 +10,8 @@ export const LOCALE_TEXT: Record<
|
||||
string,
|
||||
() => Promise<I18NDeepPartial | undefined>
|
||||
> = {
|
||||
'pt-br': () => import('./locales/pt-br').then((m) => m.default),
|
||||
'pt-pt': () => import('./locales/pt-pt').then((m) => m.default),
|
||||
'pt-br': () => import('./locales/pt-br').then(m => m.default),
|
||||
'pt-pt': () => import('./locales/pt-pt').then(m => m.default),
|
||||
};
|
||||
|
||||
export const getTextForLocale = async (
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { I18NDeepPartial } from '..';
|
||||
|
||||
const TEXT: I18NDeepPartial = {
|
||||
locale: 'pt-br',
|
||||
photo: {
|
||||
photo: 'Foto',
|
||||
photoPlural: 'Fotos',
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { I18NDeepPartial } from '..';
|
||||
|
||||
const TEXT: I18NDeepPartial = {
|
||||
locale: 'pt-pt',
|
||||
photo: {
|
||||
photo: 'Fotografia',
|
||||
photoPlural: 'Fotografias',
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
const TEXT = {
|
||||
locale: 'en-us',
|
||||
photo: {
|
||||
photo: 'Photo',
|
||||
photoPlural: 'Photos',
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
import { ReactNode } from 'react';
|
||||
import { AppTextContext } from './client';
|
||||
import { I18N } from '..';
|
||||
import { generateI18NState } from '.';
|
||||
import { generateAppTextState } from '.';
|
||||
|
||||
export default function AppTextProviderClient({
|
||||
children,
|
||||
@ -13,7 +13,7 @@ export default function AppTextProviderClient({
|
||||
value: I18N
|
||||
}) {
|
||||
return (
|
||||
<AppTextContext.Provider value={generateI18NState(value)}>
|
||||
<AppTextContext.Provider value={generateAppTextState(value)}>
|
||||
{children}
|
||||
</AppTextContext.Provider>
|
||||
);
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
'use client';
|
||||
|
||||
import { createContext, use } from 'react';
|
||||
import { generateI18NState } from '.';
|
||||
import { generateAppTextState } from '.';
|
||||
import US_EN from '../locales/us-en';
|
||||
|
||||
export const AppTextContext = createContext(generateI18NState(US_EN));
|
||||
export const AppTextContext = createContext(generateAppTextState(US_EN));
|
||||
|
||||
export const useAppText = () => use(AppTextContext);
|
||||
|
||||
@ -1,45 +1,45 @@
|
||||
import { I18N } from '..';
|
||||
|
||||
export type I18NState = ReturnType<typeof generateI18NState>;
|
||||
export type AppTextState = ReturnType<typeof generateAppTextState>;
|
||||
|
||||
export const generateI18NState = (i18nText: I18N) => {
|
||||
export const generateAppTextState = (i18n: I18N) => {
|
||||
return {
|
||||
...i18nText,
|
||||
...i18n,
|
||||
category: {
|
||||
...i18nText.category,
|
||||
...i18n.category,
|
||||
cameraTitle: (camera: string) =>
|
||||
i18nText.category.cameraTitle.replace('{{camera}}', camera),
|
||||
i18n.category.cameraTitle.replace('{{camera}}', camera),
|
||||
cameraShare: (camera: string) =>
|
||||
i18nText.category.cameraShare.replace('{{camera}}', camera),
|
||||
i18n.category.cameraShare.replace('{{camera}}', camera),
|
||||
taggedPhrase: (tag: string) =>
|
||||
i18nText.category.taggedPhrase.replace('{{tag}}', tag),
|
||||
i18n.category.taggedPhrase.replace('{{tag}}', tag),
|
||||
recipeShare: (recipe: string) =>
|
||||
i18nText.category.recipeShare.replace('{{recipe}}', recipe),
|
||||
i18n.category.recipeShare.replace('{{recipe}}', recipe),
|
||||
filmShare: (film: string) =>
|
||||
i18nText.category.filmShare.replace('{{film}}', film),
|
||||
i18n.category.filmShare.replace('{{film}}', film),
|
||||
focalLengthTitle: (focal: string) =>
|
||||
i18nText.category.focalLengthTitle.replace('{{focal}}', focal),
|
||||
i18n.category.focalLengthTitle.replace('{{focal}}', focal),
|
||||
focalLengthShare: (focal: string) =>
|
||||
i18nText.category.focalLengthShare.replace('{{focal}}', focal),
|
||||
i18n.category.focalLengthShare.replace('{{focal}}', focal),
|
||||
},
|
||||
admin: {
|
||||
...i18nText.admin,
|
||||
...i18n.admin,
|
||||
deleteConfirm: (photoTitle: string) =>
|
||||
i18nText.admin.deleteConfirm.replace('{{photoTitle}}', photoTitle),
|
||||
i18n.admin.deleteConfirm.replace('{{photoTitle}}', photoTitle),
|
||||
},
|
||||
misc: {
|
||||
...i18nText.misc,
|
||||
...i18n.misc,
|
||||
copyPhrase: (label: string) =>
|
||||
i18nText.misc.copyPhrase.replace('{{label}}', label),
|
||||
i18n.misc.copyPhrase.replace('{{label}}', label),
|
||||
},
|
||||
utility: {
|
||||
...i18nText.utility,
|
||||
...i18n.utility,
|
||||
paginate: (index: number, count: number) =>
|
||||
i18nText.utility.paginate
|
||||
i18n.utility.paginate
|
||||
.replace('{{index}}', index.toString())
|
||||
.replace('{{count}}', count.toString()),
|
||||
paginateAction: (index: number, count: number, action: string) =>
|
||||
i18nText.utility.paginateAction
|
||||
i18n.utility.paginateAction
|
||||
.replace('{{index}}', index.toString())
|
||||
.replace('{{count}}', count.toString())
|
||||
.replace('{{action}}', action),
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { APP_LOCALE } from '@/app/config';
|
||||
import { getTextForLocale } from '..';
|
||||
import { generateI18NState } from '.';
|
||||
import { generateAppTextState } from '.';
|
||||
|
||||
export const getAppText = async () =>
|
||||
getTextForLocale(APP_LOCALE).then(generateI18NState);
|
||||
export const getAppText = () =>
|
||||
getTextForLocale(APP_LOCALE).then(generateAppTextState);
|
||||
|
||||
@ -9,7 +9,7 @@ import {
|
||||
absolutePathForLens,
|
||||
absolutePathForLensImage,
|
||||
} from '@/app/paths';
|
||||
import { I18NState } from '@/i18n/state';
|
||||
import { AppTextState } from '@/i18n/state';
|
||||
|
||||
// Meta functions moved to separate file to avoid
|
||||
// dependencies (camelcase-keys) found in photo/index.ts
|
||||
@ -18,7 +18,7 @@ import { I18NState } from '@/i18n/state';
|
||||
export const titleForLens = (
|
||||
lens: Lens,
|
||||
photos: Photo[],
|
||||
appText: I18NState,
|
||||
appText: AppTextState,
|
||||
explicitCount?: number,
|
||||
) => [
|
||||
`${appText.category.lens}:`,
|
||||
@ -29,7 +29,7 @@ export const titleForLens = (
|
||||
export const shareTextForLens = (
|
||||
lens: Lens,
|
||||
photos: Photo[],
|
||||
appText: I18NState,
|
||||
appText: AppTextState,
|
||||
) =>
|
||||
[
|
||||
`${appText.category.lens}:`,
|
||||
@ -38,7 +38,7 @@ export const shareTextForLens = (
|
||||
|
||||
export const descriptionForLensPhotos = (
|
||||
photos: Photo[],
|
||||
appText: I18NState,
|
||||
appText: AppTextState,
|
||||
dateBased?: boolean,
|
||||
explicitCount?: number,
|
||||
explicitDateRange?: PhotoDateRange,
|
||||
@ -55,7 +55,7 @@ export const descriptionForLensPhotos = (
|
||||
export const generateMetaForLens = (
|
||||
lens: Lens,
|
||||
photos: Photo[],
|
||||
appText: I18NState,
|
||||
appText: AppTextState,
|
||||
explicitCount?: number,
|
||||
explicitDateRange?: PhotoDateRange,
|
||||
) => ({
|
||||
|
||||
@ -24,7 +24,7 @@ import type { Metadata } from 'next';
|
||||
import { FujifilmRecipe } from '@/platforms/fujifilm/recipe';
|
||||
import { FujifilmSimulation } from '@/platforms/fujifilm/simulation';
|
||||
import { PhotoSyncStatus, generatePhotoSyncStatus } from './sync';
|
||||
import { I18NState } from '@/i18n/state';
|
||||
import { AppTextState } from '@/i18n/state';
|
||||
|
||||
// INFINITE SCROLL: FEED
|
||||
export const INFINITE_SCROLL_FEED_INITIAL =
|
||||
@ -234,7 +234,7 @@ export const altTextForPhoto = (photo: Photo) =>
|
||||
|
||||
export const photoLabelForCount = (
|
||||
count: number,
|
||||
appText: I18NState,
|
||||
appText: AppTextState,
|
||||
_capitalize = true,
|
||||
) => {
|
||||
const label = count === 1
|
||||
@ -247,7 +247,7 @@ export const photoLabelForCount = (
|
||||
|
||||
export const photoQuantityText = (
|
||||
count: number,
|
||||
appText: I18NState,
|
||||
appText: AppTextState,
|
||||
includeParentheses = true,
|
||||
capitalize?: boolean,
|
||||
) =>
|
||||
@ -257,7 +257,7 @@ export const photoQuantityText = (
|
||||
|
||||
export const deleteConfirmationTextForPhoto = (
|
||||
photo: Photo,
|
||||
appText: I18NState,
|
||||
appText: AppTextState,
|
||||
) =>
|
||||
appText.admin.deleteConfirm(titleForPhoto(photo));
|
||||
|
||||
@ -265,7 +265,7 @@ export type PhotoDateRange = { start: string, end: string };
|
||||
|
||||
export const descriptionForPhotoSet = (
|
||||
photos:Photo[] = [],
|
||||
appText: I18NState,
|
||||
appText: AppTextState,
|
||||
descriptor?: string,
|
||||
dateBased?: boolean,
|
||||
explicitCount?: number,
|
||||
|
||||
@ -8,7 +8,7 @@ import {
|
||||
} from '@/utility/string';
|
||||
import { FujifilmRecipe } from '@/platforms/fujifilm/recipe';
|
||||
import { labelForFilm } from '@/film';
|
||||
import { I18NState } from '@/i18n/state';
|
||||
import { AppTextState } from '@/i18n/state';
|
||||
|
||||
export type RecipeWithCount = {
|
||||
recipe: string
|
||||
@ -31,7 +31,7 @@ export const formatRecipe = (recipe?: string) =>
|
||||
export const titleForRecipe = (
|
||||
recipe: string,
|
||||
photos:Photo[] = [],
|
||||
appText: I18NState,
|
||||
appText: AppTextState,
|
||||
explicitCount?: number,
|
||||
) => [
|
||||
`${appText.category.recipe}: ${formatRecipe(recipe)}`,
|
||||
@ -40,13 +40,13 @@ export const titleForRecipe = (
|
||||
|
||||
export const shareTextForRecipe = (
|
||||
recipe: string,
|
||||
appText: I18NState,
|
||||
appText: AppTextState,
|
||||
) =>
|
||||
appText.category.recipeShare(formatRecipe(recipe));
|
||||
|
||||
export const descriptionForRecipePhotos = (
|
||||
photos: Photo[] = [],
|
||||
appText: I18NState,
|
||||
appText: AppTextState,
|
||||
dateBased?: boolean,
|
||||
explicitCount?: number,
|
||||
explicitDateRange?: PhotoDateRange,
|
||||
@ -145,7 +145,7 @@ export const generateRecipeText = (
|
||||
export const generateMetaForRecipe = (
|
||||
recipe: string,
|
||||
photos: Photo[],
|
||||
appText: I18NState,
|
||||
appText: AppTextState,
|
||||
explicitCount?: number,
|
||||
explicitDateRange?: PhotoDateRange,
|
||||
) => ({
|
||||
|
||||
@ -16,7 +16,7 @@ import {
|
||||
formatCountDescriptive,
|
||||
} from '@/utility/string';
|
||||
import { sortCategoryByCount } from '@/category';
|
||||
import { I18NState } from '@/i18n/state';
|
||||
import { AppTextState } from '@/i18n/state';
|
||||
|
||||
// Reserved tags
|
||||
export const TAG_FAVS = 'favs';
|
||||
@ -42,7 +42,7 @@ export const getValidationMessageForTags = (tags?: string) => {
|
||||
export const titleForTag = (
|
||||
tag: string,
|
||||
photos:Photo[] = [],
|
||||
appText: I18NState,
|
||||
appText: AppTextState,
|
||||
explicitCount?: number,
|
||||
) => [
|
||||
formatTag(tag),
|
||||
@ -51,7 +51,7 @@ export const titleForTag = (
|
||||
|
||||
export const shareTextForTag = (
|
||||
tag: string,
|
||||
appText: I18NState,
|
||||
appText: AppTextState,
|
||||
) =>
|
||||
isTagFavs(tag)
|
||||
? appText.category.taggedFavs
|
||||
@ -96,7 +96,7 @@ export const sortTagsObjectWithoutFavs = (tags: Tags) =>
|
||||
|
||||
export const descriptionForTaggedPhotos = (
|
||||
photos: Photo[] = [],
|
||||
appText: I18NState,
|
||||
appText: AppTextState,
|
||||
dateBased?: boolean,
|
||||
explicitCount?: number,
|
||||
explicitDateRange?: PhotoDateRange,
|
||||
@ -113,7 +113,7 @@ export const descriptionForTaggedPhotos = (
|
||||
export const generateMetaForTag = (
|
||||
tag: string,
|
||||
photos: Photo[],
|
||||
appText: I18NState,
|
||||
appText: AppTextState,
|
||||
explicitCount?: number,
|
||||
explicitDateRange?: PhotoDateRange,
|
||||
) => ({
|
||||
@ -151,7 +151,7 @@ export const addHiddenToTags = (tags: Tags, photosCountHidden = 0) =>
|
||||
|
||||
export const convertTagsForForm = (
|
||||
tags: Tags = [],
|
||||
appText: I18NState,
|
||||
appText: AppTextState,
|
||||
) =>
|
||||
sortTagsObjectWithoutFavs(tags)
|
||||
.map(({ tag, count }) => ({
|
||||
|
||||
Loading…
Reference in New Issue
Block a user