💄 UX Optimized
This commit is contained in:
parent
8d1cb9d9c0
commit
86e184a803
@ -11,17 +11,18 @@
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^6.5.1",
|
||||
"@solidjs/router": "^0.10.10",
|
||||
"aplayer": "^1.10.1",
|
||||
"artplayer": "^5.1.1",
|
||||
"dompurify": "^3.0.8",
|
||||
"flv.js": "^1.6.2",
|
||||
"hls.js": "^1.5.3",
|
||||
"marked": "^12.0.0",
|
||||
"medium-zoom": "^1.1.0",
|
||||
"solid-js": "^1.8.7",
|
||||
"solid-markdown": "^2.0.0",
|
||||
"universal-cookie": "^7.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/typography": "^0.5.10",
|
||||
"@types/dompurify": "^3.0.5",
|
||||
"autoprefixer": "^10.4.17",
|
||||
"daisyui": "^4.6.1",
|
||||
"postcss": "^8.4.33",
|
||||
|
@ -3,14 +3,10 @@ import mediumZoom from "medium-zoom";
|
||||
|
||||
import styles from "./PostAttachments.module.css";
|
||||
|
||||
// @ts-ignore
|
||||
import APlayer from "aplayer";
|
||||
import Artplayer from "artplayer";
|
||||
import HlsJs from "hls.js";
|
||||
import FlvJs from "flv.js";
|
||||
|
||||
import "aplayer/dist/APlayer.min.css";
|
||||
|
||||
function Video({ url, ...rest }: any) {
|
||||
let container: any;
|
||||
|
||||
@ -21,24 +17,24 @@ function Video({ url, ...rest }: any) {
|
||||
hls.loadSource(url);
|
||||
hls.attachMedia(video);
|
||||
art.hls = hls;
|
||||
art.on('destroy', () => hls.destroy());
|
||||
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
|
||||
art.on("destroy", () => hls.destroy());
|
||||
} else if (video.canPlayType("application/vnd.apple.mpegurl")) {
|
||||
video.src = url;
|
||||
} else {
|
||||
art.notice.show = 'Unsupported playback format: m3u8';
|
||||
art.notice.show = "Unsupported playback format: m3u8";
|
||||
}
|
||||
}
|
||||
|
||||
function playFlv(video: HTMLVideoElement, url: string, art: Artplayer) {
|
||||
if (FlvJs.isSupported()) {
|
||||
if (art.flv) art.flv.destroy();
|
||||
const flv = FlvJs.createPlayer({ type: 'flv', url });
|
||||
const flv = FlvJs.createPlayer({ type: "flv", url });
|
||||
flv.attachMediaElement(video);
|
||||
flv.load();
|
||||
art.flv = flv;
|
||||
art.on('destroy', () => flv.destroy());
|
||||
art.on("destroy", () => flv.destroy());
|
||||
} else {
|
||||
art.notice.show = 'Unsupported playback format: flv';
|
||||
art.notice.show = "Unsupported playback format: flv";
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,14 +50,11 @@ function Video({ url, ...rest }: any) {
|
||||
subtitleOffset: true,
|
||||
fullscreen: true,
|
||||
fullscreenWeb: true,
|
||||
screenshot: true,
|
||||
autoPlayback: true,
|
||||
airplay: true,
|
||||
theme: "#49509e",
|
||||
customType: {
|
||||
m3u8: playM3u8,
|
||||
flv: playFlv,
|
||||
},
|
||||
flv: playFlv
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -71,21 +64,12 @@ function Video({ url, ...rest }: any) {
|
||||
}
|
||||
|
||||
function Audio({ url, caption, ...rest }: any) {
|
||||
let container: any;
|
||||
|
||||
createEffect(() => {
|
||||
new APlayer({
|
||||
container: container as HTMLDivElement,
|
||||
audio: [{
|
||||
name: caption,
|
||||
url: url,
|
||||
theme: "#49509e"
|
||||
}]
|
||||
});
|
||||
});
|
||||
|
||||
return (
|
||||
<div ref={container} {...rest}></div>
|
||||
<figure {...rest}>
|
||||
<figcaption>{caption}</figcaption>
|
||||
<audio controls src={url} />
|
||||
</figure>
|
||||
);
|
||||
}
|
||||
|
||||
@ -129,7 +113,7 @@ export default function PostAttachments(props: { attachments: any[] }) {
|
||||
</div>
|
||||
|
||||
<div class="mt-5">
|
||||
<a class="link" href={getUrl(item())} target="_blank">Open in browser</a>
|
||||
<a class="link" href={getUrl(item())} target="_blank">Open in browser</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -140,7 +124,8 @@ export default function PostAttachments(props: { attachments: any[] }) {
|
||||
</figure>
|
||||
</Match>
|
||||
<Match when={getRenderType(item()) === "audio"}>
|
||||
<Audio class="w-full" url={getUrl(item())} caption={item().filename} />
|
||||
<Audio class="p-5 flex flex-col items-center justify-center gap-2 w-full" url={getUrl(item())}
|
||||
caption={item().filename} />
|
||||
</Match>
|
||||
<Match when={getRenderType(item()) === "video"}>
|
||||
<Video class="h-[360px] w-full" url={getUrl(item())} caption={item().filename} />
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { createSignal, For, Show } from "solid-js";
|
||||
import { getAtk, useUserinfo } from "../stores/userinfo.tsx";
|
||||
import PostAttachments from "./PostAttachments.tsx";
|
||||
import { SolidMarkdown } from "solid-markdown";
|
||||
import * as marked from "marked";
|
||||
import DOMPurify from "dompurify";
|
||||
|
||||
export default function PostItem(props: {
|
||||
post: any,
|
||||
@ -37,9 +38,7 @@ export default function PostItem(props: {
|
||||
}
|
||||
|
||||
const content = (
|
||||
<article class="prose">
|
||||
<SolidMarkdown children={props.post.content} />
|
||||
</article>
|
||||
<article class="prose" innerHTML={DOMPurify.sanitize(marked.parse(props.post.content) as string)} />
|
||||
);
|
||||
|
||||
return (
|
||||
@ -64,7 +63,7 @@ export default function PostItem(props: {
|
||||
</div>
|
||||
</a>
|
||||
</Show>
|
||||
<div class="px-7">
|
||||
<div class="px-7 py-5">
|
||||
<h2 class="card-title">{props.post.title}</h2>
|
||||
|
||||
<Show when={!props.noClick} fallback={content}>
|
||||
@ -73,7 +72,7 @@ export default function PostItem(props: {
|
||||
</a>
|
||||
</Show>
|
||||
|
||||
<div class="mt-2 mb-5 flex gap-2">
|
||||
<div class="mt-2 flex gap-2">
|
||||
<For each={props.post.categories}>
|
||||
{item =>
|
||||
<a href={`/search?category=${item.alias}`} class="badge badge-primary">
|
||||
@ -93,7 +92,7 @@ export default function PostItem(props: {
|
||||
</div>
|
||||
|
||||
<Show when={props.post.attachments?.length > 0}>
|
||||
<div class="pb-5">
|
||||
<div>
|
||||
<PostAttachments attachments={props.post.attachments ?? []} />
|
||||
</div>
|
||||
</Show>
|
||||
|
@ -11,7 +11,7 @@ import { Route, Router } from "@solidjs/router";
|
||||
import "@fortawesome/fontawesome-free/css/all.css";
|
||||
|
||||
import RootLayout from "./layouts/RootLayout.tsx";
|
||||
import Feed from "./pages/feed.tsx";
|
||||
import Feed from "./pages/view.tsx";
|
||||
import Global from "./pages/global.tsx";
|
||||
import PostReference from "./pages/post.tsx";
|
||||
import { UserinfoProvider } from "./stores/userinfo.tsx";
|
||||
|
@ -1,6 +1,6 @@
|
||||
.wrapper {
|
||||
display: grid;
|
||||
grid-template-columns: fit-content(100%);
|
||||
grid-template-columns: 1fr;
|
||||
column-gap: 20px;
|
||||
|
||||
max-height: calc(100vh - 64px);
|
@ -1,4 +1,4 @@
|
||||
import styles from "./feed.module.css";
|
||||
import styles from "./view.module.css";
|
||||
|
||||
export default function DashboardPage(props: any) {
|
||||
return (
|
Loading…
Reference in New Issue
Block a user