Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .loki/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
current
difference
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,18 @@ This repository contributors are welcome to use
test results immediately as you type, and see the results in
your editor right next to your code.

node_modules/.pnpm jest-runtime version other than 29.4.3 will cause wallabyjs to stop working

## Turborepo

### run generate

```shell
turbo gen
```
```

## Known issues

### Solidjs vitest test does not work

fixed version until solidjs team fixes the issue
vitest: 2.0.5
vite: 5.4.11
8 changes: 8 additions & 0 deletions apps/bplan-client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,11 @@ https://www.mapianist.com/sheet/121897
https://magenta.tensorflow.org/get-started/#magenta-js

## kwnown issue

## Browser Compatibility

- chrome 55+
- safari 11.3+
- firefox 53+
- opera 42+
- edge 15+
8 changes: 4 additions & 4 deletions apps/bplan-client/build-hot-fix.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ function getDefaultExportFromNamespaceIfNotNamed (n) {
}`), 'utf8')
}

const fixSw = async () => {
return nodeFs.promises.rm(nodePath.resolve('public/sw.js'))
}
// const fixSw = async () => {
// return nodeFs.promises.rm(nodePath.resolve('public/sw.js'))
// }

fix().then(() => console.info('hot fix done'))
fixSw().then(() => console.info('hot fix sw done'))
// fixSw().then(() => console.info('hot fix sw done'))
22 changes: 12 additions & 10 deletions apps/bplan-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
"name": "@apps/bplan-client",
"type": "module",
"scripts": {
"build": "vinxi build && node build-hot-fix.mjs",
"build": "vinxi build",
"dev": "vinxi dev --host ",
"start": "node ./.output/server/index.mjs",
"fix": "node build-hot-fix.mjs",
"generate-pwa-assets": "pwa-assets-generator",
"check-types": "tsc --noEmit",
"lint": "eslint src/**/*.ts[x]"
Expand All @@ -14,38 +13,41 @@
"dependencies": {
"@tonejs/midi": "^2.0.28",
"@solidjs/meta": "^0.29.4",
"@solidjs/router": "^0.15.2",
"@solidjs/start": "^1.0.10",
"@solidjs/router": "0.15.3",
"@solidjs/start": "^1.0.11",
"@winter-love/lodash": "workspace:*",
"@winter-love/solid-use": "workspace:*",
"@winter-love/utils": "workspace:*",
"class-variance-authority": "^0.7.1",
"smplr": "^0.16.1",
"solid-js": "^1.9.3",
"solid-js": "^1.9.4",
"cookie": "^1.0.2",
"js-cookie": "^3.0.5",
"standardized-audio-context": "^25.3.77",
"axios": "1.7.9",
"vinxi": "0.4.3",
"vite": "^5.4.11",
"vite": "^5.2.8",
"workbox-window": "^7.3.0",
"workbox-precaching": "^7.3.0",
"workbox-routing": "^7.3.0",
"workbox-strategies": "^7.3.0",
"workbox-expiration": "^7.3.0"
},
"devDependencies": {
"@winter-love/vite-lib-config": "workspace:*",
"@vitejs/plugin-legacy": "6.0.0",
"@types/js-cookie": "^3.0.6",
"@winter-love/sw": "workspace:*",
"glob": "^11.0.0",
"@types/serviceworker": "^0.0.108",
"@iconify-json/hugeicons": "^1.2.3",
"@iconify-json/tabler": "^1.2.13",
"@unocss/vite": "^0.65.3",
"@vite-pwa/assets-generator": "^0.2.6",
"flush-promises": "^1.0.2",
"typescript": "^5.7.2",
"typescript": "^5.7.3",
"unocss": "^0.65.3",
"vite-plugin-pwa": "^0.21.1",
"vue-tsc": "^2.2.0"
"vue-tsc": "^2.2.0",
"terser": "^5.37.0"
},
"engines": {
"node": ">= 22"
Expand Down
1 change: 1 addition & 0 deletions apps/bplan-client/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'virtual:uno.css'
import './global.css'
import {MetaProvider, Title} from '@solidjs/meta'
import {Router} from '@solidjs/router'
import {FileRoutes} from '@solidjs/start/router'
Expand Down
23 changes: 9 additions & 14 deletions apps/bplan-client/src/ReloadPrompt.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,27 @@
import {JSX, Show} from 'solid-js'
import {Accessor, createEffect, createSignal, JSX, Show, Signal} from 'solid-js'
import {preventGlobalTouchAttrs} from 'src/components/real-button/use-global-touch'
import {useRegisterSW} from 'virtual:pwa-register/solid'
import {getWindow} from '@winter-love/utils'

export interface ReloadPromptProps extends JSX.HTMLAttributes<HTMLDivElement> {
//
}

export const ReloadPrompt = (props: ReloadPromptProps) => {
const {
needRefresh: [needRefresh, setNeedRefresh],
offlineReady: [offlineReady, setOfflineReady],
updateServiceWorker,
} = useRegisterSW({
immediate: true,
onRegisteredSW(swUrl) {
console.info(`Service worker at: ${swUrl}`)
},
const [offlineReady, setOfflineReady] = createSignal(false)
const [needRefresh, setNeedRefresh] = createSignal(false)

createEffect(() => {
})

const handleClose = () => {
setOfflineReady(false)
setNeedRefresh(false)
// setOfflineReady(false)
// setNeedRefresh(false)
}

const handleUpdateServiceWorker = async () => {
console.info('handleUpdateServiceWorker')
handleClose()
await updateServiceWorker()
// await updateServiceWorker()
}

return (
Expand Down
23 changes: 12 additions & 11 deletions apps/bplan-client/src/components/button/HButton.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {JSX} from 'solid-js'
import {JSX, splitProps} from 'solid-js'

export interface HButtonProps
extends Omit<JSX.ButtonHTMLAttributes<HTMLButtonElement>, 'onClick' | 'onTouchEnd'> {
Expand All @@ -25,27 +25,28 @@ export interface HButtonProps
* @prop {JSX.EventHandler<HTMLButtonElement, TouchEvent>} [onTouchEnd] - Event handler for the `touchend` event.
*/
export const HButton = (props: HButtonProps) => {
const [innerProps, restProps] = splitProps(props, ['onClick', 'onTouchEnd'])
/**
* Handles the `click` event for the button component and forwards it to the parent component.
*
* @param event The mouse event triggered by user interaction.
*/
const handleClick: HButtonProps['onClick'] = (event) => {
props.onClick?.(event)
const handleClick: HButtonProps['onClick'] = (event: any) => {
// skip touch
if (event.pointerType === 'touch') {
return
}

innerProps.onClick?.(event)
}

/**
* Handles the `click` or `touch` event for the button component.
*
* @param event The touch event triggered by user interaction.
*/
const handleTouchEnd: HButtonProps['onTouchEnd'] = (event) => {
props.onTouchEnd?.(event)
props.onClick?.(event)
innerProps.onClick?.(event)
innerProps.onTouchEnd?.(event)
}

return (
<button {...props} onClick={handleClick} onTouchEnd={handleTouchEnd}>
<button {...restProps} on:click={handleClick} onTouchEnd={handleTouchEnd}>
{props.children}
</button>
)
Expand Down
14 changes: 7 additions & 7 deletions apps/bplan-client/src/components/midi-player/SClose.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {cva, cx} from 'class-variance-authority'
import {JSX} from 'solid-js'
import {HButton} from 'src/components/button/HButton'
import {preventGlobalTouchAttrs} from 'src/components/real-button/use-global-touch'

export interface SCloseProps extends JSX.HTMLAttributes<HTMLButtonElement> {
Expand Down Expand Up @@ -34,8 +35,8 @@ const rootStyle = cva(
const iconStyle = cva('inline-block text-7 text-white', {
variants: {
isHidden: {
false: 'i-hugeicons:cancel-02',
true: 'i-hugeicons:youtube',
false: 'i-tabler:x',
true: 'i-tabler:playlist',
},
},
})
Expand All @@ -46,7 +47,8 @@ export const SClose = (props: SCloseProps) => {
}

return (
<button
<HButton
{...preventGlobalTouchAttrs()}
class={cx(
rootStyle({
isHidden: Boolean(props.isHidden),
Expand All @@ -56,11 +58,9 @@ export const SClose = (props: SCloseProps) => {
)}
type="button"
onClick={handleClose}
onTouchEnd={handleClose}
title="close midi player"
{...preventGlobalTouchAttrs()}
title={props.isHidden ? 'open midi player' : 'close midi player'}
>
<span class={iconStyle({isHidden: Boolean(props.isHidden)})} />
</button>
</HButton>
)
}
12 changes: 5 additions & 7 deletions apps/bplan-client/src/components/midi-player/SFileItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export interface SFileItemProps
const rootStyle = cx(
'gap-4 p-0 b-0 bg-transparent text-5 flex-shrink-0 h-9 mb-0.3125rem last:mb-0',
'after:bg-gray-300 after:h-.25 first:after:hidden after:content-[""] after:absolute',
'after:top--0.1875rem after:left-0.5rem after:w-[calc(100%-1rem)]',
'after:top--0.1875rem after:left-0.5rem after:w-[calc(100%-1rem)] cursor-pointer',
)
const indexStyle = cva('', {
variants: {
Expand Down Expand Up @@ -110,7 +110,7 @@ export const SFileItem = (props: SFileItemProps) => {
onLeftExecute={handleLeDelete}
dragLeftChildren={
<span class="block w-[calc(100%-0.25rem)] h-full overflow-hidden bg-red p-1 box-border rd-1">
<span class="block w-full h-full i-hugeicons:delete-02 bg-white " />
<span class="block w-full h-full i-tabler:trash bg-white " />
</span>
}
>
Expand All @@ -125,7 +125,7 @@ export const SFileItem = (props: SFileItemProps) => {
<span class="block absolute bg-blue rd-1 top-0 left-0 w-full h-full opacity-40" />
</Show>
<Show when={showPlayingIcon()}>
<span class="block i-hugeicons:arrow-right-double absolute text-gray-500 left-3" />
<span class="block i-tabler:chevrons-right absolute text-gray-500 left-3" />
</Show>
<span class="relative block text-gray b-r-solid b-r-.25 b-r-gray-300 pr-2">
<span class={indexStyle({playing: showPlayingIcon()})}>
Expand All @@ -146,12 +146,10 @@ export const SFileItem = (props: SFileItemProps) => {
</span>
<Show
when={innerProps.inProgress}
fallback={<span class="w-5 h-5 flex-shrink-0" />}
fallback={<span class="w-5 h-5 flex-shrink-0 i-tabler:piano" />}
>
<span class="scale-140 inline-flex origin-center flex-shrink-0">
<span
class={cx('inline-block i-hugeicons:loading-02 text-black', 'animate-spin')}
/>
<span class={cx('inline-block i-tabler:loader-2 text-black', 'animate-spin')} />
</span>
</Show>
<Show when={innerProps.ext && innerProps.ext !== 'midi' && !innerProps.inProgress}>
Expand Down
4 changes: 2 additions & 2 deletions apps/bplan-client/src/components/midi-player/SFileList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export interface SFileListProps
const rootStyle = cva(
cx(
'flex flex-col relative',
'before-i-hugeicons:arrow-down-01 before-absolute before-w-5 before-h-5 before-bottom--1 before-w-full',
'after-i-hugeicons:arrow-up-01 after-absolute after-w-5 after-h-5 after-top--1 after-w-full',
'before-i-tabler:chevron-down before-absolute before-w-5 before-h-5 before-bottom--1 before-w-full',
'after-i-tabler:chevron-up after-absolute after-w-5 after-h-5 after-top--1 after-w-full',
),
{
variants: {
Expand Down
38 changes: 14 additions & 24 deletions apps/bplan-client/src/components/midi-player/SHiddenPlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const rootStyle = cva(
},
},
)
const playerContainerStyle = cva('flex flex-col gap-2', {
const playerContainerStyle = cva('flex flex-col gap-2 overflow-hidden', {
variants: {
isShow: {
false: 'h-0 opacity-0 pointer-events-none',
Expand Down Expand Up @@ -72,35 +72,27 @@ export const SHiddenPlayer = (props: SHiddenPlayerProps) => {
])
const [isShow, setIsShow] = createSignal(false)
const [surfaceKind, setSurfaceKind] = createSignal<SurfaceKind>('player')
const [isRender, setIsRender] = createSignal(false)

const handleClose = () => {
const _isShow = !isShow()
setIsShow((prev) => {
const nextState = !prev

if (_isShow) {
setIsRender(true)
} else {
handleSurfaceKindChange('player')
}
if (nextState) {
handleSurfaceKindChange('player')
}

setIsShow(_isShow)
return nextState
})
}

const isPlaying = createMemo(
() =>
defaultProps.pianoState.playingId !== '' &&
defaultProps.pianoState.leftTime < defaultProps.pianoState.totalDuration &&
!defaultProps.pianoState.suspended,
)

const handleSurfaceKindChange = (kind: SurfaceKind) => {
setSurfaceKind(kind)
}

const handleTransitionEnd = () => {
setIsRender(isShow())
}

// Dynamic component has an error with ssr prefetching hydration
return (
<aside class={props.class ?? 'relative'}>
Expand All @@ -118,15 +110,13 @@ export const SHiddenPlayer = (props: SHiddenPlayerProps) => {
aria-hidden={isShow() ? 'false' : 'true'}
{...preventGlobalTouchAttrs()}
class={rootStyle({isSetting: surfaceKind() === 'setting', isShow: isShow()})}
onTransitionEnd={handleTransitionEnd}
>
<div class={playerContainerStyle({isShow: surfaceKind() !== 'setting'})}>
<Show when={isRender()}>
<SPlayer
{...restProps}
onSetting={() => handleSurfaceKindChange('setting')}
/>
</Show>
<div
class={playerContainerStyle({
isShow: surfaceKind() !== 'setting',
})}
>
<SPlayer {...restProps} onSetting={() => handleSurfaceKindChange('setting')} />
</div>
<Show when={surfaceKind() === 'setting'}>
<SSetting
Expand Down
Loading