Skip to content

Commit

Permalink
Merge pull request #14 from xyhomi3/dev
Browse files Browse the repository at this point in the history
Feature: visualizer, fortmats
  • Loading branch information
xyhomi3 authored Sep 13, 2024
2 parents 8bf1d45 + ec996f6 commit 1ab6882
Show file tree
Hide file tree
Showing 38 changed files with 1,587 additions and 237 deletions.
9 changes: 9 additions & 0 deletions .changeset/gorgeous-lemons-fold.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@omi3/audio': patch
'@omi3/utils': patch
'@omi3/tailwind': patch
'@omi3/ui': patch
'@omi3/site': patch
---

optmisation
9 changes: 9 additions & 0 deletions .changeset/poor-dolls-thank.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@omi3/audio': patch
'@omi3/utils': patch
'@omi3/tailwind': patch
'@omi3/ui': patch
'@omi3/site': patch
---

formating
57 changes: 57 additions & 0 deletions .github/workflows/pr-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: PR Check

on:
pull_request:
branches: [main]

permissions:
contents: write

jobs:
check:
name: Check Changes
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Configure Git
run: |
git config --global user.name 'github-actions[bot]'
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
- name: Setup repository
run: |
git fetch origin main:main
git branch -a
- name: Debug info
run: |
git status
git log --oneline -n 5
git branch -a
- uses: pnpm/action-setup@v2
with:
version: 9.1.1

- uses: actions/setup-node@v4
with:
node-version: 'lts/*'
cache: 'pnpm'

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Check Changesets
run: pnpm changeset status

- name: Dry Run Version Update
run: pnpm changeset version --dry-run --verbose

- name: Debug Git status after changeset
if: failure()
run: |
git status
git diff
17 changes: 4 additions & 13 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ name: Release
on:
push:
branches: [main]
pull_request:
branches: [main]

concurrency: ${{ github.workflow }}-${{ github.ref }}

Expand Down Expand Up @@ -32,21 +30,14 @@ jobs:
node-version: 'lts/*'
cache: 'pnpm'

- run: pnpm install --frozen-lockfile
- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Create Release Pull Request
if: github.event_name == 'pull_request'
- name: Create Release Pull Request or Publish to npm
uses: changesets/action@v1
with:
version: pnpm version-packages
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Publish to npm
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
uses: changesets/action@v1
with:
publish: pnpm release
publish: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' && 'pnpm release' || '' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
119 changes: 64 additions & 55 deletions apps/site/app/_components/audio/player.tsx
Original file line number Diff line number Diff line change
@@ -1,68 +1,64 @@
'use client';

import { Button, Card, CardContent, CardHeader, CardTitle, Progress } from '@omi3/ui';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { AudioChannel, Visualizer } from '@omi3/audio';
import { Button, Card, CardContent, CardHeader, CardTitle, Icons, Slider } from '@omi3/ui';
import { playtime, seek } from '@omi3/utils';
import { useAtomValue, useSetAtom } from 'jotai';
import { useCallback, useMemo } from 'react';

import { AudioChannel } from '@omi3/audio';
import { playtime } from '@omi3/utils';
import AudioVisualizer from './visualizer';

const sampleMusic = {
url: 'https://cdn.pixabay.com/audio/2023/12/29/audio_a1497a53af.mp3',
};
import { audio } from '@/store';

