Add live wallpaper source folders and bundle preferences page icons
Live Wallpaper page gains a "Wallpaper Folders" list (mirroring the static rotation one) plus an "Available Media" list of the videos/GIFs found inside them to pick from, backed by a new live-wallpaper-folders GSettings key and a generalized wallpaperSource.js extension scan. The preferences page-switcher icons (General, Rotation, Live Wallpaper, OLED Protection, About) were showing as broken-image placeholders since they depended on exact symbolic icon names being present in the user's system icon theme. Bundle a small set of custom SVG icons under icons/ and register them via Gtk.IconTheme.add_search_path so they always resolve regardless of the system theme.
This commit is contained in:
@@ -13,6 +13,7 @@ export const SettingsKey = Object.freeze({
|
||||
|
||||
LIVE_WALLPAPER_ENABLED: 'live-wallpaper-enabled',
|
||||
LIVE_WALLPAPER_PATH: 'live-wallpaper-path',
|
||||
LIVE_WALLPAPER_FOLDERS: 'live-wallpaper-folders',
|
||||
LIVE_WALLPAPER_MUTED: 'live-wallpaper-muted',
|
||||
LIVE_WALLPAPER_PLAYBACK_RATE: 'live-wallpaper-playback-rate',
|
||||
LIVE_WALLPAPER_PAUSE_ON_BATTERY: 'live-wallpaper-pause-on-battery',
|
||||
@@ -32,3 +33,7 @@ export const SettingsKey = Object.freeze({
|
||||
export const IMAGE_EXTENSIONS = Object.freeze([
|
||||
'.jpg', '.jpeg', '.png', '.webp', '.bmp', '.tiff', '.tif', '.gif',
|
||||
]);
|
||||
|
||||
export const LIVE_WALLPAPER_EXTENSIONS = Object.freeze([
|
||||
'.gif', '.mp4', '.webm', '.mkv', '.mov', '.avi', '.m4v', '.ogv',
|
||||
]);
|
||||
|
||||
+24
-9
@@ -1,19 +1,19 @@
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
|
||||
import {IMAGE_EXTENSIONS} from './settingsKeys.js';
|
||||
import {IMAGE_EXTENSIONS, LIVE_WALLPAPER_EXTENSIONS} from './settingsKeys.js';
|
||||
|
||||
Gio._promisify(Gio.File.prototype, 'enumerate_children_async', 'enumerate_children_finish');
|
||||
Gio._promisify(Gio.FileEnumerator.prototype, 'next_files_async', 'next_files_finish');
|
||||
Gio._promisify(Gio.FileEnumerator.prototype, 'close_async', 'close_finish');
|
||||
|
||||
function hasImageExtension(name) {
|
||||
function hasExtension(name, extensions) {
|
||||
const lower = name.toLowerCase();
|
||||
return IMAGE_EXTENSIONS.some(ext => lower.endsWith(ext));
|
||||
return extensions.some(ext => lower.endsWith(ext));
|
||||
}
|
||||
|
||||
/** Non-recursively lists image files directly inside a single folder. */
|
||||
export async function listImagesInFolder(folderPath) {
|
||||
/** Non-recursively lists files with one of `extensions` directly inside a single folder. */
|
||||
async function listFilesInFolder(folderPath, extensions) {
|
||||
const results = [];
|
||||
const dir = folderPath.startsWith('file://')
|
||||
? Gio.File.new_for_uri(folderPath)
|
||||
@@ -38,7 +38,7 @@ export async function listImagesInFolder(folderPath) {
|
||||
for (const info of infos) {
|
||||
if (info.get_file_type() !== Gio.FileType.REGULAR)
|
||||
continue;
|
||||
if (!hasImageExtension(info.get_name()))
|
||||
if (!hasExtension(info.get_name(), extensions))
|
||||
continue;
|
||||
results.push(enumerator.get_child(info).get_path());
|
||||
}
|
||||
@@ -53,10 +53,10 @@ export async function listImagesInFolder(folderPath) {
|
||||
return results;
|
||||
}
|
||||
|
||||
/** Merges and de-duplicates images found across several folders. */
|
||||
export async function listImagesInFolders(folderPaths) {
|
||||
/** Merges and de-duplicates files with one of `extensions` found across several folders. */
|
||||
async function listFilesInFolders(folderPaths, extensions) {
|
||||
const lists = await Promise.all(
|
||||
folderPaths.map(folder => listImagesInFolder(folder).catch(() => [])));
|
||||
folderPaths.map(folder => listFilesInFolder(folder, extensions).catch(() => [])));
|
||||
|
||||
const seen = new Set();
|
||||
const merged = [];
|
||||
@@ -72,3 +72,18 @@ export async function listImagesInFolders(folderPaths) {
|
||||
merged.sort();
|
||||
return merged;
|
||||
}
|
||||
|
||||
/** Non-recursively lists image files directly inside a single folder. */
|
||||
export async function listImagesInFolder(folderPath) {
|
||||
return listFilesInFolder(folderPath, IMAGE_EXTENSIONS);
|
||||
}
|
||||
|
||||
/** Merges and de-duplicates images found across several folders. */
|
||||
export async function listImagesInFolders(folderPaths) {
|
||||
return listFilesInFolders(folderPaths, IMAGE_EXTENSIONS);
|
||||
}
|
||||
|
||||
/** Merges and de-duplicates live-wallpaper-capable videos/GIFs found across several folders. */
|
||||
export async function listMediaFilesInFolders(folderPaths) {
|
||||
return listFilesInFolders(folderPaths, LIVE_WALLPAPER_EXTENSIONS);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user