-
- {!isConnected() ? (
-
-
已连接到服务器
-
播放器需要连接到游戏
-
在游戏中输入以下指令:
-
- /ipm bind 123456
-
-
- ) : (
-
-
播放器已准备好
-
点击下方按钮开始播放
-
-
- )}
+
+
+
+
+
+
+ {renderWell()}
+
+
>
diff --git a/src/components/Card.tsx b/src/components/Card.tsx
deleted file mode 100644
index 3846407..0000000
--- a/src/components/Card.tsx
+++ /dev/null
@@ -1,37 +0,0 @@
-import { createEffect, createSignal, JSXElement, onCleanup, onMount, useTransition } from "solid-js"
-
-export type CardProps = {
- title?: string | JSXElement,
- children?: any
-}
-
-export const Card = (props: CardProps) => {
- const [outerHeight, setOuterHeight] = createSignal
(0)
- let innerElem: HTMLDivElement | undefined
-
- onMount(() => {
- if (innerElem) {
- setOuterHeight(innerElem?.offsetHeight)
- }
- })
-
- createEffect(() => {
- if (innerElem) {
- setOuterHeight(innerElem?.offsetHeight)
- }
- })
-
- return (
-
-
-
-
-
{props.title}
-
点击下方按钮开始播放
-
-
-
-
-
- )
-}
\ No newline at end of file
diff --git a/src/components/ConnectingWell.tsx b/src/components/ConnectingWell.tsx
new file mode 100644
index 0000000..ed3ccde
--- /dev/null
+++ b/src/components/ConnectingWell.tsx
@@ -0,0 +1,8 @@
+export const ConnectingWell = () => {
+ return (
+
+ )
+}
\ No newline at end of file
diff --git a/src/components/HeightTransition/index.scss b/src/components/HeightTransition/index.scss
new file mode 100644
index 0000000..171773a
--- /dev/null
+++ b/src/components/HeightTransition/index.scss
@@ -0,0 +1,11 @@
+.height-transition-container {
+ overflow: hidden;
+ position: relative;
+ transition: height 350ms ease-in-out;
+ height: auto;
+}
+
+.height-transition-inner {
+ width: 100%;
+ height: auto;
+}
\ No newline at end of file
diff --git a/src/components/HeightTransition/index.tsx b/src/components/HeightTransition/index.tsx
new file mode 100644
index 0000000..feb1a23
--- /dev/null
+++ b/src/components/HeightTransition/index.tsx
@@ -0,0 +1,31 @@
+import { createSignal, JSXElement } from "solid-js"
+import { Transition } from "solid-transition-group"
+import "./index.scss";
+
+export type HeightTransitionProps = {
+ children: JSXElement
+}
+
+export const HeightTransition = (props: HeightTransitionProps) => {
+ const [outerHeight, setOuterHeight] = createSignal()
+
+ return (
+
+
+ {
+ setOuterHeight((el as any).offsetHeight);
+ setTimeout(done, 400);
+ }}
+ onExit={(el, done) => {
+ setOuterHeight((el as any).offsetHeight);
+ setTimeout(done, 400);
+ }}
+ >
+ {props.children}
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/src/components/PairWell.tsx b/src/components/PairWell.tsx
new file mode 100644
index 0000000..dc45515
--- /dev/null
+++ b/src/components/PairWell.tsx
@@ -0,0 +1,11 @@
+export const PairWell = () => {
+ return (
+
+
播放器需要连接到游戏
+
在游戏中输入以下指令:
+
+ /ipm bind 123456
+
+
+ )
+}
\ No newline at end of file
diff --git a/src/components/PlayerActivationWell.tsx b/src/components/PlayerActivationWell.tsx
new file mode 100644
index 0000000..5aaae08
--- /dev/null
+++ b/src/components/PlayerActivationWell.tsx
@@ -0,0 +1,41 @@
+import { createSignal } from "solid-js"
+import { SuccessAnimateIcon } from "./SuccessAnimateIcon"
+
+export type PlayerActivationWellProps = {
+ connecting?: boolean,
+ onEnabled?: () => any
+}
+
+export const PlayerActivationWell = (props: PlayerActivationWellProps) => {
+ const [processing, setProcessing] = createSignal(false)
+ const [enabled, setEnabled] = createSignal(false)
+ const [error, setError] = createSignal()
+
+ const handleEnableClick = () => {
+ setProcessing(true)
+ setEnabled(true)
+ // 等待成功动画结束
+ setTimeout(() => {
+ props.onEnabled?.()
+ }, 1500)
+ }
+
+ return (
+
+
播放器需要激活
+
由于浏览器限制,网页不能自动播放音频,需要手动点击下方按钮
+
+
+ {enabled() && (
+
+ )}
+ {!error() && enabled() && props.connecting && (
+ 正在等待连接服务器
+ )}
+ {error() && (
+ 启动播放器错误: {error()}
+ )}
+
+
+ )
+}
\ No newline at end of file
diff --git a/src/components/PlayerWell.tsx b/src/components/PlayerWell.tsx
new file mode 100644
index 0000000..0d017f7
--- /dev/null
+++ b/src/components/PlayerWell.tsx
@@ -0,0 +1,8 @@
+export const PlayerWell = () => {
+ return (
+
+
播放器已准备完成
+
当前状态: 等待播放
+
+ )
+}
\ No newline at end of file
diff --git a/src/components/ServerStatus.tsx b/src/components/ServerStatus.tsx
new file mode 100644
index 0000000..e3eb723
--- /dev/null
+++ b/src/components/ServerStatus.tsx
@@ -0,0 +1,36 @@
+import { Match, mergeProps, Switch } from "solid-js";
+import { Transition } from "solid-transition-group"
+
+export type ServerStatusType = 'connecting' | 'connected' | 'error'
+
+export type ServerStatusProps = {
+ type?: ServerStatusType,
+ error?: string
+}
+
+export const ServerStatus = (srcProps: ServerStatusProps) => {
+ const props = mergeProps({
+ type: 'connecting',
+ }, srcProps)
+
+ return (
+
+ )
+}
\ No newline at end of file
diff --git a/src/components/SuccessAnimateIcon/index.scss b/src/components/SuccessAnimateIcon/index.scss
new file mode 100644
index 0000000..160d124
--- /dev/null
+++ b/src/components/SuccessAnimateIcon/index.scss
@@ -0,0 +1,45 @@
+.success-animation {
+ display: inline-block;
+ padding: 6px;
+
+ .checkmark {
+ width: 36px;
+ height: 36px;
+ border-radius: 50%;
+ --bs-bg-opacity: 1;
+ stroke-width: 3px;
+ stroke: rgb(var(--bs-success-rgb));
+ stroke-miterlimit: 10;
+ box-shadow: inset 0px 0px 0px rgb(var(--bs-success-rgb));
+ animation: successAnimIconFill .4s ease-in-out .4s forwards;
+
+ &__circle {
+ stroke-dasharray: 166;
+ stroke-dashoffset: 166;
+ stroke-width: 3px;
+ stroke-miterlimit: 10;
+ stroke: rgb(var(--bs-success-rgb));
+ fill: rgb(var(--bs-white-rgb));
+ animation: successAnimIconStroke 0.6s cubic-bezier(0.65, 0, 0.45, 1) forwards;
+ }
+
+ &__check {
+ transform-origin: 50% 50%;
+ stroke-dasharray: 48;
+ stroke-dashoffset: 48;
+ animation: successAnimIconStroke 0.3s cubic-bezier(0.65, 0, 0.45, 1) 0.6s forwards;
+ }
+ }
+}
+
+@keyframes successAnimIconStroke {
+ 100% {
+ stroke-dashoffset: 0;
+ }
+}
+
+@keyframes successAnimIconFill {
+ 100% {
+ box-shadow: inset 0px 0px 0px 30px #4bb71b;
+ }
+}
\ No newline at end of file
diff --git a/src/components/SuccessAnimateIcon/index.tsx b/src/components/SuccessAnimateIcon/index.tsx
new file mode 100644
index 0000000..a2bb197
--- /dev/null
+++ b/src/components/SuccessAnimateIcon/index.tsx
@@ -0,0 +1,12 @@
+import "./index.scss"
+
+export const SuccessAnimateIcon = () => {
+ return (
+
+ )
+};
\ No newline at end of file
diff --git a/src/libs/bootstrap/scss/bootstrap.scss b/src/libs/bootstrap/scss/bootstrap.scss
index 8f8296d..e329d4c 100644
--- a/src/libs/bootstrap/scss/bootstrap.scss
+++ b/src/libs/bootstrap/scss/bootstrap.scss
@@ -17,31 +17,31 @@
@import "images";
@import "containers";
@import "grid";
-@import "tables";
+// @import "tables";
@import "forms";
@import "buttons";
-@import "transitions";
+// @import "transitions";
@import "dropdown";
@import "button-group";
@import "nav";
@import "navbar";
@import "card";
-@import "accordion";
-@import "breadcrumb";
-@import "pagination";
-@import "badge";
-@import "alert";
-@import "progress";
-@import "list-group";
+// @import "accordion";
+// @import "breadcrumb";
+// @import "pagination";
+// @import "badge";
+// @import "alert";
+// @import "progress";
+// @import "list-group";
@import "close";
-@import "toasts";
+// @import "toasts";
@import "modal";
-@import "tooltip";
-@import "popover";
-@import "carousel";
+// @import "tooltip";
+// @import "popover";
+// @import "carousel";
@import "spinners";
-@import "offcanvas";
-@import "placeholders";
+// @import "offcanvas";
+// @import "placeholders";
// Helpers
@import "helpers";
diff --git a/src/stores/Player.ts b/src/stores/Player.ts
new file mode 100644
index 0000000..e69de29
diff --git a/src/style.scss b/src/style.scss
index 237b81d..f22d99e 100644
--- a/src/style.scss
+++ b/src/style.scss
@@ -1,2 +1,4 @@
@import "./libs/bootstrap/scss/bootstrap.scss";
-@import "bootstrap-icons/font/bootstrap-icons.css";
\ No newline at end of file
+@import "bootstrap-icons/font/bootstrap-icons.css";
+
+@import "./styles/animate.scss";
\ No newline at end of file
diff --git a/src/styles/animate.scss b/src/styles/animate.scss
new file mode 100644
index 0000000..a6cd75f
--- /dev/null
+++ b/src/styles/animate.scss
@@ -0,0 +1,94 @@
+.anim-scroll-container {
+ overflow-y: hidden;
+ position: relative;
+}
+
+.slide-up {
+ &-enter-active {
+ transform: translate3d(0, 100%, 0);
+ transition: transform 350ms ease-in-out;
+ }
+
+ &-enter-to {
+ transform: translate3d(0, 0, 0);
+ }
+
+ &-exit-active {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ transform: translate3d(0, 0, 0);
+ transition: transform 350ms ease-in-out;
+ }
+
+ &-exit-to {
+ transform: translate3d(0, -100%, 0);
+ }
+}
+
+.fade {
+ &-enter {
+ opacity: 0;
+ }
+
+ &-enter-active {
+ display: inherit;
+ opacity: 0;
+ transition: opacity 150ms linear;
+ }
+
+ &-enter-to {
+ opacity: 1;
+ }
+
+ &-exit {
+ opacity: 1;
+ }
+
+ &-exit-active {
+ opacity: 1;
+ transition: opacity 150ms linear;
+ }
+
+ &-exit-to {
+ opacity: 0;
+ }
+}
+
+.fade-left {
+ &-enter {
+ opacity: 0;
+ }
+
+ &-enter-active {
+ display: inherit;
+ opacity: 0;
+ transform: translate3d(5%, 0, 0);
+ transition: opacity 250ms linear, transform 250ms ease-in-out;
+ }
+
+ &-enter-to {
+ opacity: 1;
+ transform: translate3d(0, 0, 0);
+ }
+
+ &-exit {
+ opacity: 1;
+ }
+
+ &-exit-active {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ opacity: 1;
+ transform: translate3d(0, 0, 0);
+ transition: opacity 250ms linear, transform 250ms ease-in-out;
+ }
+
+ &-exit-to {
+ opacity: 0;
+ transform: translate3d(-5%, 0, 0);
+ }
+}
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
index 109805d..3b62042 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -5,6 +5,7 @@
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
+ "jsxImportSource": "solid-js",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,