mirror of
https://github.com/zoriya/v10.git
synced 2026-08-15 10:23:32 +00:00
feat(monorepo): migrate prototype code to organized package structure
Migrate all prototype code from vjs10-prototype repository into the monorepo structure following established dependency hierarchy and package organization patterns. Core packages migrated: - @vjs-10/media-store: Complete media store with nanostores integration - @vjs-10/playback-engine: HLS.js playback engine implementation - @vjs-10/media: Core media state owner and interfaces HTML packages migrated: - @vjs-10/html-icons: Web component icons with proper base classes - @vjs-10/html-media-elements: Context provider integration - @vjs-10/html: Main HTML UI components, skins, and utilities React packages migrated: - @vjs-10/react-icons: React icon components - @vjs-10/react-media-elements: Video component with state integration - @vjs-10/react-media-store: MediaProvider and React hooks - @vjs-10/react: Main React UI components and skins Changes made: - Updated all imports to use monorepo package names (@vjs-10/*) - Distributed dependencies to specific packages that use them - Preserved all prototype functionality and component structure - Created proper index files for all packages - Fixed workspace protocol usage for npm compatibility 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude
parent
fc5a0e46fd
commit
4b472ec49c
@@ -1,155 +1 @@
|
||||
import { MediaElementLike, createMediaElementAdapter } from '@vjs-10/media';
|
||||
import { PlaybackEngine, NativePlaybackEngine } from '@vjs-10/playback-engine';
|
||||
|
||||
export interface MediaElementOptions {
|
||||
playbackEngine?: PlaybackEngine;
|
||||
controls?: boolean;
|
||||
autoplay?: boolean;
|
||||
preload?: 'none' | 'metadata' | 'auto';
|
||||
}
|
||||
|
||||
export class VjsMediaElement extends HTMLElement {
|
||||
private mediaElement: HTMLVideoElement | HTMLAudioElement;
|
||||
private playbackEngine: PlaybackEngine;
|
||||
private adapter: MediaElementLike;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.attachShadow({ mode: 'open' });
|
||||
|
||||
const mediaType = this.getAttribute('media-type') || 'video';
|
||||
this.mediaElement = mediaType === 'audio'
|
||||
? document.createElement('audio')
|
||||
: document.createElement('video');
|
||||
|
||||
this.playbackEngine = new NativePlaybackEngine();
|
||||
this.adapter = createMediaElementAdapter(this.mediaElement);
|
||||
}
|
||||
|
||||
static get observedAttributes() {
|
||||
return ['src', 'controls', 'autoplay', 'preload', 'media-type'];
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.render();
|
||||
this.setupEventListeners();
|
||||
this.playbackEngine.attach(this.mediaElement);
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
this.playbackEngine.detach();
|
||||
}
|
||||
|
||||
attributeChangedCallback(name: string, oldValue: string, newValue: string) {
|
||||
if (oldValue === newValue) return;
|
||||
|
||||
switch (name) {
|
||||
case 'src':
|
||||
if (newValue) {
|
||||
this.playbackEngine.load({ src: newValue, type: 'video/mp4' });
|
||||
}
|
||||
break;
|
||||
case 'controls':
|
||||
this.mediaElement.controls = newValue !== null;
|
||||
break;
|
||||
case 'autoplay':
|
||||
this.mediaElement.autoplay = newValue !== null;
|
||||
break;
|
||||
case 'preload':
|
||||
this.mediaElement.preload = newValue as any;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private render() {
|
||||
if (!this.shadowRoot) return;
|
||||
|
||||
const styles = `
|
||||
<style>
|
||||
:host {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
video, audio {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
`;
|
||||
|
||||
this.shadowRoot.innerHTML = styles;
|
||||
this.shadowRoot.appendChild(this.mediaElement);
|
||||
}
|
||||
|
||||
private setupEventListeners() {
|
||||
this.mediaElement.addEventListener('play', () => {
|
||||
this.dispatchEvent(new CustomEvent('vjs-play'));
|
||||
});
|
||||
|
||||
this.mediaElement.addEventListener('pause', () => {
|
||||
this.dispatchEvent(new CustomEvent('vjs-pause'));
|
||||
});
|
||||
|
||||
this.mediaElement.addEventListener('timeupdate', () => {
|
||||
this.dispatchEvent(new CustomEvent('vjs-timeupdate', {
|
||||
detail: { currentTime: this.mediaElement.currentTime }
|
||||
}));
|
||||
});
|
||||
|
||||
this.mediaElement.addEventListener('loadedmetadata', () => {
|
||||
this.dispatchEvent(new CustomEvent('vjs-loadedmetadata', {
|
||||
detail: { duration: this.mediaElement.duration }
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
async play() {
|
||||
return this.playbackEngine.play();
|
||||
}
|
||||
|
||||
pause() {
|
||||
this.playbackEngine.pause();
|
||||
}
|
||||
|
||||
seekTo(time: number) {
|
||||
this.playbackEngine.seekTo(time);
|
||||
}
|
||||
|
||||
get currentTime() {
|
||||
return this.adapter.currentTime;
|
||||
}
|
||||
|
||||
set currentTime(value: number) {
|
||||
this.adapter.currentTime = value;
|
||||
}
|
||||
|
||||
get duration() {
|
||||
return this.adapter.duration;
|
||||
}
|
||||
|
||||
get paused() {
|
||||
return this.adapter.paused;
|
||||
}
|
||||
|
||||
get volume() {
|
||||
return this.adapter.volume;
|
||||
}
|
||||
|
||||
set volume(value: number) {
|
||||
this.adapter.volume = value;
|
||||
}
|
||||
|
||||
get muted() {
|
||||
return this.adapter.muted;
|
||||
}
|
||||
|
||||
set muted(value: boolean) {
|
||||
this.adapter.muted = value;
|
||||
}
|
||||
}
|
||||
|
||||
if (!customElements.get('vjs-media')) {
|
||||
customElements.define('vjs-media', VjsMediaElement);
|
||||
}
|
||||
|
||||
export { MediaElementLike, createMediaElementAdapter } from '@vjs-10/media';
|
||||
export * from './media-provider';
|
||||
@@ -0,0 +1,12 @@
|
||||
import { ProviderMixin } from '@open-wc/context-protocol';
|
||||
import { createMediaStore } from '@vjs-10/media-store';
|
||||
|
||||
export class MediaProvider extends ProviderMixin(HTMLElement) {
|
||||
contexts = {
|
||||
mediaStore: () => {
|
||||
return createMediaStore();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
customElements.define('media-provider', MediaProvider);
|
||||
Reference in New Issue
Block a user