Complete v0.3.1

This commit is contained in:
iOSonntag 2023-09-23 05:27:29 +02:00
parent 458baa9bf8
commit fa5c2aeb11
No known key found for this signature in database
21 changed files with 517 additions and 167 deletions

View file

@ -6,5 +6,5 @@ charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = tab
indent_size = 4
tab_width = 4
indent_size = 2
tab_width = 2

38
.github/workflows/release.yml vendored Normal file
View file

@ -0,0 +1,38 @@
name: Release Obsidian plugin
on:
push:
tags:
- "*"
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: "18.x"
- uses: pnpm/action-setup@v2
with:
version: 8
- name: Build plugin
run: |
pnpm install
pnpm run build
- name: Create release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
tag="${GITHUB_REF#refs/tags/}"
gh release create "$tag" \
--title="$tag" \
--draft \
main.js manifest.json styles.css

109
README.md
View file

@ -1,96 +1,57 @@
# Obsidian Sample Plugin
# Obsidian Plugin: TreeFocus
This is a sample plugin for Obsidian (https://obsidian.md).
Highlight, dim & style your files & folders in the file explorer (navigation)
based on predefined or custom rules.
This project uses Typescript to provide type checking and documentation.
The repo depends on the latest plugin API (obsidian.d.ts) in Typescript Definition format, which contains TSDoc comments describing what it does.
> Also works in combination with `obsidian-iconize` / `obsidian-icon-folder` plugin! Hurray 🕺 🎊 🎉 !
**Note:** The Obsidian API is still in early alpha and is subject to change at any time!
## Example Result
<img src="resources/treefocus_01.png?raw=true" width="200">
This sample plugin demonstrates some of the basic functionality the plugin API can do.
- Adds a ribbon icon, which shows a Notice when clicked.
- Adds a command "Open Sample Modal" which opens a Modal.
- Adds a plugin setting tab to the settings page.
- Registers a global click event and output 'click' to the console.
- Registers a global interval which logs 'setInterval' to the console.
<br/>
The screenshot is a result of choosing the Transformation Theme `Fancy` and
based on the following rules:
## First time developing plugins?
<br/>
Quick starting guide for new plugin devs:
- Check if [someone already developed a plugin for what you want](https://obsidian.md/plugins)! There might be an existing plugin similar enough that you can partner up with.
- Make a copy of this repo as a template with the "Use this template" button (login to GitHub if you don't see it).
- Clone your repo to a local development folder. For convenience, you can place this folder in your `.obsidian/plugins/your-plugin-name` folder.
- Install NodeJS, then run `npm i` in the command line under your repo folder.
- Run `npm run dev` to compile your plugin from `main.ts` to `main.js`.
- Make changes to `main.ts` (or create new `.ts` files). Those changes should be automatically compiled into `main.js`.
- Reload Obsidian to load the new version of your plugin.
- Enable plugin in settings window.
- For updates to the Obsidian API run `npm update` in the command line under your repo folder.
- activate `DIM` mode on all files / folders starting with `"_"`
- explicitly activate mode `HIGHLIGHT` on:
- `/Backend`
- `/More`
## Releasing new releases
- Update your `manifest.json` with your new version number, such as `1.0.1`, and the minimum Obsidian version required for your latest release.
- Update your `versions.json` file with `"new-plugin-version": "minimum-obsidian-version"` so older versions of Obsidian can download an older version of your plugin that's compatible.
- Create new GitHub release using your new version number as the "Tag version". Use the exact version number, don't include a prefix `v`. See here for an example: https://github.com/obsidianmd/obsidian-sample-plugin/releases
- Upload the files `manifest.json`, `main.js`, `styles.css` as binary attachments. Note: The manifest.json file must be in two places, first the root path of your repository and also in the release.
- Publish the release.
## Settings
> 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 configure the behavior of this plugin by either defining general rules
or explicitly set the transformation mode per file / folder.
## Adding your plugin to the community plugin list
<img src="resources/settings_01.png?raw=true" width="400">
- Check https://github.com/obsidianmd/obsidian-releases/blob/master/plugin-review.md
- Publish an initial version.
- Make sure you have a `README.md` file in the root of your repo.
- Make a pull request at https://github.com/obsidianmd/obsidian-releases to add your plugin.
## How to use
## Bugs
- Clone this repo.
- Make sure your NodeJS is at least v16 (`node --version`).
- `npm i` or `yarn` to install dependencies.
- `npm run dev` to start compilation in watch mode.
Report bugs at: [TreeFocus - GitHub Repository](https://github.com/iOSonntag/obsidian-plugin-treefocus/issues)
## Manually installing the plugin
- Copy over `main.js`, `styles.css`, `manifest.json` to your vault `VaultFolder/.obsidian/plugins/your-plugin-id/`.
## Contribution
## Improve code quality with eslint (optional)
- [ESLint](https://eslint.org/) is a tool that analyzes your code to quickly find problems. You can run ESLint against your plugin to find common bugs and ways to improve your code.
- To use eslint with this project, make sure to install eslint from terminal:
- `npm install -g eslint`
- To use eslint to analyze this project use this command:
- `eslint main.ts`
- eslint will then create a report with suggestions for code improvement by file and line number.
- If your source code is in a folder, such as `src`, you can use eslint with this command to analyze all files in that folder:
- `eslint .\src\`
Pull requests are **WELCOME** !
## Funding URL
> If you have improvements or feel like you can solve a bug, please do not
> hesitate to submit a pull requests. Even if you think you might not be skilled
> enough. That's pure bullsh*t. We are all beginners - all the time :)
You can include funding URLs where people who use your plugin can financially support it.
## Support
The simple way is to set the `fundingUrl` field to your link in your `manifest.json` file:
If you find this useful - feel free to buy me a coffee :)
```json
{
"fundingUrl": "https://buymeacoffee.com"
}
```
<a href="https://www.buymeacoffee.com/iOSonntag" target="_blank"><img
src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A
Coffee" style="height: 60px !important;width: 217px !important;" ></a>
If you have multiple URLs, you can also do:
```json
{
"fundingUrl": {
"Buy Me a Coffee": "https://buymeacoffee.com",
"GitHub Sponsor": "https://github.com/sponsors",
"Patreon": "https://www.patreon.com/"
}
}
```
## API Documentation
See https://github.com/obsidianmd/obsidian-api
or direct via
- [Buy Me A Coffee](https://www.buymeacoffee.com/iOSonntag)
- [GitHub Sponsor](https://github.com/sponsors/iOSonntag)
- [PayPal](https://paypal.com/paypalme/iOSonntag/20)
- [Homepage](https://iOSonntag.com/buy-me-a-coffe)

View file

@ -2,7 +2,7 @@ import { App, FileExplorer, Menu, PluginManifest, TAbstractFile, WorkspaceLeaf }
import { pluginMetaData } from 'src/_config/meta';
import { TreeFocus } from 'src/core/tree-focus';
import { ObsidianPlugin } from 'src/enhanced-obsidian-components/obsidian-plugin';
import { FILE_EXPLORER_TYPE } from 'src/enhanced-obsidian-components/view-types';
import { SOURCE_TYPE_FILE_EXPLORER_CONTEXT_MENU, VIEW_TYPE_FILE_EXPLORER } from 'src/enhanced-obsidian-components/known-type-keys';
import { Log } from 'src/util/logger';
export default class TreeFocusPlugin extends ObsidianPlugin {
@ -42,7 +42,7 @@ export default class TreeFocusPlugin extends ObsidianPlugin {
getFileExplorers(): FileExplorer[]
{
let list = this.app.workspace.getLeavesOfType(FILE_EXPLORER_TYPE);
let list = this.app.workspace.getLeavesOfType(VIEW_TYPE_FILE_EXPLORER);
return list.map((leaf) => leaf.view as FileExplorer);
}
@ -57,6 +57,11 @@ export default class TreeFocusPlugin extends ObsidianPlugin {
onFileMenu(menu: Menu, file: TAbstractFile, source: string, leaf?: WorkspaceLeaf): any
{
Log.eventFired('workspace.file-menu');
Log.debug('menu', menu, 'file', file, 'source', source, 'leaf', leaf);
if (source !== SOURCE_TYPE_FILE_EXPLORER_CONTEXT_MENU) return;
this.treeFocus.onOpenFileExplorerContextMenu(menu, file);
}

View file

@ -1,11 +1,16 @@
{
"id": "treefocus",
"name": "TreeFocus",
"version": "0.8.1",
"version": "0.3.1",
"minAppVersion": "1.2.0",
"description": "Highlight, dim & style your files & folders in the file explorer (navigation) based on predefined or custom rules.",
"author": "iOSonntag",
"authorUrl": "https://iOSonntag.com",
"fundingUrl": "https://iOSonntag.com/buy-me-a-coffee",
"isDesktopOnly": false
"isDesktopOnly": false,
"fundingUrl": {
"Buy Me a Coffee": "https://www.buymeacoffee.com/iOSonntag",
"GitHub Sponsor": "https://github.com/sponsors/iOSonntag",
"PayPal": "https://paypal.com/paypalme/iOSonntag/20",
"Homepage": "https://iOSonntag.com/buy-me-a-coffee"
}
}

View file

@ -1,7 +1,7 @@
{
"name": "obsidian-sample-plugin",
"version": "1.0.0",
"description": "This is a sample plugin for Obsidian (https://obsidian.md)",
"name": "obsidian-treefocus",
"version": "0.3.1",
"description": "Obsidian plugin: Highlight, dim & style your files & folders in the file explorer (navigation) based on predefined or custom rules.",
"main": "main.js",
"scripts": {
"dev": "node esbuild.config.mjs",
@ -20,5 +20,8 @@
"obsidian": "latest",
"tslib": "2.4.0",
"typescript": "4.7.4"
},
"dependencies": {
"deepmerge": "^4.3.1"
}
}

View file

@ -4,16 +4,21 @@ settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
dependencies:
deepmerge:
specifier: ^4.3.1
version: 4.3.1
devDependencies:
'@types/node':
specifier: ^16.11.6
version: 16.11.6
'@typescript-eslint/eslint-plugin':
specifier: 5.29.0
version: 5.29.0(@typescript-eslint/parser@5.29.0)(eslint@8.49.0)(typescript@4.7.4)
version: 5.29.0(@typescript-eslint/parser@5.29.0)(eslint@8.50.0)(typescript@4.7.4)
'@typescript-eslint/parser':
specifier: 5.29.0
version: 5.29.0(eslint@8.49.0)(typescript@4.7.4)
version: 5.29.0(eslint@8.50.0)(typescript@4.7.4)
builtin-modules:
specifier: 3.3.0
version: 3.3.0
@ -22,7 +27,7 @@ devDependencies:
version: 0.17.3
obsidian:
specifier: latest
version: 1.4.11(@codemirror/state@6.2.1)(@codemirror/view@6.19.0)
version: 1.4.11(@codemirror/state@6.2.1)(@codemirror/view@6.20.1)
tslib:
specifier: 2.4.0
version: 2.4.0
@ -41,8 +46,8 @@ packages:
resolution: {integrity: sha512-RupHSZ8+OjNT38zU9fKH2sv+Dnlr8Eb8sl4NOnnqz95mCFTZUaiRP8Xv5MeeaG0px2b8Bnfe7YGwCV3nsBhbuw==}
dev: true
/@codemirror/view@6.19.0:
resolution: {integrity: sha512-XqNIfW/3GaaF+T7Q1jBcRLCPm1NbrR2DBxrXacSt1FG+rNsdsNn3/azAfgpUoJ7yy4xgd8xTPa3AlL+y0lMizQ==}
/@codemirror/view@6.20.1:
resolution: {integrity: sha512-eeLmPgW+/70PBzPLABaeZZA69yweoHl1jga1Oszv2XjG/yEWheJTIpdWHZHwEERe5IIZJpUsvvRk6uWHnPIJ3w==}
dependencies:
'@codemirror/state': 6.2.1
style-mod: 4.1.0
@ -247,13 +252,13 @@ packages:
dev: true
optional: true
/@eslint-community/eslint-utils@4.4.0(eslint@8.49.0):
/@eslint-community/eslint-utils@4.4.0(eslint@8.50.0):
resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
dependencies:
eslint: 8.49.0
eslint: 8.50.0
eslint-visitor-keys: 3.4.3
dev: true
@ -269,7 +274,7 @@ packages:
ajv: 6.12.6
debug: 4.3.4
espree: 9.6.1
globals: 13.21.0
globals: 13.22.0
ignore: 5.2.4
import-fresh: 3.3.0
js-yaml: 4.1.0
@ -279,8 +284,8 @@ packages:
- supports-color
dev: true
/@eslint/js@8.49.0:
resolution: {integrity: sha512-1S8uAY/MTJqVx0SC4epBq+N2yhuwtNwLbJYNZyhL2pO1ZVKn5HFXav5T41Ryzy9K9V7ZId2JB2oy/W4aCd9/2w==}
/@eslint/js@8.50.0:
resolution: {integrity: sha512-NCC3zz2+nvYd+Ckfh87rA47zfu2QsQpvc6k1yzTk+b9KzRj0wkGa8LSoGOXN6Zv4lRf/EIoZ80biDh9HOI+RNQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true
@ -349,7 +354,7 @@ packages:
'@types/estree': 1.0.1
dev: true
/@typescript-eslint/eslint-plugin@5.29.0(@typescript-eslint/parser@5.29.0)(eslint@8.49.0)(typescript@4.7.4):
/@typescript-eslint/eslint-plugin@5.29.0(@typescript-eslint/parser@5.29.0)(eslint@8.50.0)(typescript@4.7.4):
resolution: {integrity: sha512-kgTsISt9pM53yRFQmLZ4npj99yGl3x3Pl7z4eA66OuTzAGC4bQB5H5fuLwPnqTKU3yyrrg4MIhjF17UYnL4c0w==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
@ -360,12 +365,12 @@ packages:
typescript:
optional: true
dependencies:
'@typescript-eslint/parser': 5.29.0(eslint@8.49.0)(typescript@4.7.4)
'@typescript-eslint/parser': 5.29.0(eslint@8.50.0)(typescript@4.7.4)
'@typescript-eslint/scope-manager': 5.29.0
'@typescript-eslint/type-utils': 5.29.0(eslint@8.49.0)(typescript@4.7.4)
'@typescript-eslint/utils': 5.29.0(eslint@8.49.0)(typescript@4.7.4)
'@typescript-eslint/type-utils': 5.29.0(eslint@8.50.0)(typescript@4.7.4)
'@typescript-eslint/utils': 5.29.0(eslint@8.50.0)(typescript@4.7.4)
debug: 4.3.4
eslint: 8.49.0
eslint: 8.50.0
functional-red-black-tree: 1.0.1
ignore: 5.2.4
regexpp: 3.2.0
@ -376,7 +381,7 @@ packages:
- supports-color
dev: true
/@typescript-eslint/parser@5.29.0(eslint@8.49.0)(typescript@4.7.4):
/@typescript-eslint/parser@5.29.0(eslint@8.50.0)(typescript@4.7.4):
resolution: {integrity: sha512-ruKWTv+x0OOxbzIw9nW5oWlUopvP/IQDjB5ZqmTglLIoDTctLlAJpAQFpNPJP/ZI7hTT9sARBosEfaKbcFuECw==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
@ -390,7 +395,7 @@ packages:
'@typescript-eslint/types': 5.29.0
'@typescript-eslint/typescript-estree': 5.29.0(typescript@4.7.4)
debug: 4.3.4
eslint: 8.49.0
eslint: 8.50.0
typescript: 4.7.4
transitivePeerDependencies:
- supports-color
@ -404,7 +409,7 @@ packages:
'@typescript-eslint/visitor-keys': 5.29.0
dev: true
/@typescript-eslint/type-utils@5.29.0(eslint@8.49.0)(typescript@4.7.4):
/@typescript-eslint/type-utils@5.29.0(eslint@8.50.0)(typescript@4.7.4):
resolution: {integrity: sha512-JK6bAaaiJozbox3K220VRfCzLa9n0ib/J+FHIwnaV3Enw/TO267qe0pM1b1QrrEuy6xun374XEAsRlA86JJnyg==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
@ -414,9 +419,9 @@ packages:
typescript:
optional: true
dependencies:
'@typescript-eslint/utils': 5.29.0(eslint@8.49.0)(typescript@4.7.4)
'@typescript-eslint/utils': 5.29.0(eslint@8.50.0)(typescript@4.7.4)
debug: 4.3.4
eslint: 8.49.0
eslint: 8.50.0
tsutils: 3.21.0(typescript@4.7.4)
typescript: 4.7.4
transitivePeerDependencies:
@ -449,7 +454,7 @@ packages:
- supports-color
dev: true
/@typescript-eslint/utils@5.29.0(eslint@8.49.0)(typescript@4.7.4):
/@typescript-eslint/utils@5.29.0(eslint@8.50.0)(typescript@4.7.4):
resolution: {integrity: sha512-3Eos6uP1nyLOBayc/VUdKZikV90HahXE5Dx9L5YlSd/7ylQPXhLk1BYb29SDgnBnTp+jmSZUU0QxUiyHgW4p7A==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
@ -459,9 +464,9 @@ packages:
'@typescript-eslint/scope-manager': 5.29.0
'@typescript-eslint/types': 5.29.0
'@typescript-eslint/typescript-estree': 5.29.0(typescript@4.7.4)
eslint: 8.49.0
eslint: 8.50.0
eslint-scope: 5.1.1
eslint-utils: 3.0.0(eslint@8.49.0)
eslint-utils: 3.0.0(eslint@8.50.0)
transitivePeerDependencies:
- supports-color
- typescript
@ -595,6 +600,11 @@ packages:
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
dev: true
/deepmerge@4.3.1:
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
engines: {node: '>=0.10.0'}
dev: false
/dir-glob@3.0.1:
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
engines: {node: '>=8'}
@ -660,13 +670,13 @@ packages:
estraverse: 5.3.0
dev: true
/eslint-utils@3.0.0(eslint@8.49.0):
/eslint-utils@3.0.0(eslint@8.50.0):
resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==}
engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0}
peerDependencies:
eslint: '>=5'
dependencies:
eslint: 8.49.0
eslint: 8.50.0
eslint-visitor-keys: 2.1.0
dev: true
@ -680,15 +690,15 @@ packages:
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true
/eslint@8.49.0:
resolution: {integrity: sha512-jw03ENfm6VJI0jA9U+8H5zfl5b+FvuU3YYvZRdZHOlU2ggJkxrlkJH4HcDrZpj6YwD8kuYqvQM8LyesoazrSOQ==}
/eslint@8.50.0:
resolution: {integrity: sha512-FOnOGSuFuFLv/Sa+FDVRZl4GGVAAFFi8LecRsI5a1tMO5HIE8nCm4ivAlzt4dT3ol/PaaGC0rJEEXQmHJBGoOg==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
hasBin: true
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.49.0)
'@eslint-community/eslint-utils': 4.4.0(eslint@8.50.0)
'@eslint-community/regexpp': 4.8.1
'@eslint/eslintrc': 2.1.2
'@eslint/js': 8.49.0
'@eslint/js': 8.50.0
'@humanwhocodes/config-array': 0.11.11
'@humanwhocodes/module-importer': 1.0.1
'@nodelib/fs.walk': 1.2.8
@ -707,7 +717,7 @@ packages:
file-entry-cache: 6.0.1
find-up: 5.0.0
glob-parent: 6.0.2
globals: 13.21.0
globals: 13.22.0
graphemer: 1.4.0
ignore: 5.2.4
imurmurhash: 0.1.4
@ -861,8 +871,8 @@ packages:
path-is-absolute: 1.0.1
dev: true
/globals@13.21.0:
resolution: {integrity: sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==}
/globals@13.22.0:
resolution: {integrity: sha512-H1Ddc/PbZHTDVJSnj8kWptIRSD6AM3pK+mKytuIVF4uoBV7rshFlhhvA58ceJ5wp3Er58w6zj7bykMpYXt3ETw==}
engines: {node: '>=8'}
dependencies:
type-fest: 0.20.2
@ -1026,14 +1036,14 @@ packages:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
dev: true
/obsidian@1.4.11(@codemirror/state@6.2.1)(@codemirror/view@6.19.0):
/obsidian@1.4.11(@codemirror/state@6.2.1)(@codemirror/view@6.20.1):
resolution: {integrity: sha512-BCVYTvaXxElJMl6MMbDdY/CGK+aq18SdtDY/7vH8v6BxCBQ6KF4kKxL0vG9UZ0o5qh139KpUoJHNm+6O5dllKA==}
peerDependencies:
'@codemirror/state': ^6.0.0
'@codemirror/view': ^6.0.0
dependencies:
'@codemirror/state': 6.2.1
'@codemirror/view': 6.19.0
'@codemirror/view': 6.20.1
'@types/codemirror': 5.60.8
moment: 2.29.4
dev: true

BIN
resources/settings_01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

BIN
resources/treefocus_01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

View file

@ -1,8 +1,39 @@
import { DEFAULT_RULES, SettingsObject } from 'src/core/plugin-settings';
import { SettingsObject } from 'src/core/plugin-settings';
import { Rule } from 'src/types/rules';
export const DEFAULT_RULES = (): Rule[] => [
{
matcher: {
method: 'STARTS_WITH',
value: '_',
context: 'NAME',
},
mode: 'DIM',
excludes: []
},
{
matcher: {
method: 'STARTS_WITH',
value: '.',
context: 'NAME',
},
mode: 'DIM',
excludes: []
},
{
matcher: {
method: 'STARTS_WITH',
value: '!',
context: 'NAME',
},
mode: 'HIGHLIGHT',
excludes: []
}
];
export const initialSettings: SettingsObject = {
transformPreset: 'DEFAULT',
rules: DEFAULT_RULES,
rules: DEFAULT_RULES(),
fileOverwrites: {}
};

View file

@ -2,6 +2,8 @@
import { PluginDataStore } from 'src/services/plugin-data-store';
import { RulesHelper } from 'src/util/rules-helper';
import { FilesFocusModeMap, Rule } from 'src/types/rules';
import { ItemFocusMode } from 'src/types/general';
import { DEFAULT_RULES } from 'src/_config/initial-settings';
export type TransformPresetKey = 'DEFAULT' | 'FANCY' | 'DELIGHT';
@ -12,35 +14,7 @@ export type SettingsObject = {
fileOverwrites: FilesFocusModeMap;
};
export const DEFAULT_RULES: Rule[] = [
{
matcher: {
method: 'STARTS_WITH',
value: '_',
context: 'NAME',
},
mode: 'DIM',
excludes: []
},
{
matcher: {
method: 'STARTS_WITH',
value: '.',
context: 'NAME',
},
mode: 'DIM',
excludes: []
},
{
matcher: {
method: 'STARTS_WITH',
value: '!',
context: 'NAME',
},
mode: 'HIGHLIGHT',
excludes: []
}
];
export type SettingsObjectKey = keyof SettingsObject;
@ -65,7 +39,26 @@ export abstract class PluginSettings {
static async resetRules(): Promise<void>
{
await PluginSettings.set('rules', DEFAULT_RULES);
await PluginSettings.set('rules', DEFAULT_RULES());
}
static async setExplicitMode(path: string, mode: ItemFocusMode): Promise<void>
{
const files = PluginSettings.get('fileOverwrites');
files[path] = mode;
await PluginSettings.set('fileOverwrites', files);
}
static async removeExplicitMode(path: string): Promise<void>
{
const files = PluginSettings.get('fileOverwrites');
delete files[path];
await PluginSettings.set('fileOverwrites', files);
}
}

View file

@ -1,6 +1,6 @@
import { App, FileExplorer, Plugin as ObsidianPlugin, PluginManifest, debounce } from 'obsidian';
import { App, FileExplorer, Menu, MenuItem, Plugin as ObsidianPlugin, PluginManifest, TAbstractFile, debounce } from 'obsidian';
import { Log } from '../util/logger';
import { FILE_EXPLORER_TYPE } from 'src/enhanced-obsidian-components/view-types';
import { VIEW_TYPE_FILE_EXPLORER } from 'src/enhanced-obsidian-components/known-type-keys';
import { PluginDataStore } from 'src/services/plugin-data-store';
import { initialSettings } from 'src/_config/initial-settings';
import { SettingsView } from 'src/views/settings-view';
@ -34,7 +34,7 @@ export class TreeFocus {
this.refreshDebouncer = debounce(
() => this.refresh(),
1000,
100,
true
);
@ -47,6 +47,98 @@ export class TreeFocus {
this.settingsView = new SettingsView(() => this.onSettingsChanged());
}
onOpenFileExplorerContextMenu(menu: Menu, file: TAbstractFile): void
{
Log.debug('open file explorer context menu', menu, file);
menu.addSeparator();
const explicitMode = ModeEvaluationService.getExplicitModeIfSet(file.path);
const itemHeadline= (item: MenuItem) => {
item.setTitle('TreeFocus');
item.setDisabled(true);
};
const highlighted = explicitMode === 'HIGHLIGHT';
const itemHighlight = (item: MenuItem) => {
item.setTitle('Highlight');
item.setChecked(highlighted);
item.onClick(async () =>
{
if (highlighted)
{
await PluginSettings.removeExplicitMode(file.path);
}
else
{
await PluginSettings.setExplicitMode(file.path, 'HIGHLIGHT');
}
this.requestRefresh();
});
};
const dimmed = explicitMode === 'DIM';
const itemDim = (item: MenuItem) => {
item.setTitle('Dim');
item.setChecked(dimmed);
item.onClick(async () =>
{
if (dimmed)
{
await PluginSettings.removeExplicitMode(file.path);
}
else
{
await PluginSettings.setExplicitMode(file.path, 'DIM');
}
this.requestRefresh();
});
};
const explicitDefault = explicitMode === 'DEFAULT';
const itemExplicitDefault = (item: MenuItem) => {
item.setTitle('Default (rule overwrite)');
item.setChecked(explicitDefault);
item.onClick(async () =>
{
if (explicitDefault)
{
await PluginSettings.removeExplicitMode(file.path);
}
else
{
await PluginSettings.setExplicitMode(file.path, 'DEFAULT');
}
this.requestRefresh();
});
};
const itemReset = (item: MenuItem) => {
item.setTitle('Reset...');
item.setDisabled(explicitMode === undefined);
item.onClick(async () =>
{
await PluginSettings.removeExplicitMode(file.path);
this.requestRefresh();
});
};
menu.addItem(itemHeadline);
menu.addItem(itemHighlight);
menu.addItem(itemDim);
menu.addItem(itemExplicitDefault);
menu.addItem(itemReset);
}
/**
* Use this method to request a refresh of the changes made to obsidian by the
* tree focus plugin.
*/
requestRefresh(): void
{
Log.log('refresh requested');
@ -54,6 +146,9 @@ export class TreeFocus {
this.refreshDebouncer();
}
/**
* Fired when the settings of the plugin have changed.
*/
onSettingsChanged(): void
{
Log.log('settings changed');
@ -65,6 +160,9 @@ export class TreeFocus {
this.requestRefresh();
}
/**
* Refreshes the changes made to obsidian by the tree focus plugin.
*/
private refresh(): void
{
Log.log('refreshing');
@ -73,6 +171,9 @@ export class TreeFocus {
this.addElementChanges();
}
/**
* Removes all changes made to obsidian by the tree focus plugin.
*/
private removeElementChanges(): void
{
Log.log('removing element changes');
@ -91,7 +192,9 @@ export class TreeFocus {
}
/**
* Adds all obsidian modifications by the tree focus plugin.
*/
private addElementChanges(): void
{
Log.log('adding element changes');
@ -117,11 +220,14 @@ export class TreeFocus {
}
}
/**
* Gets all file explorers in the current workspace.
*/
private getFileExplorers(): FileExplorer[]
{
Log.debug('getting file explorers');
let list = this.app.workspace.getLeavesOfType(FILE_EXPLORER_TYPE);
let list = this.app.workspace.getLeavesOfType(VIEW_TYPE_FILE_EXPLORER);
let finalList = list.map((leaf) =>
{

View file

@ -0,0 +1,13 @@
/**
* Key for Obsidian's file explorer view.
*/
export const VIEW_TYPE_FILE_EXPLORER = 'file-explorer';
/**
* Key for Obsidian's source: file explorer context menu.
*/
export const SOURCE_TYPE_FILE_EXPLORER_CONTEXT_MENU = 'file-explorer-context-menu';

View file

@ -27,6 +27,7 @@ export type SettingsContext = {
* and call {@link settingsUpdated}.
*/
applySettings: () => void;
createSupportLinks: (buyMeACoffee?: string, payPalUrl?: string) => void;
};
export abstract class ObsidianSettingsTab extends PluginSettingTab {
@ -62,6 +63,40 @@ export abstract class ObsidianSettingsTab extends PluginSettingTab {
}
},
createSectionDivider: () => rootElement.createDiv({ cls: 'setting-section-divider' }),
createSupportLinks: (buyMeACoffeeUsername?: string, payPalUrl?: string) =>
{
if (buyMeACoffeeUsername)
{
rootElement.createEl('br');
const parentEl = rootElement.createEl('a', {
href: `https://www.buymeacoffee.com/${buyMeACoffeeUsername}`,
});
parentEl.createEl('img', {
attr: {
src: 'https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png',
alt: 'Buy Me A Coffee',
style: 'height: 60px !important;width: 217px !important;'
}
});
rootElement.createEl('br');
}
if (payPalUrl)
{
rootElement.createEl('br');
const parentEl = rootElement.createEl('a', {
href: payPalUrl,
});
parentEl.createEl('img', {
attr: {
src: 'https://www.paypalobjects.com/webstatic/de_DE/i/de-pp-logo-200px.png',
alt: 'Donate with PayPal',
style: 'height: 60px !important;width: 217px !important;'
}
});
rootElement.createEl('br');
}
},
applySettings: () =>
{
this.display();

View file

@ -1,2 +0,0 @@
export const FILE_EXPLORER_TYPE = 'file-explorer';

View file

@ -16,11 +16,14 @@ export abstract class ModeEvaluationService {
this.files = files;
}
static getExplicitModeIfSet(path: string): ItemFocusMode | undefined
{
return this.files[path];
}
static evaluateMode(path: string, name: string): ItemFocusMode
{
let mode = 'DEFAULT';
const explicitMode = this.files[path];
const explicitMode = this.getExplicitModeIfSet(path);
if (explicitMode)
{

View file

@ -28,8 +28,8 @@ export abstract class PluginDataStore {
let storedData = await P.plugin.loadData();
let data = defaultData ? defaultData : {};
this._data = storedData ? deepmerge(data, storedData) : data;
defaultData = defaultData ? defaultData : {};
this._data = storedData ? storedData : defaultData;
Log.debug('done loading plugin data store', this._data);
}

View file

@ -15,6 +15,7 @@ export abstract class ErrorHelper {
public static pluginBug(message: string): Error
{
let finalMessage = message;
try
{

View file

@ -101,6 +101,7 @@ export class SettingsView extends ObsidianSettingsTab {
this.createRule(context, rules, i);
}
context.createSectionDivider();
context.createSectionHeader('Explicit Transformations', 'Items with explicit transformation configuration. To add an item, right click it in the file explorer and select "Set Treefocus".');
@ -111,9 +112,16 @@ export class SettingsView extends ObsidianSettingsTab {
for (let i = 0; i < keys.length; i++)
{
const key = keys[i];
this.createFileOverwrite(context, fileOverwrites, key);
}
context.createSectionDivider();
context.createSectionHeader('Support This Plugin', 'If you like this plugin, please consider supporting it by buying me a coffee. Thank you!');
context.createSupportLinks('iOSonntag', 'https://paypal.com/paypalme/iOSonntag/20');
}
createRule(context: SettingsContext, rules: Rule[], index: number): void

View file

@ -9,14 +9,154 @@ If your plugin does not need CSS, delete this file.
/* TRANSFORMATION STYLES */
.tree-item-self[data-treefocus-theme="DEFAULT"][data-treefocus-mode="HIGHLIGHT"] {
font-size: calc(var(--nav-item-size) * 2.3);
body {
--iconize-icon-size: 16px;
--treefocus-highlight-font-scale: 1.0;
--treefocus-highlight-font-weight: var(--nav-item-weight);
--treefocus-highlight-opacity: 1.0;
--treefocus-highlight-box-shadow: none;
--treefocus-highlight-background: none;
--treefocus-highlight-color: var(--nav-item-color);
--treefocus-highlight-border: none;
--treefocus-highlight-border-radius: var(--radius-s);
/* --treefocus-highlight-padding-h: var(--nav-item-padding); */
/* --treefocus-highlight-padding-v: var(--nav-item-padding); */
/* --treefocus-highlight-icon-padding: 4px; */
/* --treefocus-highlight-icon-spacing: 6px; */
/* --treefocus-highlight-icon-background: var(--text-accent); */
/* --treefocus-highlight-icon-color: var(--nav-item-color); */
--treefocus-highlight-line-height-addition: 1.0;
--treefocus-dim-font-scale: 1.0;
--treefocus-dim-font-weight: var(--nav-item-weight);
--treefocus-dim-opacity: 1.0;
--treefocus-dim-box-shadow: none;
--treefocus-dim-background: none;
--treefocus-dim-color: var(--nav-item-color);
--treefocus-dim-border: none;
--treefocus-dim-border-radius: var(--radius-s);
/* --treefocus-dim-padding-h: var(--nav-item-padding); */
/* --treefocus-dim-padding-v: var(--nav-item-padding); */
/* --treefocus-dim-icon-padding: 4px; */
/* --treefocus-dim-icon-spacing: 6px; */
/* --treefocus-dim-icon-background: var(--text-accent); */
/* --treefocus-dim-icon-color: var(--nav-item-color); */
--treefocus-dim-line-height-addition: 1.0;
}
.tree-item-self[data-tree-focus="DIM"] {
font-size: calc(var(--nav-item-size) * 0.7);
.tree-item-self[data-treefocus-theme="DEFAULT"] {
--treefocus-highlight-font-scale: 1.3;
--treefocus-highlight-font-weight: 700;
--treefocus-dim-font-scale: 0.7;
--treefocus-dim-opacity: 0.5;
}
.tree-item-self[data-treefocus-theme="DELIGHT"] {
--treefocus-highlight-font-scale: 1.2;
--treefocus-highlight-font-weight: 700;
--treefocus-dim-font-scale: 0.86;
--treefocus-dim-opacity: 0.7;
}
.tree-item-self[data-treefocus-theme="FANCY"] {
--treefocus-highlight-font-scale: 1.2;
--treefocus-highlight-font-weight: 700;
/* --treefocus-highlight-box-shadow: 0px 0px 0px 1px var(--color-base-00); */
/* --treefocus-highlight-border: 1px solid var(--background-primary); */
/* --treefocus-highlight-border: 1.5px solid var(--text-accent); */
--treefocus-highlight-border-radius: 30px;
--treefocus-highlight-background: var(--color-base-100);
--treefocus-highlight-color: var(--color-base-30);
--treefocus-highlight-padding-h: 12px;
--treefocus-highlight-padding-v: 2px;
--treefocus-highlight-line-height-addition: 1.0;
--treefocus-highlight-icon-padding: 4px;
--treefocus-highlight-icon-spacing: 6px;
--treefocus-highlight-icon-background: var(--text-accent);
--treefocus-highlight-icon-color: var(--color-base-100);
--treefocus-dim-font-scale: 0.7;
--treefocus-dim-opacity: 0.4;
}
.tree-item-self[data-treefocus-mode="HIGHLIGHT"] {
font-size: calc(var(--nav-item-size) * var(--treefocus-highlight-font-scale));
line-height: calc(var(--line-height-tight) * var(--treefocus-highlight-font-scale) * var(--treefocus-highlight-line-height-addition));
font-weight: var(--treefocus-highlight-font-weight) !important;
color: var(--treefocus-highlight-color);
}
.tree-item-self[data-treefocus-mode="DIM"] {
font-size: calc(var(--nav-item-size) * var(--treefocus-dim-font-scale));
line-height: calc(var(--line-height-tight) * var(--treefocus-dim-font-scale) * var(--treefocus-dim-line-height-addition));
font-weight: var(--treefocus-dim-font-weight) !important;
color: var(--treefocus-dim-color);
}
.tree-item-self[data-treefocus-mode="HIGHLIGHT"]:hover {
color: var(--treefocus-highlight-color) !important;
}
.tree-item-self[data-treefocus-mode="DIM"]:hover {
color: var(--treefocus-dim-color) !important;
}
.tree-item-self[data-treefocus-mode="HIGHLIGHT"] .tree-item-inner {
opacity: var(--treefocus-highlight-opacity);
box-shadow: var(--treefocus-highlight-box-shadow);
border: var(--treefocus-highlight-border);
border-radius: var(--treefocus-highlight-border-radius);
background: var(--treefocus-highlight-background);
padding: var(--treefocus-highlight-padding-v) var(--treefocus-highlight-padding-h) ;
}
.tree-item-self[data-treefocus-mode="DIM"] .tree-item-inner {
opacity: var(--treefocus-dim-opacity);
box-shadow: var(--treefocus-dim-box-shadow);
border: var(--treefocus-dim-border);
border-radius: var(--treefocus-dim-border-radius);
background: var(--treefocus-dim-background);
padding: var(--treefocus-dim-padding-v) var(--treefocus-dim-padding-h) ;
}
.tree-item-self[data-treefocus-mode="HIGHLIGHT"] .obsidian-icon-folder-icon {
background: var(--treefocus-highlight-icon-background, var(--treefocus-highlight-background));
border-radius: var(--treefocus-highlight-border-radius);
padding: calc(var(--treefocus-highlight-icon-padding));
margin-right: var(--treefocus-highlight-icon-spacing) !important;
color: var(--treefocus-highlight-icon-color, var(--treefocus-highlight-color));
}
.tree-item-self[data-treefocus-mode="DIM"] .obsidian-icon-folder-icon {
background: var(--treefocus-dim-icon-background, var(--treefocus-dim-background));
border-radius: var(--treefocus-dim-border-radius);
padding: calc(var(--treefocus-dim-icon-padding));
margin-right: var(--treefocus-dim-icon-spacing) !important;
color: var(--treefocus-dim-icon-color, var(--treefocus-dim-color));
}
.tree-item-self[data-treefocus-mode="HIGHLIGHT"] .obsidian-icon-folder-icon svg {
--treefocus-iconize-icon-size: calc(var(--iconize-icon-size) * var(--treefocus-highlight-font-scale));
width: var(--treefocus-iconize-icon-size);
height: var(--treefocus-iconize-icon-size);
opacity: var(--treefocus-highlight-opacity);
}
.tree-item-self[data-treefocus-mode="DIM"] .obsidian-icon-folder-icon svg {
--treefocus-iconize-icon-size: calc(var(--iconize-icon-size) * var(--treefocus-dim-font-scale));
width: var(--treefocus-iconize-icon-size);
height: var(--treefocus-iconize-icon-size);
opacity: var(--treefocus-dim-opacity);
}
/* OBSIDIAN CLASS REF */
/* full cell

View file

@ -1,3 +1,3 @@
{
"1.0.0": "0.15.0"
"0.3.1": "1.2.0"
}