Skip to content

Commit

Permalink
fix: fix bugs in MPRIS, and improve MPRIS (#1760)
Browse files Browse the repository at this point in the history
Co-authored-by: JellyBrick <[email protected]>
Co-authored-by: Totto <[email protected]>
  • Loading branch information
JellyBrick and Totto16 authored Feb 20, 2024
1 parent 8bd05f5 commit d37cd24
Show file tree
Hide file tree
Showing 15 changed files with 516 additions and 300 deletions.
4 changes: 3 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,9 @@ app.whenReady().then(async () => {
);
}

handleProtocol(command);
const splited = decodeURIComponent(command).split(' ');

handleProtocol(splited.shift()!, splited);
return;
}

Expand Down
3 changes: 2 additions & 1 deletion src/plugins/music-together/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { t } from '@/i18n';
import { createPlugin } from '@/utils';
import promptOptions from '@/providers/prompt-options';

import { type AppElement, getDefaultProfile, type Permission, type Profile, type VideoData } from './types';
import { getDefaultProfile, type Permission, type Profile, type VideoData } from './types';
import { Queue } from './queue';
import { Connection, type ConnectionEventUnion } from './connection';
import { createHostPopup } from './ui/host';
Expand All @@ -19,6 +19,7 @@ import style from './style.css?inline';
import type { YoutubePlayer } from '@/types/youtube-player';
import type { RendererContext } from '@/types/contexts';
import type { VideoDataChanged } from '@/types/video-data-changed';
import type { AppElement } from '@/types/queue';

