(null);
useEffect(() => {
- if (file != null) setTitle?.(file.id);
+ if (file != null)
+ setTitle?.(file.id);
}, [file, setTitle]);
+ useEffect(() => {
+ if (file == null || file.source == null)
+ return;
+
+ if (file.extension && AUDIO_EXTENSIONS.includes(file.extension)) {
+ if (audioRef.current) {
+ audioRef.current.src = file.source;
+ void audioRef.current.play();
+ setIsPlaying(true);
+ }
+ }
+
+ if (file.extension && VIDEO_EXTENSIONS.includes(file.extension)) {
+ if (videoRef.current) {
+ videoRef.current.src = file.source;
+ void videoRef.current.play();
+ setIsPlaying(true);
+ }
+ }
+
+ return () => {
+ if (audioRef.current) {
+ audioRef.current.pause();
+ audioRef.current.currentTime = 0;
+ }
+ if (videoRef.current) {
+ videoRef.current.pause();
+ videoRef.current.currentTime = 0;
+ }
+ };
+ }, [file]);
+
+ const handlePlay = () => {
+ if (audioRef.current) {
+ void audioRef.current.play();
+ }
+ if (videoRef.current) {
+ void videoRef.current.play();
+ }
+ setIsPlaying(true);
+ };
+
+ const handlePause = () => {
+ if (audioRef.current) {
+ audioRef.current.pause();
+ }
+ if (videoRef.current) {
+ videoRef.current.pause();
+ }
+ setIsPlaying(false);
+ };
+
+ const handleStop = () => {
+ if (audioRef.current) {
+ audioRef.current.pause();
+ audioRef.current.currentTime = 0;
+ }
+ if (videoRef.current) {
+ videoRef.current.pause();
+ videoRef.current.currentTime = 0;
+ }
+ setIsPlaying(false);
+ };
+
if (file == null) {
const fileExplorerApp = appsConfig.getAppByRole(AppsConfig.APP_ROLES.fileExplorer);
@@ -22,12 +90,56 @@ export function MediaViewer({ file, close, setTitle }: MediaViewerProps) {
windowsManager?.open(fileExplorerApp.id, { path: "~/Pictures" });
close?.();
}, 10);
- return;
+ return null;
}
- if (file.extension == null || !IMAGE_EXTENSIONS.includes(file.extension)) return Invalid file format.
;
+ if (file.extension == null || !MEDIA_EXTENSIONS.includes(file.extension)) {
+ return Invalid file format.
;
+ }
- if (file.source == null) return File failed to load.
;
+ if (file.source == null)
+ return File failed to load.
;
+
+ if (IMAGE_EXTENSIONS.includes(file.extension)) {
+ return
+ {file.id}
+
;
+ } else if (AUDIO_EXTENSIONS.includes(file.extension)) {
+ return
+
Playing audio: {file.id}
+
+
+
+
+
+
+
;
+ } else if (VIDEO_EXTENSIONS.includes(file.extension)) {
+ if (file.extension === "yt") {
+ return
+
+
;
+ } else {
+ return
+
+
;
+ }
+ }
return
{file.id}
diff --git a/packages/apps/media-viewer/src/main.ts b/packages/apps/media-viewer/src/main.ts
index 5919bcc7..a49cab83 100644
--- a/packages/apps/media-viewer/src/main.ts
+++ b/packages/apps/media-viewer/src/main.ts
@@ -1,10 +1,10 @@
-import { App, AppsConfig, IMAGE_EXTENSIONS } from "@prozilla-os/core";
+import { App, AppsConfig, MEDIA_EXTENSIONS } from "@prozilla-os/core";
import { MediaViewer, MediaViewerProps } from "./components/MediaViewer";
const mediaViewer = new App("Media Viewer", "media-viewer", MediaViewer)
.setIconUrl("https://os.prozilla.dev/assets/apps/icons/media-viewer.svg")
.setRole(AppsConfig.APP_ROLES.mediaViewer)
- .setAssociatedExtensions(IMAGE_EXTENSIONS)
+ .setAssociatedExtensions(MEDIA_EXTENSIONS)
.setCategory("Photo & video");
export { mediaViewer };
\ No newline at end of file
diff --git a/packages/core/src/constants/index.ts b/packages/core/src/constants/index.ts
index 34370c71..1efa8cb5 100644
--- a/packages/core/src/constants/index.ts
+++ b/packages/core/src/constants/index.ts
@@ -1,3 +1,3 @@
-export { CODE_EXTENSIONS, IMAGE_EXTENSIONS } from "./virtualDrive.const";
+export { CODE_EXTENSIONS, IMAGE_EXTENSIONS, VIDEO_EXTENSIONS, AUDIO_EXTENSIONS, MEDIA_EXTENSIONS } from "./virtualDrive.const";
export { THEMES } from "./themes.const";
export { APP_CATEGORIES } from "./apps.const";
\ No newline at end of file
diff --git a/packages/core/src/constants/virtualDrive.const.ts b/packages/core/src/constants/virtualDrive.const.ts
index 1cfde485..2f930f30 100644
--- a/packages/core/src/constants/virtualDrive.const.ts
+++ b/packages/core/src/constants/virtualDrive.const.ts
@@ -19,7 +19,40 @@ export const IMAGE_EXTENSIONS = [
"ico",
];
+export const AUDIO_EXTENSIONS = [
+ "mp3",
+ "wav",
+ "aac",
+ "flac",
+ "ogg",
+ "m4a",
+ "wma",
+ "alac",
+ "aiff",
+ "pcm",
+];
+
+export const VIDEO_EXTENSIONS = [
+ "mp4",
+ "avi",
+ "mkv",
+ "mov",
+ "wmv",
+ "flv",
+ "webm",
+ "mpeg",
+ "mpg",
+ "m4v",
+ "yt",
+];
+
+export const MEDIA_EXTENSIONS = [
+ ...IMAGE_EXTENSIONS,
+ ...AUDIO_EXTENSIONS,
+ ...VIDEO_EXTENSIONS,
+];
+
export const FILE_SCHEMES = {
external: "ext://",
app: "app://",
-};
\ No newline at end of file
+};
diff --git a/packages/core/src/features/virtual-drive/file/virtualFile.ts b/packages/core/src/features/virtual-drive/file/virtualFile.ts
index 84a84aa5..0581fbf0 100644
--- a/packages/core/src/features/virtual-drive/file/virtualFile.ts
+++ b/packages/core/src/features/virtual-drive/file/virtualFile.ts
@@ -1,4 +1,4 @@
-import { FILE_SCHEMES, IMAGE_EXTENSIONS } from "../../../constants/virtualDrive.const";
+import { AUDIO_EXTENSIONS, FILE_SCHEMES, IMAGE_EXTENSIONS, VIDEO_EXTENSIONS } from "../../../constants/virtualDrive.const";
import { WindowsManager } from "../../windows/windowsManager";
import { VirtualBase, VirtualBaseJson } from "../virtualBase";
@@ -121,8 +121,14 @@ export class VirtualFile extends VirtualBase {
const { skin, appsConfig } = this.getRoot().systemManager;
if (this.source != null) {
- if (this.extension != null && IMAGE_EXTENSIONS.includes(this.extension)) {
- return this.source;
+ if (this.extension != null) {
+ if (IMAGE_EXTENSIONS.includes(this.extension)) {
+ return this.source;
+ } else if (VIDEO_EXTENSIONS.includes(this.extension)) {
+ return skin.fileIcons.video ?? skin.fileIcons.generic;
+ } else if (AUDIO_EXTENSIONS.includes(this.extension)) {
+ return skin.fileIcons.audio ?? skin.fileIcons.generic;
+ }
} else if (this.source.startsWith(FILE_SCHEMES.app)) {
const app = appsConfig.getAppById(VirtualFile.removeFileScheme(this.source));
diff --git a/packages/core/src/features/virtual-drive/root/defaultData.ts b/packages/core/src/features/virtual-drive/root/defaultData.ts
index 5f2f18f2..c53cc88e 100644
--- a/packages/core/src/features/virtual-drive/root/defaultData.ts
+++ b/packages/core/src/features/virtual-drive/root/defaultData.ts
@@ -111,6 +111,23 @@ export function loadDefaultData(systemManager: SystemManager, virtualRoot: Virtu
});
});
}
+
+ userFolder.createFolder("Videos", (videosFolder) => {
+ videosFolder.setIconUrl(skin.folderIcons.video ?? skin.folderIcons.generic)
+ .createFile("Weezer_Buddy-Holly", "yt", (file) => {
+ file.setSource("https://www.youtube.com/watch?v=kemivUKb4f4");
+ });
+ });
+
+ userFolder.createFolder("Audio", (folder) => {
+ folder.setIconUrl(skin.folderIcons.audio ?? skin.folderIcons.generic)
+ .createFile("Assasins Creed Rogue Theme", "mp3", (file) => {
+ file.setSource("https://vgmsite.com/soundtracks/assassin-s-creed-rogue-original-game-soundtrack/rgvmdtdtyv/01.%20Assassin%27s%20Creed%20Rogue%20Main%20Theme.mp3");
+ })
+ .createFile("Mortal Kombat theme", "mp3", (file) => {
+ file.setSource("https://kappa.vgmsite.com/soundtracks/mortal-kombat-vscdt-1487-1993/posqvhcduj/01.%20TECHNO-SYNDROME%207%27%27%20MIX.mp3");
+ });
+ });
userFolder.createFolder("Apps", (appsFolder) => {
appsConfig.apps.forEach((app) => {
diff --git a/packages/skins/src/core/skin.ts b/packages/skins/src/core/skin.ts
index 5a7461a6..d0f56f26 100644
--- a/packages/skins/src/core/skin.ts
+++ b/packages/skins/src/core/skin.ts
@@ -39,6 +39,8 @@ interface SkinOptions {
text?: string;
code?: string;
external?: string;
+ video?: string;
+ audio?: string;
};
/**
@@ -49,6 +51,8 @@ interface SkinOptions {
images?: string;
text?: string;
link?: string;
+ video?: string;
+ audio?: string;
};
/**
@@ -94,12 +98,16 @@ export class Skin {
info: "https://os.prozilla.dev/assets/apps/file-explorer/icons/file-info.svg",
code: "https://os.prozilla.dev/assets/apps/file-explorer/icons/file-code.svg",
external: "https://os.prozilla.dev/assets/apps/file-explorer/icons/file-external.svg",
+ video: "https://os.prozilla.dev/assets/apps/file-explorer/icons/file-video.svg",
+ audio: "https://os.prozilla.dev/assets/apps/file-explorer/icons/file-audio.svg",
};
this.folderIcons = options.folderIcons ?? {
generic: "https://os.prozilla.dev/assets/apps/file-explorer/icons/folder.svg",
images: "https://os.prozilla.dev/assets/apps/file-explorer/icons/folder-images.svg",
text: "https://os.prozilla.dev/assets/apps/file-explorer/icons/folder-text.svg",
link: "https://os.prozilla.dev/assets/apps/file-explorer/icons/folder-link.svg",
+ video: "https://os.prozilla.dev/assets/apps/file-explorer/icons/folder-video.svg",
+ audio: "https://os.prozilla.dev/assets/apps/file-explorer/icons/folder-audio.svg",
};
this.loadStyleSheet = options.loadStyleSheet;