mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-10 07:56:46 -05:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7655ee8fae | ||
|
|
1510abf563 | ||
|
|
1218293fe2 |
@@ -1,4 +1,3 @@
|
||||
|
||||
/// When downloading a remote file, it makes sense to try to match the same file extension (with reasonable safeguards).
|
||||
#[deprecated(note = "Use `Extension` in `url_utils::extension::extension` instead")]
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
|
||||
@@ -12,9 +12,7 @@ pub fn extract_download_extension_from_url_str(url: &str) -> Option<DownloadExte
|
||||
#[deprecated(note = "Use `extract_extension_from_url` in `url_utils::extension::extract_extension_from_url` instead")]
|
||||
pub fn extract_download_extension_from_url(url: &Url) -> Option<DownloadExtension> {
|
||||
let path = url.path();
|
||||
let extension = std::path::Path::new(path)
|
||||
.extension()
|
||||
.and_then(|ext| ext.to_str())?;
|
||||
let extension = std::path::Path::new(path).extension().and_then(|ext| ext.to_str())?;
|
||||
DownloadExtension::try_from_str(extension)
|
||||
}
|
||||
|
||||
@@ -26,14 +24,14 @@ mod tests {
|
||||
#[test]
|
||||
fn success_case() {
|
||||
let url = "https://storyteller.ai/example.jpg";
|
||||
let maybe_extension= extract_download_extension_from_url_str(url);
|
||||
let maybe_extension = extract_download_extension_from_url_str(url);
|
||||
assert_eq!(maybe_extension, Some(DownloadExtension::Jpg));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn difficult_url() {
|
||||
let url = "https://videos.youtube.com/foo/bar/files/00000000-f19a-1275-a092-caa60b38f8d2%2Fraw?se=2025-11-21T22%3A26%3A53Z&sp=r&sv=2024-08-09&sr=b&skoid=8cfff87a-01fc-27c1-9091-32999dcd1389&sktid=aa8ccaf6-e6da-484e-ab11-9c7496c21c53&skt=2025-11-17T21%3A09%3A08Z&ske=2025-10-23T21%3A14%3A08Z&sks=b&skv=2024-08-04&sig=T2U6%2Brw9WJdJagBkCL4/GlFr72KhZGP3QPlobIO7JlU%3D&ac=oaisdsorprnorthcentralus";
|
||||
let maybe_extension= extract_download_extension_from_url_str(url);
|
||||
let maybe_extension = extract_download_extension_from_url_str(url);
|
||||
assert!(maybe_extension.is_none());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#[expect(clippy::module_inception, reason = "Preserve the existing public module path")]
|
||||
mod download_extension;
|
||||
pub mod extract_download_extension_from_url;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use std::borrow::Cow;
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
/// A file extension that can be either a compile-time constant or a runtime-parsed value.
|
||||
///
|
||||
@@ -16,7 +17,7 @@ use std::fmt;
|
||||
/// assert_eq!(ext.without_period(), "mp4");
|
||||
/// assert_eq!(ext.with_period(), ".mp4");
|
||||
/// ```
|
||||
#[derive(Clone, Eq, Hash)]
|
||||
#[derive(Clone, Eq)]
|
||||
pub struct Extension {
|
||||
/// The extension without the leading period, e.g. "png", "mp4".
|
||||
value: Cow<'static, str>,
|
||||
@@ -34,20 +35,14 @@ impl Extension {
|
||||
/// const MP4: Extension = Extension::from_static("mp4", ".mp4");
|
||||
/// ```
|
||||
pub const fn from_static(ext: &'static str, dotted: &'static str) -> Self {
|
||||
Self {
|
||||
value: Cow::Borrowed(ext),
|
||||
dotted: Cow::Borrowed(dotted),
|
||||
}
|
||||
Self { value: Cow::Borrowed(ext), dotted: Cow::Borrowed(dotted) }
|
||||
}
|
||||
|
||||
/// Creates an `Extension` from a `&str` at runtime.
|
||||
/// The input must NOT include a leading period.
|
||||
pub fn new(ext: &str) -> Self {
|
||||
let dotted = format!(".{}", ext);
|
||||
Self {
|
||||
value: Cow::Owned(ext.to_string()),
|
||||
dotted: Cow::Owned(dotted),
|
||||
}
|
||||
let dotted = format!(".{ext}");
|
||||
Self { value: Cow::Owned(ext.to_string()), dotted: Cow::Owned(dotted) }
|
||||
}
|
||||
|
||||
/// Returns the extension without the leading period, e.g. `"png"`.
|
||||
@@ -67,6 +62,12 @@ impl PartialEq for Extension {
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for Extension {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.value.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Extension {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "Extension(\"{}\")", self.value)
|
||||
@@ -135,12 +136,28 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn display() {
|
||||
assert_eq!(format!("{}", PNG), "png");
|
||||
assert_eq!(format!("{PNG}"), "png");
|
||||
assert_eq!(format!("{}", Extension::new("xyz")), "xyz");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn debug() {
|
||||
assert_eq!(format!("{:?}", PNG), "Extension(\"png\")");
|
||||
assert_eq!(format!("{PNG:?}"), "Extension(\"png\")");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hash_matches_equality() {
|
||||
let plain = Extension::from_static("png", ".png");
|
||||
let inconsistent = Extension::from_static("png", ".not-a-suffix");
|
||||
assert_eq!(plain, inconsistent);
|
||||
assert_eq!(hash(&plain), hash(&inconsistent));
|
||||
}
|
||||
|
||||
fn hash(extension: &Extension) -> u64 {
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
|
||||
let mut hasher = DefaultHasher::new();
|
||||
extension.hash(&mut hasher);
|
||||
hasher.finish()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,24 +6,13 @@ use url::Url;
|
||||
// TODO: Lookups against these as lists will be slow
|
||||
|
||||
/// Known image extensions.
|
||||
const KNOWN_IMAGE_EXTENSIONS: &[Extension] = &[
|
||||
Extension::from_static("png", ".png"),
|
||||
Extension::from_static("jpg", ".jpg"),
|
||||
Extension::from_static("jpeg", ".jpeg"),
|
||||
Extension::from_static("webp", ".webp"),
|
||||
];
|
||||
const KNOWN_IMAGE_EXTENSIONS: &[Extension] = &[Extension::from_static("png", ".png"), Extension::from_static("jpg", ".jpg"), Extension::from_static("jpeg", ".jpeg"), Extension::from_static("webp", ".webp")];
|
||||
|
||||
/// Known audio extensions.
|
||||
const KNOWN_AUDIO_EXTENSIONS: &[Extension] = &[
|
||||
Extension::from_static("wav", ".wav"),
|
||||
Extension::from_static("mp3", ".mp3"),
|
||||
];
|
||||
const KNOWN_AUDIO_EXTENSIONS: &[Extension] = &[Extension::from_static("wav", ".wav"), Extension::from_static("mp3", ".mp3")];
|
||||
|
||||
/// Known video extensions.
|
||||
const KNOWN_VIDEO_EXTENSIONS: &[Extension] = &[
|
||||
Extension::from_static("mp4", ".mp4"),
|
||||
Extension::from_static("webm", ".webm"),
|
||||
];
|
||||
const KNOWN_VIDEO_EXTENSIONS: &[Extension] = &[Extension::from_static("mp4", ".mp4"), Extension::from_static("webm", ".webm")];
|
||||
|
||||
/// Controls which extensions are accepted when extracting from a URL.
|
||||
pub enum ExtractExtensions {
|
||||
@@ -62,9 +51,7 @@ pub fn extract_extension_from_url_str(url: &str, accept: &ExtractExtensions) ->
|
||||
/// Extracts a file extension from a parsed `Url`, filtered by `accept`.
|
||||
pub fn extract_extension_from_url(url: &Url, accept: &ExtractExtensions) -> Option<Extension> {
|
||||
let path = url.path();
|
||||
let raw_ext = std::path::Path::new(path)
|
||||
.extension()
|
||||
.and_then(|ext| ext.to_str())?;
|
||||
let raw_ext = std::path::Path::new(path).extension().and_then(|ext| ext.to_str())?;
|
||||
|
||||
let lower = raw_ext.to_lowercase();
|
||||
let candidate = Extension::new(&lower);
|
||||
@@ -72,27 +59,40 @@ pub fn extract_extension_from_url(url: &Url, accept: &ExtractExtensions) -> Opti
|
||||
match accept {
|
||||
ExtractExtensions::All => Some(candidate),
|
||||
ExtractExtensions::Set(set) => {
|
||||
if set.contains(&candidate) { Some(candidate) } else { None }
|
||||
}
|
||||
ExtractExtensions::KnownImage => {
|
||||
if slice_contains(KNOWN_IMAGE_EXTENSIONS, &candidate) { Some(candidate) } else { None }
|
||||
}
|
||||
ExtractExtensions::KnownAudio => {
|
||||
if slice_contains(KNOWN_AUDIO_EXTENSIONS, &candidate) { Some(candidate) } else { None }
|
||||
}
|
||||
ExtractExtensions::KnownVideo => {
|
||||
if slice_contains(KNOWN_VIDEO_EXTENSIONS, &candidate) { Some(candidate) } else { None }
|
||||
}
|
||||
ExtractExtensions::KnownMedia => {
|
||||
if slice_contains(KNOWN_IMAGE_EXTENSIONS, &candidate)
|
||||
|| slice_contains(KNOWN_AUDIO_EXTENSIONS, &candidate)
|
||||
|| slice_contains(KNOWN_VIDEO_EXTENSIONS, &candidate)
|
||||
{
|
||||
if set.contains(&candidate) {
|
||||
Some(candidate)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
},
|
||||
ExtractExtensions::KnownImage => {
|
||||
if slice_contains(KNOWN_IMAGE_EXTENSIONS, &candidate) {
|
||||
Some(candidate)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
},
|
||||
ExtractExtensions::KnownAudio => {
|
||||
if slice_contains(KNOWN_AUDIO_EXTENSIONS, &candidate) {
|
||||
Some(candidate)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
},
|
||||
ExtractExtensions::KnownVideo => {
|
||||
if slice_contains(KNOWN_VIDEO_EXTENSIONS, &candidate) {
|
||||
Some(candidate)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
},
|
||||
ExtractExtensions::KnownMedia => {
|
||||
if slice_contains(KNOWN_IMAGE_EXTENSIONS, &candidate) || slice_contains(KNOWN_AUDIO_EXTENSIONS, &candidate) || slice_contains(KNOWN_VIDEO_EXTENSIONS, &candidate) {
|
||||
Some(candidate)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,19 +190,14 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn set_matches_custom_list() {
|
||||
let accept = ExtractExtensions::from_vec(vec![
|
||||
Extension::from_static("csv", ".csv"),
|
||||
Extension::from_static("tsv", ".tsv"),
|
||||
]);
|
||||
let accept = ExtractExtensions::from_vec(vec![Extension::from_static("csv", ".csv"), Extension::from_static("tsv", ".tsv")]);
|
||||
let ext = extract_extension_from_url_str("https://example.com/data.csv", &accept);
|
||||
assert_eq!(ext.unwrap().without_period(), "csv");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_rejects_non_member() {
|
||||
let accept = ExtractExtensions::from_vec(vec![
|
||||
Extension::from_static("csv", ".csv"),
|
||||
]);
|
||||
let accept = ExtractExtensions::from_vec(vec![Extension::from_static("csv", ".csv")]);
|
||||
let ext = extract_extension_from_url_str("https://example.com/data.png", &accept);
|
||||
assert!(ext.is_none());
|
||||
}
|
||||
@@ -215,10 +210,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn query_params_ignored() {
|
||||
let ext = extract_extension_from_url_str(
|
||||
"https://example.com/file.mp4?token=abc&format=hd",
|
||||
&ExtractExtensions::KnownVideo,
|
||||
);
|
||||
let ext = extract_extension_from_url_str("https://example.com/file.mp4?token=abc&format=hd", &ExtractExtensions::KnownVideo);
|
||||
assert_eq!(ext.unwrap().without_period(), "mp4");
|
||||
}
|
||||
|
||||
@@ -230,8 +222,7 @@ mod tests {
|
||||
}
|
||||
|
||||
fn extract_extension_all(url: &str) -> Option<String> {
|
||||
extract_extension_from_url_str(url, &ExtractExtensions::All)
|
||||
.map(|ext| ext.without_period().to_string())
|
||||
extract_extension_from_url_str(url, &ExtractExtensions::All).map(|ext| ext.without_period().to_string())
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
#[expect(clippy::module_inception, reason = "Preserve the existing public module path")]
|
||||
pub mod extension;
|
||||
pub mod extract_extension_from_url;
|
||||
pub mod extract_extension_from_url;
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
pub mod extension;
|
||||
pub mod download_extension;
|
||||
#[expect(deprecated, reason = "Keep the public compatibility module while downstream users migrate to Extension")]
|
||||
pub mod download_extension;
|
||||
|
||||
@@ -948,7 +948,7 @@ export const GalleryModal = React.memo(
|
||||
// couldn't see it — making the library button appear broken.
|
||||
galleryModalDraggingUnder.value = false;
|
||||
let cancelled = false;
|
||||
(async () => {
|
||||
void (async () => {
|
||||
setUsernameError(false);
|
||||
const name = await fetchCurrentUsername();
|
||||
if (cancelled) return;
|
||||
|
||||
@@ -90,7 +90,7 @@ export function useMediaPromptTokens(
|
||||
const key = [...new Set(cleaned)].sort().join(",");
|
||||
|
||||
useEffect(() => {
|
||||
if (key.length > 0) fetchMissing(key.split(","));
|
||||
if (key.length > 0) void fetchMissing(key.split(","));
|
||||
}, [key]);
|
||||
|
||||
const result = new Map<string, string>();
|
||||
|
||||
@@ -63,7 +63,7 @@ export function usePrompts(
|
||||
const key = [...new Set(cleaned)].sort().join(",");
|
||||
|
||||
useEffect(() => {
|
||||
if (key.length > 0) fetchMissing(key.split(","));
|
||||
if (key.length > 0) void fetchMissing(key.split(","));
|
||||
}, [key]);
|
||||
|
||||
const result = new Map<string, Prompts>();
|
||||
|
||||
@@ -42,7 +42,7 @@ const NewsView = ({ onBack }: { onBack: () => void }) => {
|
||||
console.warn("Failed to fetch news feed, using bundled content.", e);
|
||||
}
|
||||
};
|
||||
fetchNews();
|
||||
void fetchNews();
|
||||
}, []);
|
||||
|
||||
const selectedPost = useMemo(
|
||||
@@ -312,7 +312,7 @@ export function HelpMenuButton({
|
||||
});
|
||||
};
|
||||
|
||||
run();
|
||||
void run();
|
||||
|
||||
return () => {
|
||||
if (progressTimerRef.current) {
|
||||
|
||||
@@ -179,7 +179,7 @@ export function LightboxModal({
|
||||
audioPlayerRef.current = null;
|
||||
};
|
||||
audioPlayerRef.current = audio;
|
||||
audio.play();
|
||||
void audio.play();
|
||||
setPlayingAudioToken(token);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -83,7 +83,7 @@ export function TagsSection({
|
||||
useEffect(() => {
|
||||
if (currentUsername !== undefined) return;
|
||||
let cancelled = false;
|
||||
resolveSessionUsername().then((username) => {
|
||||
void resolveSessionUsername().then((username) => {
|
||||
if (!cancelled) setResolvedUsername(username);
|
||||
});
|
||||
return () => {
|
||||
@@ -133,7 +133,7 @@ export function TagsSection({
|
||||
}
|
||||
ownTagsLoadedRef.current = true;
|
||||
let cancelled = false;
|
||||
(async () => {
|
||||
void (async () => {
|
||||
const all: TagDetails[] = [];
|
||||
let cursor: string | undefined = undefined;
|
||||
for (let page = 0; page < 50; page++) {
|
||||
|
||||
@@ -1040,7 +1040,7 @@ const PageDraw = ({
|
||||
await tryFit();
|
||||
};
|
||||
|
||||
autoFitCanvas();
|
||||
void autoFitCanvas();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [baseImageBitmap, baseImageInfo?.isBlankCanvas]);
|
||||
|
||||
|
||||
@@ -1501,7 +1501,7 @@ export const PaintSurface = ({
|
||||
|
||||
// Load the checkboard image for transparency background
|
||||
useEffect(() => {
|
||||
loadImageFromUrl(checkerboard).then(setCheckerImage);
|
||||
void loadImageFromUrl(checkerboard).then(setCheckerImage);
|
||||
}, []);
|
||||
|
||||
// Separate function to render transformers on their own layer
|
||||
|
||||
@@ -1167,7 +1167,7 @@ export const useSceneStore = create<SceneState>((set, get, store) => ({
|
||||
console.error("Failed to restore image:", error);
|
||||
}
|
||||
};
|
||||
loadImage();
|
||||
void loadImage();
|
||||
}
|
||||
|
||||
return node;
|
||||
|
||||
@@ -387,7 +387,7 @@ export const Stage3DBody = ({
|
||||
useEffect(() => {
|
||||
const handler = onImageDrop(
|
||||
(item: GalleryItem, position: { x: number; y: number }) => {
|
||||
(async () => {
|
||||
void (async () => {
|
||||
if (!editor) {
|
||||
console.warn("Cannot drop asset: editor engine not ready");
|
||||
return;
|
||||
|
||||
@@ -14,7 +14,7 @@ export function toggleObjectVisibility(editor: Editor, uuid: string): void {
|
||||
if (!obj) return;
|
||||
const before = obj.visible;
|
||||
editor.bus.emit(new OutlinerItemVisibilityToggledEvent(uuid));
|
||||
editor.sceneManager?.hideObject(uuid);
|
||||
void editor.sceneManager?.hideObject(uuid);
|
||||
editor.history.record(
|
||||
new VisibilityAction(editor, uuid, before, !before),
|
||||
);
|
||||
|
||||
@@ -190,7 +190,7 @@ class Editor {
|
||||
// Ammo.js WASM is a global side-effect script the physics path
|
||||
// depends on. The singleton ensures it's appended to document.body
|
||||
// exactly once, even across Editor re-construction.
|
||||
ensureAmmoLoaded();
|
||||
void ensureAmmoLoaded();
|
||||
|
||||
// Version and name.
|
||||
this.version = 2.0;
|
||||
@@ -667,9 +667,9 @@ class Editor {
|
||||
};
|
||||
|
||||
if (!this.utils.isEmpty(cacheJson)) {
|
||||
this.save_manager.loadCache(cacheJson).then(applyIfLoaded);
|
||||
void this.save_manager.loadCache(cacheJson).then(applyIfLoaded);
|
||||
} else if (!this.utils.isEmpty(sceneToken)) {
|
||||
this.save_manager.loadScene(sceneToken).then(applyIfLoaded);
|
||||
void this.save_manager.loadScene(sceneToken).then(applyIfLoaded);
|
||||
} else {
|
||||
this.adapter.onSceneTitleChange?.({
|
||||
title: "Untitled New Scene",
|
||||
@@ -1065,7 +1065,7 @@ class Editor {
|
||||
}
|
||||
|
||||
this.lastFrameTime = frameTime;
|
||||
this.renderSingleFrame();
|
||||
void this.renderSingleFrame();
|
||||
}
|
||||
|
||||
startRenderLoop() {
|
||||
|
||||
+2
-2
@@ -151,7 +151,7 @@ export class ModalTransformController {
|
||||
}
|
||||
}
|
||||
this.target.position.copy(this.startPos).add(delta);
|
||||
this.editor.renderScene();
|
||||
void this.editor.renderScene();
|
||||
}
|
||||
|
||||
private axisVector(axis: "x" | "y" | "z"): THREE.Vector3 {
|
||||
@@ -190,7 +190,7 @@ export class ModalTransformController {
|
||||
|
||||
private cancel() {
|
||||
if (this.target) this.target.position.copy(this.startPos);
|
||||
this.editor.renderScene();
|
||||
void this.editor.renderScene();
|
||||
this.cleanup();
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ export class LoadingPlaceHolderManager {
|
||||
if (result === undefined) {
|
||||
return;
|
||||
}
|
||||
result.destroyWithScene(this.scene);
|
||||
void result.destroyWithScene(this.scene);
|
||||
this.messages.delete(id);
|
||||
}
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ class Scene {
|
||||
initialize() {
|
||||
this.scene = new THREE.Scene();
|
||||
this.placeholder_manager = new LoadingPlaceHolderManager(this.scene);
|
||||
this.placeholder_manager.initialize();
|
||||
void this.placeholder_manager.initialize();
|
||||
|
||||
this._createGrid();
|
||||
this._create_base_lighting();
|
||||
|
||||
@@ -170,7 +170,7 @@ export function useCurrency(): UseCurrencyResult {
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
fetchRates().then((r) => {
|
||||
void fetchRates().then((r) => {
|
||||
if (!cancelled) {
|
||||
setRates(r);
|
||||
setRatesLoaded(true);
|
||||
|
||||
@@ -102,7 +102,7 @@ const AudioRefTile = ({
|
||||
el.volume = 0.2;
|
||||
audioRef.current = el;
|
||||
el.onended = () => setIsPlaying(false);
|
||||
el.play();
|
||||
void el.play();
|
||||
setIsPlaying(true);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -347,7 +347,7 @@ export const PromptBox2D = ({
|
||||
const isSubmitCombo = enterToGenerate && !e.shiftKey;
|
||||
if (isSubmitCombo) {
|
||||
e.preventDefault();
|
||||
handleGenerate();
|
||||
void handleGenerate();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -543,7 +543,7 @@ export const PromptBox3D = ({
|
||||
const isSubmitCombo = enterToGenerate && !e.shiftKey;
|
||||
if (isSubmitCombo) {
|
||||
e.preventDefault();
|
||||
handleEnqueue();
|
||||
void handleEnqueue();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -352,7 +352,7 @@ export const PromptBoxAudio = ({
|
||||
if (e.key !== "Enter") return;
|
||||
if (enterToGenerate && !e.shiftKey) {
|
||||
e.preventDefault();
|
||||
handleEnqueue();
|
||||
void handleEnqueue();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -461,7 +461,7 @@ export const PromptBoxImage = ({
|
||||
const isSubmitCombo = enterToGenerate && !e.shiftKey;
|
||||
if (isSubmitCombo) {
|
||||
e.preventDefault();
|
||||
handleEnqueue();
|
||||
void handleEnqueue();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1231,7 +1231,7 @@ export const PromptBoxVideo = ({
|
||||
console.error("PromptBoxVideo - enqueue failed", failure.reason);
|
||||
toast.error(commandErrorMessage(failure.reason, "Failed to start video generation. Please try again."));
|
||||
}
|
||||
if (acceptedIds.length) onEnqueuePressed?.(prompt, acceptedIds);
|
||||
if (acceptedIds.length) void onEnqueuePressed?.(prompt, acceptedIds);
|
||||
|
||||
setIsEnqueueing(false);
|
||||
};
|
||||
@@ -1282,7 +1282,7 @@ export const PromptBoxVideo = ({
|
||||
return;
|
||||
}
|
||||
|
||||
handleEnqueue();
|
||||
void handleEnqueue();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1392,7 +1392,7 @@ export const PromptBoxVideo = ({
|
||||
)
|
||||
return;
|
||||
if (!prompt.trim()) return;
|
||||
handleEnqueue();
|
||||
void handleEnqueue();
|
||||
}
|
||||
}}
|
||||
onFocus={() => setIsFocused(true)}
|
||||
|
||||
@@ -68,7 +68,7 @@ export const DeckCard = ({
|
||||
el.volume = 0.2;
|
||||
audioRef.current = el;
|
||||
el.onended = () => setIsPlaying(false);
|
||||
el.play();
|
||||
void el.play();
|
||||
setIsPlaying(true);
|
||||
}
|
||||
}, [isPlaying, item.url, stopAudio]);
|
||||
|
||||
@@ -516,8 +516,8 @@ export function useDeckMedia<
|
||||
);
|
||||
|
||||
if (images.length > 0) processImageFiles(images, "start");
|
||||
if (videos.length > 0 && setReferenceVideos) processVideoFiles(videos);
|
||||
if (audios.length > 0 && setReferenceAudios) processAudioFiles(audios);
|
||||
if (videos.length > 0 && setReferenceVideos) void processVideoFiles(videos);
|
||||
if (audios.length > 0 && setReferenceAudios) void processAudioFiles(audios);
|
||||
};
|
||||
|
||||
// maxImages of 0 means the page's model takes no image refs at all.
|
||||
|
||||
@@ -92,7 +92,7 @@ export function ProviderSetupModal({
|
||||
icon={ArrowRightIcon}
|
||||
iconFlip={true}
|
||||
onClick={() => {
|
||||
buttonOnClick();
|
||||
void buttonOnClick();
|
||||
}}
|
||||
>
|
||||
{modalButtonText}
|
||||
|
||||
@@ -27,7 +27,7 @@ export const AboutSettingsPane = (args: AboutSettingsPaneProps) => {
|
||||
const prefs = await GetAppInfo();
|
||||
setAppInfo(prefs.payload);
|
||||
};
|
||||
fetchData();
|
||||
void fetchData();
|
||||
}, []);
|
||||
|
||||
const handleVersionClick = () => {
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ export const ArtcraftAccountBlock = ({
|
||||
setIsCheckingArtcraftSession(false);
|
||||
}
|
||||
};
|
||||
fetchSession();
|
||||
void fetchSession();
|
||||
}, []);
|
||||
|
||||
const handleArtcraftButton = async () => {
|
||||
|
||||
+2
-2
@@ -24,11 +24,11 @@ export const GrokAccountBlock = () => {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchSession();
|
||||
void fetchSession();
|
||||
}, []);
|
||||
|
||||
useRefreshAccountStateEvent(async (event: RefreshAccountStateEvent) => {
|
||||
fetchSession();
|
||||
void fetchSession();
|
||||
});
|
||||
|
||||
const clearState = async() => {
|
||||
|
||||
+2
-2
@@ -24,11 +24,11 @@ export const MidjourneyAccountBlock = () => {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchSession();
|
||||
void fetchSession();
|
||||
}, []);
|
||||
|
||||
useRefreshAccountStateEvent(async (event: RefreshAccountStateEvent) => {
|
||||
fetchSession();
|
||||
void fetchSession();
|
||||
});
|
||||
|
||||
const clearState = async() => {
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ export const OpenAIApiKeyBlock = () => {
|
||||
setIsCheckingOpenAIApiKey(false);
|
||||
}
|
||||
};
|
||||
fetchKey();
|
||||
void fetchKey();
|
||||
}, []);
|
||||
|
||||
const syncOpenAIApiKey = async (key: string) => {
|
||||
|
||||
@@ -23,7 +23,7 @@ export const AudioSettingsPane = (args: AudioSettingsPaneProps) => {
|
||||
const prefs = await GetAppPreferences();
|
||||
setPreferences(prefs.preferences);
|
||||
};
|
||||
fetchData();
|
||||
void fetchData();
|
||||
}, []);
|
||||
|
||||
const playSounds = preferences?.play_sounds || false;
|
||||
|
||||
@@ -221,7 +221,7 @@ export const DownloadsSettingsPane = () => {
|
||||
if (value === "custom") {
|
||||
setFilenameMode("custom");
|
||||
} else {
|
||||
saveFilenamePreference("artcraft_convention");
|
||||
void saveFilenamePreference("artcraft_convention");
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
+2
-2
@@ -139,7 +139,7 @@ export const ProviderPrioritySettingsPane = () => {
|
||||
|
||||
setItems(items);
|
||||
};
|
||||
fetchData();
|
||||
void fetchData();
|
||||
}, []);
|
||||
|
||||
const sensors = useSensors(
|
||||
@@ -178,7 +178,7 @@ export const ProviderPrioritySettingsPane = () => {
|
||||
const newOrder = arrayMove(prevItems, oldIndex, newIndex);
|
||||
|
||||
// Send update to backend
|
||||
updateProviderPriorityOnBackend(newOrder);
|
||||
void updateProviderPriorityOnBackend(newOrder);
|
||||
|
||||
return newOrder;
|
||||
});
|
||||
|
||||
@@ -270,7 +270,7 @@ export const UploadFiles3D = ({
|
||||
// B's key.
|
||||
useEffect(() => {
|
||||
if (previewStatus.type === "OK" && canvasRef.current) {
|
||||
snapshotCanvasAsThumbnail({
|
||||
void snapshotCanvasAsThumbnail({
|
||||
targetNode: canvasRef.current,
|
||||
resultCallback: (blob) => {
|
||||
const currentFile = fileEntries[previewIndex]?.file;
|
||||
@@ -503,7 +503,7 @@ export const UploadFiles3D = ({
|
||||
// can only ever be a clean single-file submission; the excludedCount
|
||||
// check makes that invariant explicit rather than incidental.
|
||||
if (excludedCount === 0 && files.length === 1 && fileEntries.length === 1) {
|
||||
upload3DObjects({
|
||||
void upload3DObjects({
|
||||
title: files[0].name.slice(0, files[0].name.lastIndexOf(".")),
|
||||
assetFile: files[0],
|
||||
engineCategory,
|
||||
@@ -521,7 +521,7 @@ export const UploadFiles3D = ({
|
||||
setIsUploading(true);
|
||||
setOverallProgress({ current: 0, total: files.length });
|
||||
|
||||
upload3DObjectsBatch({
|
||||
void upload3DObjectsBatch({
|
||||
files,
|
||||
thumbnails: pendingThumbnails,
|
||||
engineCategory,
|
||||
@@ -581,7 +581,7 @@ export const UploadFiles3D = ({
|
||||
setIsUploading(true);
|
||||
setOverallProgress({ current: 0, total: failedFiles.length });
|
||||
|
||||
upload3DObjectsBatch({
|
||||
void upload3DObjectsBatch({
|
||||
files: failedFiles,
|
||||
thumbnails: failedThumbnails,
|
||||
engineCategory,
|
||||
@@ -742,7 +742,7 @@ export const UploadFiles3D = ({
|
||||
className="hidden items-center text-xs text-white/60 transition-colors hover:text-white group-hover:inline-flex"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
retrySingleFile(i);
|
||||
void retrySingleFile(i);
|
||||
}}
|
||||
title="Retry"
|
||||
>
|
||||
|
||||
@@ -117,7 +117,7 @@ export const UploadFilesImage = ({
|
||||
.filter((i) => i !== -1);
|
||||
|
||||
if (files.length === 1 && fileEntries.length === 1) {
|
||||
uploadImage({
|
||||
void uploadImage({
|
||||
title: files[0].name.slice(0, files[0].name.lastIndexOf(".")),
|
||||
assetFile: files[0],
|
||||
progressCallback: onUploadProgress,
|
||||
@@ -128,7 +128,7 @@ export const UploadFilesImage = ({
|
||||
setIsUploading(true);
|
||||
setOverallProgress({ current: 0, total: files.length });
|
||||
|
||||
uploadImagesBatch({
|
||||
void uploadImagesBatch({
|
||||
files,
|
||||
onFileStatusChange: (batchIndex, status, errorMessage) =>
|
||||
updateFileStatus(originalIndices[batchIndex], status, errorMessage),
|
||||
@@ -159,7 +159,7 @@ export const UploadFilesImage = ({
|
||||
setIsUploading(true);
|
||||
setOverallProgress({ current: 0, total: failedFiles.length });
|
||||
|
||||
uploadImagesBatch({
|
||||
void uploadImagesBatch({
|
||||
files: failedFiles,
|
||||
onFileStatusChange: (batchIndex, status, errorMessage) =>
|
||||
updateFileStatus(failedIndices[batchIndex], status, errorMessage),
|
||||
@@ -248,7 +248,7 @@ export const UploadFilesImage = ({
|
||||
className="hidden group-hover:inline-flex items-center text-xs text-white/60 hover:text-white transition-colors"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
retrySingleFile(i);
|
||||
void retrySingleFile(i);
|
||||
}}
|
||||
title="Retry"
|
||||
>
|
||||
|
||||
@@ -127,7 +127,7 @@ export const UploadFilesSplat = ({
|
||||
const canvas = canvasRef.current;
|
||||
const currentFile = fileEntries[previewIndex]?.file;
|
||||
const rafId = requestAnimationFrame(() => {
|
||||
snapshotCanvasAsThumbnail({
|
||||
void snapshotCanvasAsThumbnail({
|
||||
targetNode: canvas,
|
||||
resultCallback: (blob) => {
|
||||
if (blob && currentFile) {
|
||||
@@ -222,7 +222,7 @@ export const UploadFilesSplat = ({
|
||||
);
|
||||
|
||||
if (files.length === 1 && fileEntries.length === 1) {
|
||||
upload3DObjects({
|
||||
void upload3DObjects({
|
||||
title: files[0].name.slice(0, files[0].name.lastIndexOf(".")),
|
||||
assetFile: files[0],
|
||||
engineCategory,
|
||||
@@ -236,7 +236,7 @@ export const UploadFilesSplat = ({
|
||||
setIsUploading(true);
|
||||
setOverallProgress({ current: 0, total: files.length });
|
||||
|
||||
upload3DObjectsBatch({
|
||||
void upload3DObjectsBatch({
|
||||
files,
|
||||
thumbnails: pendingThumbnails,
|
||||
engineCategory,
|
||||
@@ -277,7 +277,7 @@ export const UploadFilesSplat = ({
|
||||
setIsUploading(true);
|
||||
setOverallProgress({ current: 0, total: failedFiles.length });
|
||||
|
||||
upload3DObjectsBatch({
|
||||
void upload3DObjectsBatch({
|
||||
files: failedFiles,
|
||||
thumbnails: failedThumbnails,
|
||||
engineCategory,
|
||||
@@ -375,7 +375,7 @@ export const UploadFilesSplat = ({
|
||||
className="hidden group-hover:inline-flex items-center text-xs text-white/60 hover:text-white transition-colors"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
retrySingleFile(i);
|
||||
void retrySingleFile(i);
|
||||
}}
|
||||
title="Retry"
|
||||
>
|
||||
|
||||
@@ -441,7 +441,7 @@ export function useEditorActions() {
|
||||
useActionHandler(
|
||||
"toggle-bookmark",
|
||||
() => {
|
||||
editor.scenes.toggleBookmark({ time: editor.playback.getCurrentTime() });
|
||||
void editor.scenes.toggleBookmark({ time: editor.playback.getCurrentTime() });
|
||||
},
|
||||
undefined,
|
||||
);
|
||||
|
||||
@@ -21,7 +21,7 @@ export function useFontAtlas({ open }: { open: boolean }) {
|
||||
if (!open || atlas) return;
|
||||
|
||||
setStatus("loading");
|
||||
loadFontAtlas().then((data) => {
|
||||
void loadFontAtlas().then((data) => {
|
||||
if (data) {
|
||||
setAtlas(data);
|
||||
setStatus("idle");
|
||||
@@ -34,7 +34,7 @@ export function useFontAtlas({ open }: { open: boolean }) {
|
||||
const retry = useCallback(() => {
|
||||
clearFontAtlasCache();
|
||||
setStatus("loading");
|
||||
loadFontAtlas().then((data) => {
|
||||
void loadFontAtlas().then((data) => {
|
||||
if (data) {
|
||||
setAtlas(data);
|
||||
setStatus("idle");
|
||||
|
||||
@@ -20,7 +20,7 @@ export function useFullscreen({
|
||||
const toggleFullscreen = useCallback(() => {
|
||||
if (!containerRef.current) return;
|
||||
if (document.fullscreenElement) {
|
||||
document.exitFullscreen();
|
||||
void document.exitFullscreen();
|
||||
} else {
|
||||
containerRef.current.requestFullscreen();
|
||||
}
|
||||
|
||||
+2
-2
@@ -313,7 +313,7 @@ function BookmarkPopoverContent({
|
||||
}, [bookmark.color]);
|
||||
|
||||
const handleRemove = () => {
|
||||
editor.scenes.removeBookmark({ time });
|
||||
void editor.scenes.removeBookmark({ time });
|
||||
onPopoverClose();
|
||||
};
|
||||
|
||||
@@ -334,7 +334,7 @@ function BookmarkPopoverContent({
|
||||
updates.duration = duration;
|
||||
}
|
||||
if (Object.keys(updates).length === 0) return;
|
||||
editor.scenes.updateBookmark({ time, updates });
|
||||
void editor.scenes.updateBookmark({ time, updates });
|
||||
};
|
||||
const maxDuration = mediaTimeToSeconds({
|
||||
time:
|
||||
|
||||
+1
-1
@@ -240,7 +240,7 @@ export function useBookmarkDrag({
|
||||
const clampedTime =
|
||||
dragState.currentTime > duration ? duration : dragState.currentTime;
|
||||
|
||||
editor.scenes.moveBookmark({
|
||||
void editor.scenes.moveBookmark({
|
||||
fromTime: dragState.bookmarkTime,
|
||||
toTime: clampedTime,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user