Skip to content

Commit

Permalink
feat(player): media now prefer open in pinned leaves
Browse files Browse the repository at this point in the history
close #210
  • Loading branch information
aidenlx committed Feb 16, 2024
1 parent ddb1a0f commit 2c28f70
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 53 deletions.
32 changes: 27 additions & 5 deletions apps/app/src/media-note/leaf-open/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ declare module "obsidian" {
interface WorkspaceLeaf {
activeTime: number;
tabHeaderEl: HTMLDivElement;
pinned: boolean;
togglePinned(): void;
}
interface WorkspaceTabGroup {
children: WorkspaceLeaf[];
Expand Down Expand Up @@ -125,21 +127,26 @@ export class LeafOpener extends Component {
if (mediaInfo) {
// if the note is a media note, only accept corresponding media leaves
// don't use the latest media leaf as fallback
const leaf = this.findExistingPlayer(mediaInfo);
const leaf = this.findPlayerWithSameMedia(mediaInfo);
return leaf;
}
}
// for other cases like non-media note, use the latest media leaf as fallback
return fallback();
}

findExistingPlayer(info: MediaInfo): MediaLeaf | null {
findPlayerWithSameMedia(info: MediaInfo): MediaLeaf | null {
for (const type of this.plugin.urlViewType.getSupported(info)) {
const leaves = getMediaLeavesOf(info, type, this.workspace);
if (leaves.length > 0) return leaves[0];
}
return null;
}
findPinnedPlayer(): MediaLeaf | null {
return (
getAllMediaLeaves(this.workspace).filter((leaf) => leaf.pinned)[0] ?? null
);
}

get settings() {
return this.plugin.settings.getState();
Expand Down Expand Up @@ -181,14 +188,22 @@ export class LeafOpener extends Component {
): Promise<MediaLeaf> {
const { workspace } = this.app;
if (!newLeaf) {
const existing = this.#openInExistingPlayer(mediaInfo);
const existing = await this.#openInExistingPlayer(mediaInfo, viewType);
if (existing) return existing;
}

const leaf = workspace.getLeaf(
(noRemap ? newLeaf : this.getSplitBehavior(newLeaf)) as "split",
direction,
);
return this.#openMedia(leaf, mediaInfo, viewType);
}

async #openMedia(
leaf: WorkspaceLeaf,
mediaInfo: MediaInfo,
viewType?: RemoteMediaViewType,
) {
if (isFileMediaInfo(mediaInfo)) {
await leaf.openFile(mediaInfo.file, {
eState: { subpath: mediaInfo.hash },
Expand All @@ -214,8 +229,15 @@ export class LeafOpener extends Component {
return leaf as MediaLeaf;
}

#openInExistingPlayer(info: MediaInfo): MediaLeaf | null {
const opened = this.findExistingPlayer(info);
async #openInExistingPlayer(
info: MediaInfo,
remoteViewType?: RemoteMediaViewType,
): Promise<MediaLeaf | null> {
const pinned = this.findPinnedPlayer();
if (pinned) {
return await this.#openMedia(pinned, info, remoteViewType);
}
const opened = this.findPlayerWithSameMedia(info);
if (opened) {
updateHash(info.hash, opened);
return opened;
Expand Down
47 changes: 24 additions & 23 deletions apps/app/src/media-view/base.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,31 +48,10 @@ export function titleFromUrl(src: string): string {
}

export function addAction(player: PlayerComponent & ItemView) {
function noticeBehavior(action: string) {
const label = "mx:media-notetaking-notified";
const notified = localStorage.getItem(label);
if (notified) return;
new Notice(
createFragment((e) => {
e.appendText(
`You are taking ${action} from media player. By default, they will only be saved in the media note. `,
);
e.createEl("p", {
text: `To take ${action} or control playback from abritrary note, use command when focused on the note`,
});
e.createEl("p", {
text: "PS: you can assign a hotkey to each command in the settings",
});
e.appendText("Click to dismiss this notice.");
}),
0,
);
localStorage.setItem(label, "1");
}
player.addAction("star", "Timestamp", () => {
const info = player.getMediaInfo();
if (!info) return;
noticeBehavior("timestamp");
noticeNotetaking("timestamp");
openOrCreateMediaNote(info, player).then((ctx) => {
takeTimestamp(player, ctx);
});
Expand All @@ -81,13 +60,35 @@ export function addAction(player: PlayerComponent & ItemView) {
player.addAction("camera", "Screenshot", () => {
const info = player.getMediaInfo();
if (!info) return;
noticeBehavior("screenshot");
noticeNotetaking("screenshot");
openOrCreateMediaNote(info, player).then((ctx) =>
saveScreenshot(player, ctx),
);
});
}

function noticeNotetaking(action: string) {
const label = "mx:media-notetaking-notified";
const notified = localStorage.getItem(label);
if (notified) return;
new Notice(
createFragment((e) => {
e.appendText(
`You are taking ${action} from media player. By default, they will only be saved in the media note. `,
);
e.createEl("p", {
text: `To take ${action} or control playback from abritrary note, use command when focused on the note`,
});
e.createEl("p", {
text: "PS: you can assign a hotkey to each command in the settings",
});
e.appendText("Click to dismiss this notice.");
}),
0,
);
localStorage.setItem(label, "1");
}

export function onPaneMenu<
T extends PlayerComponent & {
getViewType(): MediaViewType;
Expand Down
9 changes: 1 addition & 8 deletions apps/app/src/media-view/iframe-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,7 @@ export class MediaEmbedView extends MediaRemoteView {
}
return super.setState(state, result);
}
getState(): MediaRemoteViewState {
const state = super.getState() as MediaRemoteViewState;
const url = this.store.getState().source?.url;
return {
...state,
source: url ? url.jsonState.source : state.source,
};
}

getDisplayText(): string {
const source = hostTitleMap[this.sourceType] ?? "Embed";
if (!this.playerTitle) return source;
Expand Down
9 changes: 9 additions & 0 deletions apps/app/src/media-view/remote-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,15 @@ export abstract class MediaRemoteView
onPaneMenu(this, menu, menuSource);
}

getState(): MediaRemoteViewState {
const state = super.getState() as MediaRemoteViewState;
const url = this.store.getState().source?.url;
return {
...state,
source: url ? url.jsonState.source : state.source,
};
}

setEphemeralState(state: any): void {
if ("subpath" in state) {
const { subpath } = state;
Expand Down
9 changes: 0 additions & 9 deletions apps/app/src/media-view/url-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,6 @@ export type MediaUrlViewState = MediaRemoteViewState;

abstract class MediaUrlView extends MediaRemoteView {
abstract getViewType(): MediaUrlViewType;

getState(): MediaUrlViewState {
const state = super.getState() as MediaUrlViewState;
const url = this.store.getState().source?.url;
return {
...state,
source: url ? url.jsonState.source : state.source,
};
}
}

export class VideoUrlView extends MediaUrlView {
Expand Down
8 changes: 0 additions & 8 deletions apps/app/src/media-view/webpage-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,4 @@ export class MediaWebpageView extends MediaRemoteView {
}
return super.setState(state, result);
}
getState(): MediaWebpageViewState {
const state = super.getState() as MediaWebpageViewState;
const url = this.store.getState().source?.url;
return {
...state,
source: url ? url.jsonState.source : state.source,
};
}
}

0 comments on commit 2c28f70

Please sign in to comment.