Skip to content

Commit

Permalink
added control to allow wake lock only on active MarkdownView
Browse files Browse the repository at this point in the history
  • Loading branch information
blotspot committed Dec 27, 2024
1 parent 888425b commit 0dda1ec
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 61 deletions.
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,27 @@

This is a tniy plugin for [Obsidian](https://obsidian.md).

It's only purpose is to stop your device from dimming or locking the screen. Use it at your own leisure as an always active screen will impact your device battery.
It's only purpose is to stop your device from dimming or locking the screen. Use it at your own leisure, as an always active screen will impact your device battery.

## How it works

WakeLock is released whenever the Obsidian window or app isn't visible and will be requested whenever it is called back to front again.

The functionality can be disabled through a hotkey, command or in the plugin settings page. For mobile devices, the Command can be added to the mobile toolbar by going to `Settings > Toolbar > [Scroll down to bottom] > [Search for "Toggle WakeLock" in the "Add global command" search field]`. The command should then be added to your active toolbar options automatically.
The functionality can be disabled through a hotkey, command or in the plugin settings page.

For mobile devices, the command can be added to the mobile toolbar by going to `Settings > Toolbar > [Scroll down to bottom] > [Search for "Toggle WakeLock" in the "Add global command" search field]`. The command icon will then be added to your active toolbar options automatically.

On desktop devices, the plugin can be configured to show its current status in the status bar. Additionally, it can be enabled or disabled from there too by clicking on the icon.

## Manually installing the plugin

1. Head over to [Releases](https://github.com/blotspot/obsidian-wake-lock/releases/latest).
1. Download and unpack the zip file into `VaultFolder/.obsidian/plugins/` folder.
1. OR Download and copy `main.js`, `styles.css` and `manifest.json` to your vault `VaultFolder/.obsidian/plugins/wake-lock/`.

## Possible Updates
## Future Roadmap

- Allowing WakeLock only when a file is currently edited (actively focused).
- Subsequently, disable WakeLock to trigger through a frontmatter code
- Added setting options (like, global WakeLock (current functionality) or editing WakeLock (see above))
- Allow files to disable WakeLock through a frontmatter code

## Compatability

Expand Down
116 changes: 86 additions & 30 deletions main.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { Notice, Plugin } from "obsidian";
import { MarkdownView, Notice, Plugin, WorkspaceLeaf } from "obsidian";
import { WakeLock } from "./src/wake-lock";
import { WakeLockStatusBarItem } from "./src/statusbar";
import { Log } from "./src/log";
import { WakeLockPluginSettings } from "./src/settings";
import {
WakeLockPluginSettings,
WakeLockPluginSettingsData,
} from "./src/settings";

export default class WakeLockPlugin extends Plugin {
private settings: WakeLockPluginSettings;
Expand Down Expand Up @@ -45,41 +48,15 @@ export default class WakeLockPlugin extends Plugin {
this.unregisterDomEvents();
}

private updateWakeLockState(isActive: boolean) {
if (isActive) {
this.notice("WakeLock enabled!");
this.enableWakeLock();
} else {
this.notice("WakeLock disabled!");
this.disableWakeLock();
}
}

private updateStatusBarVisibility(showInStatusBar: boolean) {
this.statusBarItem.setVisible(showInStatusBar);
}

private async initSettings() {
this.settings = await WakeLockPluginSettings.load(this);
this.settings.addEventListener("active", (ev) => {
this.updateWakeLockState(ev.detail);
});
this.settings.addEventListener("showInStatusBar", (ev) => {
this.updateStatusBarVisibility(ev.detail);
});
}

private initWakeLock() {
if (this.settings.data.isActive) {
this.enableWakeLock();
}
this.wakeLock.addEventListener("request", () => {
this.notice("WakeLock on.");
this.statusBarItem.switch(true);
});
this.wakeLock.addEventListener("release", () => {
this.statusBarItem.switch(false);
});
this.setWakeLockState(this.settings.data);
}

private toggleIsActive = () => {
Expand All @@ -99,7 +76,62 @@ export default class WakeLockPlugin extends Plugin {
private initStatusBar() {
this.statusBarItem = new WakeLockStatusBarItem(this.addStatusBarItem());
this.statusBarItem.addEventListener("click", this.toggleIsActive);
this.updateStatusBarVisibility(this.settings.data.showInStatusBar);
this.setStatusBarVisibility(this.settings.data.showInStatusBar);
}

private setWakeLockState(currentSettings: WakeLockPluginSettingsData) {
if (currentSettings.isActive) {
this.notice("WakeLock enabled!");
currentSettings.triggerOnActiveEditorView
? this.setActiveEditorTrigger(currentSettings)
: this.enableWakeLock();
} else {
this.notice("WakeLock disabled!");
this.disableWakeLock();
if (currentSettings.triggerOnActiveEditorView) {
this.unregisterEditorTrigger();
}
}
}

private setWakeLockStateBasedOnActiveView() {
const activeView = this.app.workspace.getActiveViewOfType(MarkdownView);
this.onActiveMarkdownView(
activeView === null
? null
: ({ view: activeView } as unknown as WorkspaceLeaf)
);
}

private setStatusBarVisibility(showInStatusBar: boolean) {
this.statusBarItem.setVisible(showInStatusBar);
}

private setActiveEditorTrigger(
currentSettings: WakeLockPluginSettingsData
) {
if (currentSettings.triggerOnActiveEditorView) {
this.setWakeLockStateBasedOnActiveView();
this.registerEditorTriggers();
} else {
if (currentSettings.isActive && !this.wakeLock.active()) {
this.enableWakeLock();
}
this.unregisterEditorTrigger();
}
}

private async initSettings() {
this.settings = await WakeLockPluginSettings.load(this);
this.settings.addEventListener("active", (ev) => {
this.setWakeLockState(ev.detail);
});
this.settings.addEventListener("showInStatusBar", (ev) => {
this.setStatusBarVisibility(ev.detail.showInStatusBar);
});
this.settings.addEventListener("triggerOnActiveEditorView", (ev) => {
this.setActiveEditorTrigger(ev.detail);
});
}

private onDocumentVisibilityChange = () => {
Expand All @@ -111,6 +143,30 @@ export default class WakeLockPlugin extends Plugin {
}
};

private onActiveMarkdownView = (leaf: WorkspaceLeaf | null) => {
if (
this.settings.data.isActive &&
leaf?.view instanceof MarkdownView &&
!this.wakeLock.active()
) {
this.enableWakeLock();
} else if (
this.settings.data.isActive &&
!(leaf?.view instanceof MarkdownView) &&
this.wakeLock.active()
) {
this.disableWakeLock();
}
};

private registerEditorTriggers() {
this.app.workspace.on("active-leaf-change", this.onActiveMarkdownView);
}

private unregisterEditorTrigger() {
this.app.workspace.off("active-leaf-change", this.onActiveMarkdownView);
}

private registerDomEvents() {
this.registerDomEvent(
document,
Expand Down
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "screen-wake-lock",
"name": "Screen WakeLock",
"version": "1.0.2",
"version": "1.0.3",
"minAppVersion": "0.15.0",
"description": "Allows to keep a wake lock on the display, using the w3 WakeLock API.",
"author": "blotspot",
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "obsidian-sample-plugin",
"version": "1.0.0",
"description": "This is a sample plugin for Obsidian (https://obsidian.md)",
"name": "screen-wake-lock",
"version": "1.0.3",
"description": "Allows to keep a wake lock on the display, using the w3 WakeLock API.",
"main": "main.js",
"scripts": {
"dev": "node esbuild.config.mjs",
Expand Down
48 changes: 30 additions & 18 deletions src/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import { App, PluginSettingTab, Setting } from "obsidian";
import WakeLockPlugin from "../main";

interface SettingsEventMap {
active: CustomEvent<boolean>;
hideNotifications: CustomEvent<boolean>;
showInStatusBar: CustomEvent<boolean>;
active: CustomEvent<WakeLockPluginSettingsData>;
hideNotifications: CustomEvent<WakeLockPluginSettingsData>;
showInStatusBar: CustomEvent<WakeLockPluginSettingsData>;
triggerOnActiveEditorView: CustomEvent<WakeLockPluginSettingsData>;
}

interface SettingsEventTarget extends EventTarget {
Expand Down Expand Up @@ -43,34 +44,32 @@ export class WakeLockPluginSettings extends TypedEventTarget {
this.context = context;
}

private customEvent(eventName: string) {
this.dispatchEvent(new CustomEvent(eventName, { detail: this.data }));
}

async updateIsActive(isActive: boolean) {
this.data.isActive = isActive;
await this.save();
this.dispatchEvent(
new CustomEvent("active", {
detail: isActive,
})
);
this.customEvent("active");
}

async updateHideNotifications(hideNotifications: boolean) {
this.data.hideNotifications = hideNotifications;
await this.save();
this.dispatchEvent(
new CustomEvent("hideNotifications", {
detail: hideNotifications,
})
);
this.customEvent("hideNotifications");
}

async updateShowInStatusbar(showInStatusBar: boolean) {
this.data.showInStatusBar = showInStatusBar;
await this.save();
this.dispatchEvent(
new CustomEvent("showInStatusBar", {
detail: showInStatusBar,
})
);
this.customEvent("showInStatusBar");
}

async updateTriggerOnActiveEditor(triggerOnActiveEditorView: boolean) {
this.data.triggerOnActiveEditorView = triggerOnActiveEditorView;
await this.save();
this.customEvent("triggerOnActiveEditorView");
}

/**
Expand All @@ -96,12 +95,14 @@ export interface WakeLockPluginSettingsData {
isActive: boolean;
hideNotifications: boolean;
showInStatusBar: boolean;
triggerOnActiveEditorView: boolean;
}

export const DEFAULT_SETTINGS: WakeLockPluginSettingsData = {
isActive: true,
hideNotifications: false,
showInStatusBar: true,
triggerOnActiveEditorView: false,
};

export class WakeLockSettingsTab extends PluginSettingTab {
Expand Down Expand Up @@ -132,6 +133,17 @@ export class WakeLockSettingsTab extends PluginSettingTab {
})
);

new Setting(containerEl)
.setName("Only activate on active editor view.")
.setDesc("Will only set a WakeLock when the editor is focused.")
.addToggle((toggle) =>
toggle
.setValue(this.settings.data.triggerOnActiveEditorView)
.onChange(async (value) => {
this.settings.updateTriggerOnActiveEditor(value);
})
);

new Setting(containerEl)
.setName("Hide Notifications")
.setDesc(
Expand Down
10 changes: 7 additions & 3 deletions src/statusbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,14 @@ export class WakeLockStatusBarItem extends TypedEventTarget {
}

setVisible(visible: boolean) {
if (visible && this.el.classList.contains(HIDE_CLASS)) {
this.el.classList.remove(HIDE_CLASS);
if (visible) {
if (this.el.classList.contains(HIDE_CLASS)) {
this.el.classList.remove(HIDE_CLASS);
}
} else {
this.el.classList.add(HIDE_CLASS);
if (!this.el.classList.contains(HIDE_CLASS)) {
this.el.classList.add(HIDE_CLASS);
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/wake-lock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ export class WakeLock extends TypedEventTarget {
}
}

active = () => {
return this.wakeLock !== null;
};

/**
* Request a new WakeLockSentinel from the wake lock API if none is currently active,
* and store it for later release.
Expand Down

0 comments on commit 0dda1ec

Please sign in to comment.