mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-20 15:36:18 +00:00
🆙 News windows in UI login update
This commit is contained in:
@@ -4,3 +4,8 @@ export function GetConfigurationValue<T = string>(key: string, value: T = null):
|
|||||||
{
|
{
|
||||||
return GetConfiguration().getValue(key, value);
|
return GetConfiguration().getValue(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function GetOptionalConfigurationValue<T = string>(key: string, value: T = null): T
|
||||||
|
{
|
||||||
|
return GetConfiguration().definitions.has(key) ? GetConfiguration().getValue(key, value) : value;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { GetConfiguration } from '@nitrots/nitro-renderer';
|
import { GetConfiguration } from '@nitrots/nitro-renderer';
|
||||||
import { FC, FormEvent, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { FC, FormEvent, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { ClearRememberLogin, GetConfigurationValue, GetRememberLogin, StoreRememberLoginFromPayload } from '../../api';
|
import { ClearRememberLogin, GetConfigurationValue, GetOptionalConfigurationValue, GetRememberLogin, StoreRememberLoginFromPayload } from '../../api';
|
||||||
import { configFileUrl } from '../../secure-assets';
|
import { configFileUrl } from '../../secure-assets';
|
||||||
import flagBr from '../../assets/images/flag_icon/flag_icon_br.png';
|
import flagBr from '../../assets/images/flag_icon/flag_icon_br.png';
|
||||||
import flagDe from '../../assets/images/flag_icon/flag_icon_de.png';
|
import flagDe from '../../assets/images/flag_icon/flag_icon_de.png';
|
||||||
@@ -237,7 +237,8 @@ export const LoginView: FC<LoginViewProps> = ({ onAuthenticated, isEntering = fa
|
|||||||
const loginUrl = GetConfigurationValue<string>('login.endpoint', '/api/auth/login');
|
const loginUrl = GetConfigurationValue<string>('login.endpoint', '/api/auth/login');
|
||||||
const registerUrl = GetConfigurationValue<string>('login.register.endpoint', '/api/auth/register');
|
const registerUrl = GetConfigurationValue<string>('login.register.endpoint', '/api/auth/register');
|
||||||
const forgotUrl = GetConfigurationValue<string>('login.forgot.endpoint', '/api/auth/forgot-password');
|
const forgotUrl = GetConfigurationValue<string>('login.forgot.endpoint', '/api/auth/forgot-password');
|
||||||
const newsUrl = interpolate(GetConfigurationValue<string>('login.news.url', ''));
|
const configuredNewsUrl = interpolate(GetOptionalConfigurationValue<string>('login.news.url', ''));
|
||||||
|
const newsUrl = configuredNewsUrl || configFileUrl('news.json');
|
||||||
const turnstileSiteKey = GetConfigurationValue<string>('login.turnstile.sitekey', '');
|
const turnstileSiteKey = GetConfigurationValue<string>('login.turnstile.sitekey', '');
|
||||||
const rawTurnstileEnabled = GetConfigurationValue<unknown>('login.turnstile.enabled', false);
|
const rawTurnstileEnabled = GetConfigurationValue<unknown>('login.turnstile.enabled', false);
|
||||||
const turnstileEnabled = (rawTurnstileEnabled === true
|
const turnstileEnabled = (rawTurnstileEnabled === true
|
||||||
@@ -366,7 +367,7 @@ export const LoginView: FC<LoginViewProps> = ({ onAuthenticated, isEntering = fa
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const healthUrl = GetConfigurationValue<string>('login.health.endpoint', '');
|
const healthUrl = GetConfigurationValue<string>('login.health.endpoint', '');
|
||||||
const healthMethodRaw = GetConfigurationValue<string>('login.health.method', 'GET');
|
const healthMethodRaw = GetOptionalConfigurationValue<string>('login.health.method', 'GET');
|
||||||
const healthMethod = (healthMethodRaw || 'GET').toUpperCase();
|
const healthMethod = (healthMethodRaw || 'GET').toUpperCase();
|
||||||
const checkServerReachable = useCallback(async (): Promise<boolean> =>
|
const checkServerReachable = useCallback(async (): Promise<boolean> =>
|
||||||
{
|
{
|
||||||
@@ -480,7 +481,7 @@ export const LoginView: FC<LoginViewProps> = ({ onAuthenticated, isEntering = fa
|
|||||||
|
|
||||||
const checkEmailUrl = GetConfigurationValue<string>('login.check-email.endpoint', '/api/auth/check-email');
|
const checkEmailUrl = GetConfigurationValue<string>('login.check-email.endpoint', '/api/auth/check-email');
|
||||||
const checkUsernameUrl = GetConfigurationValue<string>('login.check-username.endpoint', '/api/auth/check-username');
|
const checkUsernameUrl = GetConfigurationValue<string>('login.check-username.endpoint', '/api/auth/check-username');
|
||||||
const imagingUrl = GetConfigurationValue<string>('login.register.imaging.url', '');
|
const imagingUrl = GetOptionalConfigurationValue<string>('login.register.imaging.url', '');
|
||||||
const interpretAvailability = (ok: boolean, status: number, payload: Record<string, unknown>): { available: boolean; error?: string } =>
|
const interpretAvailability = (ok: boolean, status: number, payload: Record<string, unknown>): { available: boolean; error?: string } =>
|
||||||
{
|
{
|
||||||
const isTrue = (v: unknown) => v === true || v === 'true' || v === 1 || v === '1';
|
const isTrue = (v: unknown) => v === true || v === 'true' || v === 1 || v === '1';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { FC, useEffect, useState } from 'react';
|
import { FC, useEffect, useState } from 'react';
|
||||||
import { t } from '../utils/i18n';
|
import { interpolate, t } from '../utils/i18n';
|
||||||
import { resolveNewsImage, resolveNewsLink } from '../utils/news';
|
import { resolveNewsImage, resolveNewsLink } from '../utils/news';
|
||||||
|
|
||||||
interface NewsItem
|
interface NewsItem
|
||||||
@@ -12,6 +12,26 @@ interface NewsItem
|
|||||||
linkUrl: string;
|
linkUrl: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface RawNewsItem
|
||||||
|
{
|
||||||
|
id?: number;
|
||||||
|
title?: string;
|
||||||
|
body?: string;
|
||||||
|
image?: string | null;
|
||||||
|
link?: string;
|
||||||
|
linkUrl?: string;
|
||||||
|
linkText?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const normalizeNewsItem = (raw: RawNewsItem, fallbackId: number): NewsItem => ({
|
||||||
|
id: typeof raw.id === 'number' ? raw.id : fallbackId,
|
||||||
|
title: typeof raw.title === 'string' ? raw.title : '',
|
||||||
|
body: typeof raw.body === 'string' ? raw.body : '',
|
||||||
|
image: typeof raw.image === 'string' && raw.image.length ? interpolate(raw.image) : null,
|
||||||
|
linkText: typeof raw.linkText === 'string' ? raw.linkText : '',
|
||||||
|
linkUrl: interpolate((typeof raw.linkUrl === 'string' && raw.linkUrl) || (typeof raw.link === 'string' ? raw.link : ''))
|
||||||
|
});
|
||||||
|
|
||||||
interface NewsWindowProps { newsUrl: string; }
|
interface NewsWindowProps { newsUrl: string; }
|
||||||
|
|
||||||
const NEWS_AUTO_ADVANCE_MS = 10000;
|
const NEWS_AUTO_ADVANCE_MS = 10000;
|
||||||
@@ -36,10 +56,10 @@ export const NewsWindow: FC<NewsWindowProps> = ({ newsUrl }) =>
|
|||||||
.then((json: unknown) =>
|
.then((json: unknown) =>
|
||||||
{
|
{
|
||||||
if(cancelled) return;
|
if(cancelled) return;
|
||||||
const list = Array.isArray((json as { news?: unknown })?.news)
|
const rawList = Array.isArray((json as { news?: unknown })?.news)
|
||||||
? (json as { news: NewsItem[] }).news
|
? (json as { news: RawNewsItem[] }).news
|
||||||
: [];
|
: Array.isArray(json) ? (json as RawNewsItem[]) : [];
|
||||||
setItems(list);
|
setItems(rawList.map((raw, idx) => normalizeNewsItem(raw, idx + 1)));
|
||||||
})
|
})
|
||||||
.catch(() => { if(!cancelled) setFailed(true); });
|
.catch(() => { if(!cancelled) setFailed(true); });
|
||||||
return () => { cancelled = true; };
|
return () => { cancelled = true; };
|
||||||
|
|||||||
Reference in New Issue
Block a user