Added case support

This commit is contained in:
WardPearce
2024-05-18 20:14:42 +12:00
parent 75473c3368
commit 2c0455798e
9 changed files with 85 additions and 14 deletions
@@ -2,7 +2,7 @@
import { onMount } from 'svelte';
import { _ } from 'svelte-i18n';
import type { Playlist } from './Api/model';
import { getBestThumbnail, truncate } from './misc';
import { getBestThumbnail, getLetterCaseClass, truncate } from './misc';
export let playlist: Playlist;
export let disabled: boolean = false;
@@ -66,7 +66,7 @@
<nav class="no-margin">
<div class="max">
<a class:link-disabled={disabled} href={playlistLink}
><div class="bold">{truncate(playlist.title)}</div></a
><div class={`bold ${getLetterCaseClass()}`}>{truncate(playlist.title)}</div></a
>
<div>
<a class:link-disabled={playlist.authorId === null} href={`/channel/${playlist.authorId}`}
+19 -3
View File
@@ -4,7 +4,7 @@
import { iso31661 } from 'iso-3166';
import { _ } from 'svelte-i18n';
import { get } from 'svelte/store';
import { ensureNoTrailingSlash, truncate } from './misc';
import { ensureNoTrailingSlash, titleCases, truncate } from './misc';
import {
authStore,
darkModeStore,
@@ -12,6 +12,7 @@
deArrowInstanceStore,
deArrowThumbnailInstanceStore,
instanceStore,
interfaceForceCase,
interfacePreviewVideoOnHoverStore,
interfaceRegionStore,
interfaceSearchSuggestionsStore,
@@ -44,8 +45,8 @@
let invidiousInstance = get(instanceStore);
let deArrowUrl = get(deArrowInstanceStore);
let deArrowThumbnailUrl = get(deArrowThumbnailInstanceStore);
let region = get(interfaceRegionStore);
let forceCase = get(interfaceForceCase);
const sponsorCategories = [
{ name: $_('layout.sponsors.sponsor'), category: 'sponsor' },
@@ -169,7 +170,7 @@
</nav>
</div>
<div class="field label no-margin suffix border">
<div class="field label suffix border">
<select name="region" bind:value={region} on:change={() => interfaceRegionStore.set(region)}>
{#each iso31661 as region}
<option selected={$interfaceRegionStore === region.alpha2} value={region.alpha2}
@@ -180,6 +181,21 @@
<label for="region">{$_('region')}</label>
<i>arrow_drop_down</i>
</div>
<div class="field label suffix border">
<select
name="case"
bind:value={forceCase}
on:change={() => interfaceForceCase.set(forceCase)}
>
<option selected={$interfaceForceCase === null} value={null}>Default</option>
{#each titleCases as caseType}
<option selected={$interfaceForceCase === caseType} value={caseType}>{caseType}</option>
{/each}
</select>
<label for="case">{$_('letterCase')}</label>
<i>arrow_drop_down</i>
</div>
</div>
<div class="settings">
+12 -3
View File
@@ -5,7 +5,13 @@
import { getDeArrow, getThumbnail, getVideo, getVideoProgress } from './Api';
import type { Notification, PlaylistPageVideo, Video, VideoBase, VideoPlay } from './Api/model';
import ShareVideo from './ShareVideo.svelte';
import { cleanNumber, getBestThumbnail, proxyVideoUrl, videoLength } from './misc';
import {
cleanNumber,
getBestThumbnail,
getLetterCaseClass,
proxyVideoUrl,
videoLength
} from './misc';
import type { PlayerEvents } from './player';
import {
authStore,
@@ -292,11 +298,14 @@
href={watchUrl.toString()}
data-sveltekit-preload-data="off"
style="display: flex; justify-content:flex-start; position: absolute; width: 100%;"
><div class="bold" style="white-space: nowrap; overflow: hidden;text-overflow: ellipsis;">
><div
class={`${getLetterCaseClass()} bold`}
style="white-space: nowrap; overflow: hidden;text-overflow: ellipsis;"
>
{video.title}
</div>
<div class="tooltip bottom small">{video.title}</div>
<div class={`tooltip bottom small ${getLetterCaseClass()}`}>{video.title}</div>
</a>
<div style="margin-top: 1.4em;">
<a href={`/channel/${video.authorId}`}>{video.author}</a
+6
View File
@@ -4,6 +4,7 @@ import {
deArrowEnabledStore,
deArrowInstanceStore,
deArrowThumbnailInstanceStore,
interfaceForceCase,
interfacePreviewVideoOnHoverStore,
interfaceRegionStore,
interfaceSearchSuggestionsStore,
@@ -147,6 +148,11 @@ const persistedStores = [
name: 'region',
store: interfaceRegionStore,
type: 'string'
},
{
name: 'forceCase',
store: interfaceForceCase,
type: 'string'
}
];
@@ -13,6 +13,7 @@
"skipping": "Skipping",
"replies": "replies",
"region": "Region",
"letterCase": "Letter case for titles",
"hideReplies": "Hide replies",
"hideVideo": "Hide video",
"syncParty": {
+14 -2
View File
@@ -4,11 +4,23 @@ import humanNumber from 'human-number';
import type Peer from 'peerjs';
import { get } from 'svelte/store';
import type { Image } from './Api/model';
import { instanceStore } from './store';
import { instanceStore, interfaceForceCase } from './store';
export type titleCase = 'uppercase' | 'lowercase' | 'sentence case' | 'title case' | null;
export type TitleCase = 'uppercase' | 'lowercase' | 'sentence case' | 'title case' | null;
export const titleCases: TitleCase[] = [
'lowercase',
'uppercase',
'title case',
'sentence case'
];
export function getLetterCaseClass(): string {
const casing = get(interfaceForceCase);
if (!casing) return '';
return casing.toLowerCase().replaceAll(' ', '-');
}
export function truncate(value: string, maxLength: number = 50): string {
return value.length > maxLength ? `${value.substring(0, maxLength)}...` : value;
+2 -2
View File
@@ -3,7 +3,7 @@ import type Peer from 'peerjs';
import type { DataConnection } from 'peerjs';
import { persisted } from 'svelte-persisted-store';
import { writable, type Writable } from 'svelte/store';
import type { titleCase } from './misc';
import type { TitleCase } from './misc';
export const instanceStore: Writable<string> = persisted(
"invidiousInstance",
@@ -46,7 +46,7 @@ export const synciousInstanceStore: Writable<string | null | undefined> = persis
export const interfaceRegionStore: Writable<string> = persisted('interfaceRegion', 'US');
export const interfaceSearchSuggestionsStore = persisted('searchSuggestions', true);
export const interfacePreviewVideoOnHoverStore = persisted('previewVideoOnHover', true);
export const interfaceForceCase: Writable<titleCase> = persisted('forceCase', null);
export const interfaceForceCase: Writable<TitleCase> = persisted('forceCase', null);
export const sponsorBlockStore = persisted('sponsorBlock', true);
export const sponsorBlockUrlStore: Writable<string | null | undefined> = persisted(
@@ -14,7 +14,13 @@
import Player from '$lib/Player.svelte';
import ShareVideo from '$lib/ShareVideo.svelte';
import Thumbnail from '$lib/Thumbnail.svelte';
import { cleanNumber, getBestThumbnail, numberWithCommas, unsafeRandomItem } from '$lib/misc';
import {
cleanNumber,
getBestThumbnail,
getLetterCaseClass,
numberWithCommas,
unsafeRandomItem
} from '$lib/misc';
import type { PlayerEvents } from '$lib/player';
import {
activePageStore,
@@ -408,7 +414,7 @@
</div>
{/key}
</div>
<h5>{data.video.title}</h5>
<h5 class={getLetterCaseClass()}>{data.video.title}</h5>
<div class="grid no-padding">
<div class="s12 m12 l5">
+21
View File
@@ -38,6 +38,27 @@ main.root {
overflow-y: scroll;
}
.lowercase {
text-transform: lowercase;
}
.uppercase {
text-transform: uppercase;
}
.title-case {
text-transform: capitalize;
}
.sentence-case {
text-transform: lowercase;
}
.sentence-case::first-letter {
text-transform: uppercase !important;
}
@media screen and (max-width: 650px) {
dialog.right {
width: 100% !important;