export function AudioPlayer() {
const [audioChannel, setAudioChannel] = useState<AudioChannel | null>(null);
const [isPlaying, setIsPlaying] = useState(false);
const [analyser, setAnalyser] = useState<AnalyserNode | null>(null);
const [currentTime, setCurrentTime] = useState(0);
const [duration, setDuration] = useState(0);
const audioState = useAtomValue(audio.stateAtom);
const analyser = useAtomValue(audio.analyserAtom);
const togglePlayPause = useSetAtom(audio.togglePlayPauseAtom);
const initializeAudioChannel = useSetAtom(audio.initializeAudioChannelAtom);
const seekAudio = useSetAtom(audio.seekAtom);
const setVolume = useSetAtom(audio.setVolumeAtom);

const { playbackState, currentTime, duration, localVolume, isInitialized } = audioState;

const handlePlay = useCallback(() => {
if (!isInitialized) {
initializeAudioChannel();
}
togglePlayPause();
}, [isInitialized, initializeAudioChannel, togglePlayPause]);

const eventHandlers = useMemo(
const audioHandlers = useMemo(
() => ({
onPlay: () => setIsPlaying(true),
onPause: () => setIsPlaying(false),
onEnded: () => setIsPlaying(false),
onAnalyserCreated: (newAnalyser: AnalyserNode) => {
newAnalyser.fftSize = 1024; // ou 2048 pour plus de détails
newAnalyser.smoothingTimeConstant = 0.8;
newAnalyser.minDecibels = -90;
newAnalyser.maxDecibels = -10;
setAnalyser(newAnalyser);
onValueChange: (values: number[]) => {
seekAudio(values[0]);
},
onValueCommit: (values: number[]) => {
if (values.length > 0) {
seekAudio(values[0]);
}
},
onTimeUpdate: (time: number) => setCurrentTime(time),
onDurationChange: (newDuration: number) => setDuration(newDuration),
onStop: () => setIsPlaying(false),
}),
[],
[seekAudio],
);

useEffect(() => {
const channel = AudioChannel.getInstance(eventHandlers);
setAudioChannel(channel);
const volumeHandlers = useMemo(() => seek((newVolume: number) => setVolume(newVolume)), [setVolume]);

return () => {
channel.dispose();
};
}, [eventHandlers]);
useAtomValue(audio.initializeAudioChannelAtom);

const handlePlayPause = useCallback(async () => {
if (!audioChannel) return;
const getVolumeIcon = useCallback(() => {
if (localVolume === 0) return <Icons.VolumeX />;
if (localVolume < 50) return <Icons.Volume1 />;
return <Icons.Volume2 />;
}, [localVolume]);

try {
if (!isPlaying) {
await audioChannel.initialize();
if (!audioChannel.currentMusic) {
await audioChannel.load(sampleMusic);
}
await audioChannel.play();
} else {
audioChannel.pause();
}
} catch (error) {
console.error('Erreur lors de la lecture/pause audio:', error);
const getPlayPauseIcon = useCallback(() => {
switch (playbackState) {
case AudioChannel.PlaybackState.PLAYING:
return <Icons.Pause />;
case AudioChannel.PlaybackState.LOADING:
return <Icons.Loader2 className="animate-spin" />;
default:
return <Icons.Play />;
}
}, [audioChannel, isPlaying]);
}, [playbackState]);

return (
<Card className="w-full">
Expand All @@ -73,16 +69,29 @@ export function AudioPlayer() {
</CardHeader>
<CardContent>
<div className="w-full">
<AudioVisualizer analyser={analyser} width={300} height={150} />
<Visualizer analyser={analyser} width={300} height={150} />
</div>
<Progress value={(currentTime / duration) * 100} className="mt-4" />
<Slider
className="mt-4"
value={[currentTime]}
max={duration}
step={0.1}
onValueChange={audioHandlers.onValueChange}
onValueCommit={audioHandlers.onValueCommit}
/>
<div className="text-text mt-2 flex w-full justify-between text-sm">
<span>{playtime(currentTime)}</span>
<span>{playtime(duration)}</span>
</div>
<Button onClick={handlePlayPause} className="mt-4 w-full">
{isPlaying ? 'Pause' : 'Lecture'}
</Button>
<div className="mt-4 flex items-center justify-between">
<Button size="icon" onClick={handlePlay} disabled={playbackState === AudioChannel.PlaybackState.LOADING}>
{getPlayPauseIcon()}
</Button>
<div className="flex items-center gap-2">
{getVolumeIcon()}
<Slider className="w-32" value={[localVolume]} max={100} step={1} {...volumeHandlers} />
</div>
</div>
</CardContent>
</Card>
);
Expand Down
3 changes: 1 addition & 2 deletions apps/site/app/_components/layout/footer.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
export function Footer() {
return (
<footer className="z-50 flex items-center justify-center p-5">
<footer className="z-50 flex items-center justify-center gap-1 p-5">
© {new Date().getFullYear()}
<a href="https://github.com/xyhomi3" className="text-main">
{' '}
Omi3
</a>
</footer>
Expand Down
10 changes: 10 additions & 0 deletions apps/site/app/_providers/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { ReactNode } from 'react';
import { StoreProvider } from './store';

type Props = {
children: ReactNode;
};

export async function Providers({ children }: Props) {
return <StoreProvider>{children}</StoreProvider>;
}
7 changes: 7 additions & 0 deletions apps/site/app/_providers/store/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
"use client";

import { Provider } from "jotai";

export function StoreProvider({ children }: { children: React.ReactNode }) {
return <Provider>{children}</Provider>;
}
8 changes: 6 additions & 2 deletions apps/site/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import '@omi3/ui/neobrutalism.css';

import { Footer } from './_components/layout/footer';
import type { Metadata } from 'next';
import { Providers } from './_providers';
import { cn } from '@omi3/utils';
import { silk } from '@omi3/ui';

export const metadata: Metadata = {
metadataBase: new URL('https://omi3.dev'),
title: {
template: '%s - Omi3',
default: 'Omi3',
Expand All @@ -21,8 +23,10 @@ export default function RootLayout({
return (
<html lang="en" className="h-full">
<body className={cn(silk.variable, 'font-silk flex min-h-full flex-col antialiased')}>
<main className="flex flex-grow items-center justify-center p-5">{children}</main>
<Footer />
<Providers>
<main className="flex flex-grow items-center justify-center p-5">{children}</main>
<Footer />
</Providers>
</body>
</html>
);
Expand Down
42 changes: 20 additions & 22 deletions apps/site/app/opengraph-image.tsx
Original file line number Diff line number Diff line change
@@ -1,44 +1,42 @@
import { ImageResponse } from "next/og";
import { ImageResponse } from 'next/og';

export const runtime = "edge";
export const alt = "Ouest Labs";
export const runtime = 'edge';
export const alt = 'Ouest Labs';
export const size = {
width: 1200,
height: 630,
};

export default async function Image() {

return new ImageResponse(
(
<div
style={{
height: "100%",
width: "100%",
display: "flex",
textAlign: "center",
alignItems: "center",
justifyContent: "center",
flexDirection: "column",
flexWrap: "nowrap",
backgroundColor: "#111903",
height: '100%',
width: '100%',
display: 'flex',
textAlign: 'center',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'column',
flexWrap: 'nowrap',
backgroundColor: '#111903',
}}
>

<svg width={280} height={80} viewBox="0 0 14 4" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M1.375 4V3.375H0.75V1.5H1.375V0.875H2.625V1.5H3.25V3.375H2.625V4H1.375ZM1.375 3.35H2.625V1.525H1.375V3.35ZM4.5 4V0.875H5.125V1.5H5.75V2.125H6.375V2.75H5.75V2.125H5.125V4H4.5ZM7 4V2.125H6.375V1.5H7V0.875H7.625V4H7ZM8.875 4V0.875H9.5V4H8.875Z"
fill="white"
/>
<path
d="M12.625 2.125V1.5H10.75V0.875H12.625V1.5H13.25V2.125H12.625ZM12.625 3.375V2.75H11.375V2.125H12.625V2.75H13.25V3.375H12.625ZM10.75 4V3.375H12.625V4H10.75Z"
fill="#B0FC31"
fill="white"
/>
<path
d="M12.625 2.125V1.5H10.75V0.875H12.625V1.5H13.25V2.125H12.625ZM12.625 3.375V2.75H11.375V2.125H12.625V2.75H13.25V3.375H12.625ZM10.75 4V3.375H12.625V4H10.75Z"
fill="#B0FC31"
/>
</svg>
</div>
),
{
...size
}
...size,
},
);
}
}
Loading

0 comments on commit 1ab6882

Please sign in to comment.