type RawAccountData = {
accountName: {
Expand Down
3 changes: 2 additions & 1 deletion src/plugins/music-together/queue/queue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import { mapQueueItem } from './utils';
import { t } from '@/i18n';

import type { ConnectionEventUnion } from '@/plugins/music-together/connection';
import type { Profile, QueueElement, VideoData } from '../types';
import type { Profile, VideoData } from '../types';
import type { QueueItem } from '@/types/datahost-get-state';
import type { QueueElement } from '@/types/queue';

const getHeaderPayload = (() => {
let payload: {
Expand Down
41 changes: 0 additions & 41 deletions src/plugins/music-together/types.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,3 @@
import type { YoutubePlayer } from '@/types/youtube-player';
import type { GetState, QueueItem } from '@/types/datahost-get-state';

type StoreState = GetState;
type Store = {
dispatch: (obj: {
type: string;
payload?: {
items?: QueueItem[];
};
}) => void;

getState: () => StoreState;
replaceReducer: (param1: unknown) => unknown;
subscribe: (callback: () => void) => unknown;
}

export type QueueElement = HTMLElement & {
dispatch(obj: {
type: string;
payload?: unknown;
}): void;
queue: QueueAPI;
};
export type QueueAPI = {
getItems(): unknown[];
store: {
store: Store,
};
continuation?: string;
autoPlaying?: boolean;
};
export type AppElement = HTMLElement & AppAPI;
export type AppAPI = {
queue_: QueueAPI;
playerApi_: YoutubePlayer;
openToast: (message: string) => void;

// TODO: Add more
};

export type Profile = {
id: string;
handleId: string;
Expand Down
4 changes: 2 additions & 2 deletions src/plugins/notifications/interactive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,9 +307,9 @@ export default (
savedNotification?.close();
});

changeProtocolHandler((cmd) => {
changeProtocolHandler((cmd, args) => {
if (Object.keys(songControls).includes(cmd)) {
songControls[cmd as keyof typeof songControls]();
songControls[cmd as keyof typeof songControls](args as never);
if (
config().refreshOnPlayPause &&
(cmd === 'pause' || (cmd === 'play' && !config().unpauseNotification))
Expand Down
110 changes: 93 additions & 17 deletions src/plugins/shortcuts/mpris-service.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ declare module '@jellybrick/mpris-service' {
import { interface as dbusInterface } from 'dbus-next';

interface RootInterfaceOptions {
identity: string;
supportedUriSchemes: string[];
supportedMimeTypes: string[];
desktopEntry: string;
identity?: string;
supportedUriSchemes?: string[];
supportedMimeTypes?: string[];
desktopEntry?: string;
}

export interface Track {
Expand Down Expand Up @@ -35,6 +35,32 @@ declare module '@jellybrick/mpris-service' {
'xesam:userRating'?: number;
}

export type PlayBackStatus = 'Playing' | 'Paused' | 'Stopped';

export type LoopStatus = 'None' | 'Track' | 'Playlist';

export const PLAYBACK_STATUS_PLAYING: 'Playing';
export const PLAYBACK_STATUS_PAUSED: 'Paused';
export const PLAYBACK_STATUS_STOPPED: 'Stopped';

export const LOOP_STATUS_NONE: 'None';
export const LOOP_STATUS_TRACK: 'Track';
export const LOOP_STATUS_PLAYLIST: 'Playlist';

export type Interfaces = 'player' | 'trackList' | 'playlists';

export interface AdditionalPlayerOptions {
name: string;
supportedInterfaces: Interfaces[];
}

export type PlayerOptions = RootInterfaceOptions & AdditionalPlayerOptions;

export interface Position {
trackId: string;
position: number;
}

declare class Player extends EventEmitter {
constructor(opts: {
name: string;
Expand All @@ -43,18 +69,44 @@ declare module '@jellybrick/mpris-service' {
supportedInterfaces?: string[];
});

//RootInterface
on(event: 'quit', listener: () => void): this;
on(event: 'raise', listener: () => void): this;
on(
event: 'fullscreen',
listener: (fullscreenEnabled: boolean) => void,
): this;

emit(type: string, ...args: unknown[]): unknown;

name: string;
identity: string;
fullscreen: boolean;
fullscreen?: boolean;
supportedUriSchemes: string[];
supportedMimeTypes: string[];
canQuit: boolean;
canRaise: boolean;
canSetFullscreen: boolean;
canSetFullscreen?: boolean;
desktopEntry?: string;
hasTrackList: boolean;
desktopEntry: string;
playbackStatus: string;
loopStatus: string;

// PlayerInterface
on(event: 'next', listener: () => void): this;
on(event: 'previous', listener: () => void): this;
on(event: 'pause', listener: () => void): this;
on(event: 'playpause', listener: () => void): this;
on(event: 'stop', listener: () => void): this;
on(event: 'play', listener: () => void): this;
on(event: 'seek', listener: (offset: number) => void): this;
on(event: 'open', listener: ({ uri: string }) => void): this;
on(event: 'loopStatus', listener: (status: LoopStatus) => void): this;
on(event: 'rate', listener: () => void): this;
on(event: 'shuffle', listener: (enableShuffle: boolean) => void): this;
on(event: 'volume', listener: (newVolume: number) => void): this;
on(event: 'position', listener: (position: Position) => void): this;

playbackStatus: PlayBackStatus;
loopStatus: LoopStatus;
shuffle: boolean;
metadata: Track;
volume: number;
Expand All @@ -67,9 +119,40 @@ declare module '@jellybrick/mpris-service' {
rate: number;
minimumRate: number;
maximumRate: number;
playlists: unknown[];

abstract getPosition(): number;

seeked(position: number): void;

// TracklistInterface
on(event: 'addTrack', listener: () => void): this;
on(event: 'removeTrack', listener: () => void): this;
on(event: 'goTo', listener: () => void): this;

tracks: Track[];
canEditTracks: boolean;

on(event: '*', a: unknown[]): this;

addTrack(track: string): void;

removeTrack(trackId: string): void;

// PlaylistsInterface
on(event: 'activatePlaylist', listener: () => void): this;

playlists: Playlist[];
activePlaylist: string;

setPlaylists(playlists: Playlist[]): void;

setActivePlaylist(playlistId: string): void;

// Player methods
constructor(opts: PlayerOptions);

on(event: 'error', listener: (error: Error) => void): this;

init(opts: RootInterfaceOptions): void;

objectPath(subpath?: string): string;
Expand All @@ -91,13 +174,6 @@ declare module '@jellybrick/mpris-service' {
setPlaylists(playlists: Track[]): void;

setActivePlaylist(playlistId: string): void;

static PLAYBACK_STATUS_PLAYING: 'Playing';
static PLAYBACK_STATUS_PAUSED: 'Paused';
static PLAYBACK_STATUS_STOPPED: 'Stopped';
static LOOP_STATUS_NONE: 'None';
static LOOP_STATUS_TRACK: 'Track';
static LOOP_STATUS_PLAYLIST: 'Playlist';
}

interface MprisInterface extends dbusInterface.Interface {
Expand Down
Loading

0 comments on commit d37cd24

Please sign in to comment.