diff --git a/mimes.json b/mimes.json index 30f44b2a..3092679b 100755 --- a/mimes.json +++ b/mimes.json @@ -122,6 +122,7 @@ ["calx", ["application/vnd.ms-office.calx"]], ["cap", ["application/vnd.tcpdump.pcap"]], ["car", ["application/vnd.curl.car"]], + ["cast", ["application/x-asciicast"]], ["cat", ["application/vnd.ms-pki.seccat"]], ["cb7", ["application/x-cbr"]], ["cba", ["application/x-cbr"]], diff --git a/package.json b/package.json index 10de9080..194e7853 100755 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "@smithy/node-http-handler": "^4.1.0", "@tabler/icons-react": "^3.34.1", "argon2": "^0.43.1", + "asciinema-player": "^3.10.0", "bytes": "^3.1.2", "clsx": "^2.1.1", "colorette": "^2.0.20", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 70dd731e..b747ddd9 100755 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -83,6 +83,9 @@ importers: argon2: specifier: ^0.43.1 version: 0.43.1 + asciinema-player: + specifier: ^3.10.0 + version: 3.10.0 bytes: specifier: ^3.1.2 version: 3.1.2 @@ -2164,6 +2167,9 @@ packages: resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} engines: {node: '>= 0.4'} + asciinema-player@3.10.0: + resolution: {integrity: sha512-shoOK6F606nDKZxDVM7JuGSCAyWLePoGRFNlV+FqiP5Sqvyn0BlE7wlbjZyd2X4P1iRhv/HKfVNtnQIxmgphRA==} + ast-types-flow@0.0.8: resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} @@ -4248,6 +4254,16 @@ packages: engines: {node: '>=10'} hasBin: true + seroval-plugins@1.3.2: + resolution: {integrity: sha512-0QvCV2lM3aj/U3YozDiVwx9zpH0q8A60CTWIv4Jszj/givcudPb48B+rkU5D51NJ0pTpweGMttHjboPa9/zoIQ==} + engines: {node: '>=10'} + peerDependencies: + seroval: ^1.0 + + seroval@1.3.2: + resolution: {integrity: sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ==} + engines: {node: '>=10'} + set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} @@ -4311,6 +4327,9 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} + solid-js@1.9.9: + resolution: {integrity: sha512-A0ZBPJQldAeGCTW0YRYJmt7RCeh5rbFfPZ2aOttgYnctHE7HgKeHCBB/PVc2P7eOfmNXqMFFFoYYdm3S4dcbkA==} + sonic-boom@4.2.0: resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==} @@ -7177,6 +7196,11 @@ snapshots: get-intrinsic: 1.3.0 is-array-buffer: 3.0.5 + asciinema-player@3.10.0: + dependencies: + '@babel/runtime': 7.28.2 + solid-js: 1.9.9 + ast-types-flow@0.0.8: {} async-function@1.0.0: {} @@ -9699,6 +9723,12 @@ snapshots: semver@7.7.2: {} + seroval-plugins@1.3.2(seroval@1.3.2): + dependencies: + seroval: 1.3.2 + + seroval@1.3.2: {} + set-blocking@2.0.0: {} set-cookie-parser@2.7.1: {} @@ -9800,6 +9830,12 @@ snapshots: slash@3.0.0: {} + solid-js@1.9.9: + dependencies: + csstype: 3.1.3 + seroval: 1.3.2 + seroval-plugins: 1.3.2(seroval@1.3.2) + sonic-boom@4.2.0: dependencies: atomic-sleep: 1.0.0 diff --git a/src/components/file/DashboardFileType.tsx b/src/components/file/DashboardFileType.tsx index 8c216bad..cb613306 100755 --- a/src/components/file/DashboardFileType.tsx +++ b/src/components/file/DashboardFileType.tsx @@ -15,6 +15,7 @@ import { useEffect, useState, useCallback, useMemo } from 'react'; import { renderMode } from '../pages/upload/renderMode'; import Render from '../render/Render'; import fileIcon from './fileIcon'; +import Asciinema from '../render/Asciinema'; function PlaceholderContent({ text, Icon }: { text: string; Icon: Icon }) { return ( @@ -83,7 +84,7 @@ export default function DashboardFileType({ const renderIn = useMemo(() => renderMode(file.name.split('.').pop() || ''), [file.name]); const [fileContent, setFileContent] = useState(''); - const [type, setType] = useState(file.type.split('/')[0]); + const [type, setType] = useState(file.type.split('/')[0]); const [open, setOpen] = useState(false); @@ -164,8 +165,10 @@ export default function DashboardFileType({ ); - switch (type) { - case 'video': + const isAsciicast = file.type === 'application/x-asciicast' || file.name.endsWith('.cast'); + + switch (true) { + case type === 'video': return show ? (