diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b069965..c221f42 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,10 +1,5 @@ # Releasing -You can simplify the version bump process by running npm version patch, npm version minor or npm version major after updating minAppVersion manually in manifest.json. The command will bump version in manifest.json and package.json, and add the entry for the new version to versions.json +You can simplify the version bump process by running `npm version patch`, `npm version minor` or `npm version major` after updating minAppVersion manually in manifest.json. The command will bump version in manifest.json and package.json, and add the entry for the new version to versions.json There is an automatic GitHub release workflow in place that gets triggered on a push of a tag. -To push a tag: - -```bash -git tag 1.0.1 -git push origin 1.0.1 -``` +To create a new tag use `git tag 1.0.1` and to push a tag use `git push origin 1.0.1`. diff --git a/README.md b/README.md index 2dbb489..7507765 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,28 @@ # Private Mode -Simple #private mode for [Obsidian](https://obsidian.md/). - -All files, links and search results tagged with #private will get a blurred out in the default mode. You have to either hover over or focus on the element to show it temporarily or use the command "Reveal all" to always show it. +Simple #private mode for [Obsidian](https://obsidian.md/). All files, links and search results tagged with #private will get a blurred out in the default mode. You have to either hover over or focus on the element to show it temporarily or use the command "Reveal all" to always show it. **This plugin requires the obsidian plugin [Supercharged Links](https://github.com/mdelobelle/obsidian_supercharged_links) to work** -![docs/showcase.png](./docs/showcase.png) -*Basic editor view showcasing all the different elements that get blurred (colorful file explorer is custom made and doesn't come with this plugin)* +![docs/img.png](./docs/showcase_1.png) -![docs/showcase_callout.gif](./docs/showcase_callout.gif) -*There is also a callout you can use* +![docs/img_1.png](./docs/showcase_2.png) # Features -* Supported on Obsidian Mobile -* Ribbon Items and Commands to set visibility (also usable on mobile) -* Status bar indicator that shows the current state and can be clicked to toggle visibility -* New callout `private`, which is also blurred and can be collapsed via default Obsidian behaviour for even more "hidden-ness" +* 3️⃣ Three Modes + * Reveal all: to disable the blurring completely + * Reveal on hover: only show #private content on hover (default) + * Reveal never: only show #private content for the currently editing line +* 💻 By default not visible when using screenshare! Keep your secrets :) +* 📱 Supported on Obsidian Mobile +* 🎀 Commands to set visibility (also usable on mobile) +* ✅ Status bar indicator that shows the current state + * left click to cycle visibility + * right click to open the menu + * red means recording and obsidian will be visible in screensharing +* ⌨️ Keyboard shortcuts + * ALT-L cycles visibility + * ALT-SHIFT-L cycles screen share protection +* 💬 Callout `private`, which is also blurred and can be collapsed via default Obsidian behaviour for even more "hidden-ness" ```markdown > [!private]- Optional Title > some text here: diff --git a/docs/showcase.png b/docs/showcase.png deleted file mode 100644 index 2b1cd51..0000000 Binary files a/docs/showcase.png and /dev/null differ diff --git a/docs/showcase_1.png b/docs/showcase_1.png new file mode 100644 index 0000000..859c2df Binary files /dev/null and b/docs/showcase_1.png differ diff --git a/docs/showcase_2.png b/docs/showcase_2.png new file mode 100644 index 0000000..07c3a26 Binary files /dev/null and b/docs/showcase_2.png differ diff --git a/docs/showcase_callout.gif b/docs/showcase_callout.gif deleted file mode 100644 index 0a0cb78..0000000 Binary files a/docs/showcase_callout.gif and /dev/null differ diff --git a/main.ts b/main.ts index 90876cd..205679c 100644 --- a/main.ts +++ b/main.ts @@ -6,6 +6,7 @@ import { addIcon, + Menu, Plugin, setIcon, } from "obsidian"; @@ -19,27 +20,83 @@ enum Level { enum CssClass { RevealAll = "private-mode-reveal-all", RevealOnHover = "private-mode-reveal-on-hover", + UnprotectedScreenshare = "private-mode-unprotected-screenshare" } export default class PrivateModePlugin extends Plugin { statusBar: HTMLElement; statusBarSpan: HTMLSpanElement; currentLevel: Level = Level.RevealOnHover; + currentScreenshareProtection: boolean = true; async onload() { this.statusBar = this.addStatusBarItem(); this.statusBar.addClass("mod-clickable") this.statusBar.ariaLabel = "Toggle Private Mode" this.statusBar.setAttr("data-tooltip-position", "top") - this.statusBar.onClickEvent(() => { - this.cycleCurrentLevel(); - this.updateGlobalRevealStyle(); + this.statusBar.onClickEvent((event) => { + if (event.button != 0) { + const menu = new Menu(); + menu.addItem((item) => + item + .setTitle('Reveal all') + .setIcon('eye') + .setChecked(this.currentLevel == Level.RevealAll) + .onClick(() => { + this.currentLevel = Level.RevealAll + this.updateGlobalRevealStyle(); + }) + ); + menu.addItem((item) => + item + .setTitle('Reveal on hover') + .setIcon('eye-hand') + .setChecked(this.currentLevel == Level.RevealOnHover) + .onClick(() => { + this.currentLevel = Level.RevealOnHover + this.updateGlobalRevealStyle(); + }) + ); + menu.addItem((item) => + item + .setTitle('Reveal never') + .setIcon('eye-closed') + .setChecked(this.currentLevel == Level.HidePrivate) + .onClick(() => { + this.currentLevel = Level.HidePrivate + this.updateGlobalRevealStyle(); + }) + ); + menu.addSeparator() + menu.addItem((item) => + item + .setTitle('Visibility when screensharing') + .setIcon('screencast') + .setChecked(!this.currentScreenshareProtection) + .onClick(() => { + this.currentScreenshareProtection = !this.currentScreenshareProtection; + item.setChecked(!this.currentScreenshareProtection) + this.updateGlobalRevealStyle(); + }) + ); + menu.showAtMouseEvent(event); + } else { + // left click + if (event.altKey) { + this.currentScreenshareProtection = !this.currentScreenshareProtection; + this.updateGlobalRevealStyle(); + } else { + this.cycleCurrentLevel(); + this.updateGlobalRevealStyle(); + } + } }); this.statusBarSpan = this.statusBar.createSpan( { text: "" }); addIcon("eye", eyeIcon); addIcon("eye-hand", eyeHand); addIcon("eye-closed", eyeClosedIcon); + addIcon("screencast", screencastIcon); this.addCommand({ id: "private-mode-hide-private", @@ -81,6 +138,19 @@ export default class PrivateModePlugin extends Plugin { }, }); + this.addCommand({ + id: "private-mode-toggle-screenshare-protection", + name: "Toggle Screenshare protection", + hotkeys: [{ + modifiers: ['Shift', 'Alt'], + key: "L" + }], + callback: () => { + this.currentScreenshareProtection = !this.currentScreenshareProtection + this.updateGlobalRevealStyle(); + }, + }) + this.app.workspace.onLayoutReady(() => { this.updateGlobalRevealStyle(); }); @@ -102,18 +172,23 @@ export default class PrivateModePlugin extends Plugin { updateGlobalRevealStyle() { this.removeAllClasses(); - this.setClassToDocumentBody(this.currentLevel); + this.setClassToDocumentBody(); + window.require("electron").remote.getCurrentWindow().setContentProtection(this.currentScreenshareProtection) } removeAllClasses() { document.body.removeClass( CssClass.RevealAll, - CssClass.RevealOnHover + CssClass.RevealOnHover, + CssClass.UnprotectedScreenshare ); } - setClassToDocumentBody(currentLevel: Level) { - switch (currentLevel) { + setClassToDocumentBody() { + if (!this.currentScreenshareProtection) { + document.body.classList.add(CssClass.UnprotectedScreenshare) + } + switch (this.currentLevel) { case Level.HidePrivate: setIcon(this.statusBarSpan, "eye-closed") break; @@ -138,3 +213,6 @@ const eyeHand = ``; + +// https://icon-sets.iconify.design/ph/screencast/ +const screencastIcon = ``; diff --git a/styles.scss b/styles.scss index f6d23bd..0d9a848 100644 --- a/styles.scss +++ b/styles.scss @@ -55,3 +55,7 @@ body:not(.private-mode-reveal-all) .callout[data-callout="private"]:not(.is-coll body:not(.private-mode-reveal-all) .callout[data-callout="private"]:not(.is-collapsed) > .callout-content:hover { filter: none; } + +body.private-mode-unprotected-screenshare .status-bar-item.plugin-obsidian-private-mode { + color: var(--text-error); +}