mirror of
https://github.com/4source/favorites-obsidian-plugin.git
synced 2026-07-22 16:40:28 +00:00
Compare commits
No commits in common. "master" and "1.0.0" have entirely different histories.
48 changed files with 357 additions and 1926 deletions
|
|
@ -9,6 +9,7 @@
|
|||
"allow": [
|
||||
"warn",
|
||||
"error",
|
||||
"debug"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
|
|
|||
2
.github/CONTRIBUTING.md
vendored
2
.github/CONTRIBUTING.md
vendored
|
|
@ -26,8 +26,6 @@ If not related issue exists, open a new one using the appropriate <a href="../..
|
|||
#### 1. Fork the repository.
|
||||
#### 2. Create a new vault
|
||||
Just for testing the plugin so you **can't** exedentially destroy your real vault
|
||||
> [!NOTE]
|
||||
> When you working with ``npm run dev`` the plugin will use another key to identify the favorite lists. This **should** ensure you are not overwriting your real favorite lists. When you are working with ``npm run build`` the plugin will use the real key.
|
||||
#### 3. Clone repository to your local machine.
|
||||
```shell
|
||||
cd path/to/vault
|
||||
|
|
|
|||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -17,7 +17,6 @@ main.js
|
|||
|
||||
# obsidian
|
||||
data.json
|
||||
backup
|
||||
|
||||
# Exclude macOS Finder (System Explorer) View States
|
||||
.DS_Store
|
||||
|
|
|
|||
2
LICENSE
2
LICENSE
|
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2025 4Source
|
||||
Copyright (c) 2024 4Source
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
|||
114
README.md
114
README.md
|
|
@ -3,16 +3,15 @@
|
|||
Stop re-searching the same plugins or themes in every vault. With one central list, your essential tools and styles are always easy to find.
|
||||
|
||||
# Features
|
||||
- **Global Favorites list for Plugins & Themes** - Mark your go-to plugins and themes once and access them across all vaults.
|
||||
- **Global In Use list for Plugins & Themes** - Automatically maintained list of plugins and themes that are currently enabled in at least one vault.
|
||||
- **Global Known list for Plugins & Themes** - Automatically maintained history of plugins and themes that have been installed at least once in any vault.
|
||||
- **Ease of Use** - Favorite/unfavorite directly inside the Obsidian's
|
||||
- Plugin browser
|
||||
- Community plugins tab
|
||||
- Theme browser
|
||||
- via [Commands](#commands)
|
||||
- **Global Favorites for Plugins & Themes** - Mark your go to plugins and themes once and use them in all vaults
|
||||
- **Ease of Use** - Favorite/unfavorite directly from the Obsidian's plugin and theme details browser
|
||||
- **Vault Independence** - Favorites are stored globally on your device, not tied to a single vault
|
||||
|
||||
# Screenshots
|
||||
<img width="1104" height="1004" alt="image" src="https://github.com/user-attachments/assets/61b41e7b-4569-4509-95f3-d5e8a667d653" />
|
||||
|
||||
<img width="1104" height="1004" alt="image" src="https://github.com/user-attachments/assets/960eac0d-fea2-48e1-8faf-e54a7504149e" />
|
||||
|
||||
# How It Works
|
||||
1. Install and enable ***Favorites***.
|
||||
2. Open Obsidian's plugin or theme browser.
|
||||
|
|
@ -20,103 +19,6 @@ Stop re-searching the same plugins or themes in every vault. With one central li
|
|||
4. Use the Favorite button.
|
||||
5. Your favorites are saved globally and appear in every vault.
|
||||
|
||||
For plugins you can also favorite already installed plugins directly from the Community plugins tab.
|
||||
|
||||
# Screenshots
|
||||

|
||||
|
||||

|
||||
|
||||
<img width="1100" height="1000" alt="image" src="https://github.com/user-attachments/assets/5c8537dd-f5dc-4393-8cf7-6b506806631c" />
|
||||
|
||||
<img width="1100" height="1000" alt="image" src="https://github.com/user-attachments/assets/a6aebde5-a93c-4a93-ba0e-ccb9ad1c6560" />
|
||||
|
||||
<img width="1100" height="1000" alt="image" src="https://github.com/user-attachments/assets/e34ec7f4-57f2-4dc1-a150-45e9ab152295" />
|
||||
|
||||
<img width="1100" height="1000" alt="image" src="https://github.com/user-attachments/assets/ec9dfdf9-d607-4ff5-8679-fc286cb5e43c" />
|
||||
|
||||
<img width="1100" height="1000" alt="image" src="https://github.com/user-attachments/assets/a0b35f98-b194-433f-bd9e-66eecb5dd111" />
|
||||
|
||||
# Commands
|
||||
If you prefer managing your favorites list with commands here are the available commands
|
||||
- [Search and add plugin to favorite list](#search-and-add-plugin-to-favorite-list)
|
||||
- [Search and add theme to favorite list](#search-and-add-theme-to-favorite-list)
|
||||
- [Search and remove plugin from favorite list](#search-and-remove-plugin-from-favorite-list)
|
||||
- [Search and remove theme from favorite list](#search-and-remove-theme-from-favorite-list)
|
||||
- [Clear the plugin favorites list](#clear-the-plugin-favorites-list)
|
||||
- [Clear the plugin in use list](#clear-the-plugin-in-use-list)
|
||||
- [Clear the plugin known list](#clear-the-plugin-known-list)
|
||||
- [Clear the theme favorites list](#clear-the-theme-favorites-list)
|
||||
- [Clear the theme in use list](#clear-the-theme-in-use-list)
|
||||
- [Clear the theme known list](#clear-the-theme-known-list)
|
||||
- [Manually load the lists](#manually-load-the-lists)
|
||||
- [Manually save the lists](#manually-save-the-lists)
|
||||
- [Export lists to file](#export-lists-to-file)
|
||||
- [Import lists from file](#import-lists-from-file)
|
||||
|
||||
## Search and add plugin to favorite list
|
||||
Search and select a community plugin to add it to your favorites list. The list is fetched from the community plugin registry.
|
||||
|
||||
## Search and add theme to favorite list
|
||||
Search and select a community theme to add it to your favorites list. The list is fetched from the community theme registry.
|
||||
|
||||
## Search and remove plugin from favorite list
|
||||
Search and select from your current favorite plugins to remove it from your favorites list.
|
||||
|
||||
## Search and remove theme from favorite list
|
||||
Search and select from your current favorite themes to remove it from your favorites list.
|
||||
|
||||
## Clear the plugin favorites list
|
||||
Permanently removes ***all*** plugins from your favorites list after confirmation.
|
||||
> [!WARNING]
|
||||
> This action cannot be undone.
|
||||
|
||||
## Clear the plugin in use list
|
||||
Permanently removes ***all*** plugins from your in use list after confirmation.
|
||||
> [!WARNING]
|
||||
> This action cannot be undone.
|
||||
|
||||
## Clear the plugin known list
|
||||
Permanently removes ***all*** plugins from your known list after confirmation.
|
||||
> [!WARNING]
|
||||
> This action cannot be undone.
|
||||
|
||||
## Clear the theme favorites list
|
||||
Permanently removes ***all*** themes from your favorites list after confirmation.
|
||||
> [!WARNING]
|
||||
> This action cannot be undone.
|
||||
|
||||
## Clear the theme in use list
|
||||
Permanently removes ***all*** themes from your in use list after confirmation.
|
||||
> [!WARNING]
|
||||
> This action cannot be undone.
|
||||
|
||||
## Clear the theme known list
|
||||
Permanently removes ***all*** themes from your known list after confirmation.
|
||||
> [!WARNING]
|
||||
> This action cannot be undone.
|
||||
|
||||
## Manually load the lists
|
||||
Reloads the saved lists for plugins and themes. Use this to restore your lists if they were changed externally or need to be refreshed.
|
||||
> [!NOTE]
|
||||
> This is normally not necessary because the plugin handles this internally.
|
||||
|
||||
## Manually save the lists
|
||||
Forces the plugin to immediately save your current lists for plugins and themes. Use this if you want to ensure your lists are persistent.
|
||||
> [!WARNING]
|
||||
> This could overwrite changes from another running Obsidian instance if the changes from there are not loaded beforehand.
|
||||
|
||||
> [!NOTE]
|
||||
> This is normally not necessary because the plugin handles this internally.
|
||||
|
||||
## Export lists to file
|
||||
Creates a backup file containing your current lists for plugins and themes. The backup is saved as a timestamped JSON file inside the plugins backup folder within your vault configuration directory.
|
||||
|
||||
## Import lists from file
|
||||
Restores lists for plugins and themes from a previously created backup file. You will be prompted to select a backup file from the plugins backup folder. After confirmation imported lists will replaces your current lists with the content of the selected backup.
|
||||
> [!WARNING]
|
||||
> This will overwrite current lists and can't be undone.
|
||||
|
||||
# Contribution
|
||||
Feel free to contribute.
|
||||
|
||||
|
|
@ -124,7 +26,7 @@ You can create an [issue](https://github.com/4Source/favorites-obsidian-plugin/i
|
|||
|
||||
Or instead create a [pull request](https://github.com/4Source/favorites-obsidian-plugin/pulls) to contribute a bug fix or improvement for this plugin.
|
||||
|
||||
*Not a developer* but still want to help? You can help with testing. Either you test the current version for possible problems or, if there are currently any, you can also test [pre-releases (alpha/beta)](https://github.com/4Source/favorites-obsidian-plugin/releases). This can be easily accomplished if you install [VARE](https://obsidian.md/plugins?id=vare). Any version of this plugin must be installed. Then simply go to VARE's Settings tab and select the version you want to test from the drop-down menu. You could also add this plugin manually just ``Add unlisted plugin`` and enter ``4Source`` and ``favorites-obsidian-plugin``. If you found a bug or unexpected behavior create an [issue](https://github.com/4Source/favorites-obsidian-plugin/issues) with the version you have tested. Before creating an issue, make sure you know how to reproduce the bug. If there is already an issue for the bug you found that is still open but you have additional information, add it to the issue.
|
||||
*Not a developer* but still want to help? You can help with testing. Either you test the current version for possible problems or, if there are currently any, you can also test [pre-releases (alpha/beta)](https://github.com/4Source/favorites-obsidian-plugin/releases). This can be easily accomplished if you install [VARE](https://obsidian.md/plugins?id=vare). Any version of this plugin must be installed. Then simply go to VARE's Settings tab and select the version you want to test from the drop-down menu. You could also add this plugin manually just ``Add unlisted plugin`` and enter ``4Source`` and ``favorites-obsidian-plugin``. If you found a bug or unexpected behavior create an [issue](https://github.com/4Source/favorites-obsidian-plugin/issues) with the version you have tested. Before creating an issue, make sure you know how to reproduce the bug. If there is already an issue for the bug you found that is still open but you have additional information, add it to the issue.
|
||||
|
||||
For more info see [CONTRIBUTING](https://github.com/4Source/favorites-obsidian-plugin/blob/master/.github/CONTRIBUTING.md)
|
||||
|
||||
|
|
|
|||
|
|
@ -38,14 +38,6 @@ const context = await esbuild.context({
|
|||
sourcemap: prod ? false : "inline",
|
||||
treeShaking: true,
|
||||
outfile: "main.js",
|
||||
define: {
|
||||
'process.env.FAVORITE_PLUGINS_KEY': JSON.stringify(prod ? 'favorite-plugins' : 'dev-favorite-plugins'),
|
||||
'process.env.FAVORITE_THEMES_KEY': JSON.stringify(prod ? 'favorite-themes' : 'dev-favorite-themes'),
|
||||
'process.env.INUSE_PLUGINS_KEY': JSON.stringify(prod ? 'in-use-plugins' : 'dev-in-use-plugins'),
|
||||
'process.env.INUSE_THEMES_KEY': JSON.stringify(prod ? 'in-use-themes' : 'dev-in-use-themes'),
|
||||
'process.env.KNOWN_PLUGINS_KEY': JSON.stringify(prod ? 'known-plugins' : 'dev-known-plugins'),
|
||||
'process.env.KNOWN_THEMES_KEY': JSON.stringify(prod ? 'known-themes' : 'dev-known-themes'),
|
||||
}
|
||||
});
|
||||
|
||||
if (prod) {
|
||||
|
|
|
|||
|
|
@ -7,5 +7,5 @@
|
|||
"authorUrl": "https://github.com/4Source",
|
||||
"isDesktopOnly": false,
|
||||
"fundingUrl": "https://www.buymeacoffee.com/4Source",
|
||||
"version": "1.4.0"
|
||||
"version": "1.0.0"
|
||||
}
|
||||
99
package-lock.json
generated
99
package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "favorites",
|
||||
"version": "1.4.0",
|
||||
"version": "0.0.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "favorites",
|
||||
"version": "1.4.0",
|
||||
"version": "0.0.1",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@stylistic/eslint-plugin": "^3.1.0",
|
||||
|
|
@ -19,7 +19,6 @@
|
|||
"eslint": "^8.57.0",
|
||||
"jest": "^29.7.0",
|
||||
"jest-environment-jsdom": "^29.7.0",
|
||||
"monkey-around": "^3.0.0",
|
||||
"obsidian": "latest",
|
||||
"semver": "^7.6.0",
|
||||
"ts-jest": "^29.1.2",
|
||||
|
|
@ -1059,11 +1058,10 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@eslint/eslintrc/node_modules/minimatch": {
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
|
||||
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
|
|
@ -1106,11 +1104,10 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@humanwhocodes/config-array/node_modules/minimatch": {
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
|
||||
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
|
|
@ -1177,11 +1174,10 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": {
|
||||
"version": "3.14.2",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
|
||||
"integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
|
||||
"version": "3.14.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
|
||||
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"argparse": "^1.0.7",
|
||||
"esprima": "^4.0.0"
|
||||
|
|
@ -2210,11 +2206,10 @@
|
|||
}
|
||||
},
|
||||
"node_modules/ajv": {
|
||||
"version": "6.14.0",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz",
|
||||
"integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==",
|
||||
"version": "6.12.6",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
||||
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
|
|
@ -3230,11 +3225,10 @@
|
|||
}
|
||||
},
|
||||
"node_modules/eslint/node_modules/minimatch": {
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
|
||||
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
|
|
@ -3448,11 +3442,10 @@
|
|||
}
|
||||
},
|
||||
"node_modules/filelist/node_modules/minimatch": {
|
||||
"version": "5.1.9",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz",
|
||||
"integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==",
|
||||
"version": "5.1.6",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
|
||||
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
|
|
@ -3503,11 +3496,10 @@
|
|||
}
|
||||
},
|
||||
"node_modules/flatted": {
|
||||
"version": "3.4.2",
|
||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz",
|
||||
"integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
|
||||
"integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.4",
|
||||
|
|
@ -3674,11 +3666,10 @@
|
|||
}
|
||||
},
|
||||
"node_modules/glob/node_modules/minimatch": {
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
|
||||
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
|
|
@ -4126,11 +4117,10 @@
|
|||
}
|
||||
},
|
||||
"node_modules/jake/node_modules/minimatch": {
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
|
||||
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
|
|
@ -4739,11 +4729,10 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/js-yaml": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
|
||||
"integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1"
|
||||
},
|
||||
|
|
@ -5036,13 +5025,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "9.0.9",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
|
||||
"integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
|
||||
"version": "9.0.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
||||
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.2"
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
|
|
@ -5060,12 +5048,6 @@
|
|||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/monkey-around": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/monkey-around/-/monkey-around-3.0.0.tgz",
|
||||
"integrity": "sha512-jL6uY2lEAoaHxZep1cNRkCZjoIWY4g5VYCjriEWmcyHU7w8NU1+JH57xE251UVTohK0lCxMjv0ZV4ByDLIXEpw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
|
|
@ -5875,11 +5857,10 @@
|
|||
}
|
||||
},
|
||||
"node_modules/test-exclude/node_modules/minimatch": {
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
|
||||
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -26,12 +26,11 @@
|
|||
"eslint": "^8.57.0",
|
||||
"jest": "^29.7.0",
|
||||
"jest-environment-jsdom": "^29.7.0",
|
||||
"monkey-around": "^3.0.0",
|
||||
"obsidian": "latest",
|
||||
"semver": "^7.6.0",
|
||||
"ts-jest": "^29.1.2",
|
||||
"tslib": "2.4.0",
|
||||
"typescript": "4.7.4"
|
||||
},
|
||||
"version": "1.4.0"
|
||||
"version": "1.0.0"
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
import { Command, Notice } from 'obsidian';
|
||||
import CurrentPlugin from '../main';
|
||||
import { DialogModal } from 'src/modals/DialogModal';
|
||||
|
||||
export default function (plugin: CurrentPlugin): Command {
|
||||
return {
|
||||
id: 'clear-plugin-favorites-list',
|
||||
name: 'Clear the plugin favorites list',
|
||||
callback: () => {
|
||||
plugin.loadFavoritePlugins();
|
||||
const numberClear = plugin.favoritePlugins.length;
|
||||
new DialogModal(plugin.app, `Clear ${numberClear} plugin(s) permanently from favorite list?`, '', () => {
|
||||
plugin.favoritePlugins = [];
|
||||
plugin.saveFavoritePlugins();
|
||||
new Notice(`Cleared ${numberClear} plugins from favorite list`);
|
||||
}, () => {
|
||||
new Notice('Canceled clear plugins from favorite list');
|
||||
}, 'Clear', true, 'Cancel', false).open();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
import { Command, Notice } from 'obsidian';
|
||||
import CurrentPlugin from '../main';
|
||||
import { DialogModal } from 'src/modals/DialogModal';
|
||||
|
||||
export default function (plugin: CurrentPlugin): Command {
|
||||
return {
|
||||
id: 'clear-plugin-in-use-list',
|
||||
name: 'Clear the plugin in use list',
|
||||
callback: () => {
|
||||
plugin.loadInUsePlugins();
|
||||
const numberClear = Object.keys(plugin.inUsePlugins).length;
|
||||
new DialogModal(plugin.app, `Clear ${numberClear} plugin(s) permanently from in use list?`, '', () => {
|
||||
plugin.inUsePlugins = {};
|
||||
plugin.saveInUsePlugins();
|
||||
new Notice(`Cleared ${numberClear} plugins from in use list`);
|
||||
}, () => {
|
||||
new Notice('Canceled clear plugins from in use list');
|
||||
}, 'Clear', true, 'Cancel', false).open();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
import { Command, Notice } from 'obsidian';
|
||||
import CurrentPlugin from '../main';
|
||||
import { DialogModal } from 'src/modals/DialogModal';
|
||||
|
||||
export default function (plugin: CurrentPlugin): Command {
|
||||
return {
|
||||
id: 'clear-plugin-known-list',
|
||||
name: 'Clear the plugin known list',
|
||||
callback: () => {
|
||||
plugin.loadKnownPlugins();
|
||||
const numberClear = plugin.knownPlugins.length;
|
||||
new DialogModal(plugin.app, `Clear ${numberClear} plugin(s) permanently from known list?`, '', () => {
|
||||
plugin.knownPlugins = [];
|
||||
plugin.saveKnownPlugins();
|
||||
new Notice(`Cleared ${numberClear} plugins from known list`);
|
||||
}, () => {
|
||||
new Notice('Canceled clear plugins from known list');
|
||||
}, 'Clear', true, 'Cancel', false).open();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
import { Command, Notice } from 'obsidian';
|
||||
import CurrentPlugin from '../main';
|
||||
import { DialogModal } from 'src/modals/DialogModal';
|
||||
|
||||
export default function (plugin: CurrentPlugin): Command {
|
||||
return {
|
||||
id: 'clear-theme-favorites-list',
|
||||
name: 'Clear the theme favorites list',
|
||||
callback: () => {
|
||||
plugin.loadFavoriteThemes();
|
||||
const numberClear = plugin.favoriteThemes.length;
|
||||
new DialogModal(plugin.app, `Clear ${numberClear} theme(s) permanently from favorite list?`, '', () => {
|
||||
plugin.favoriteThemes = [];
|
||||
plugin.saveFavoriteThemes();
|
||||
new Notice(`Cleared ${numberClear} themes from favorite list`);
|
||||
}, () => {
|
||||
new Notice('Canceled clear themes from favorite list');
|
||||
}, 'Clear', true, 'Cancel', false).open();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
import { Command, Notice } from 'obsidian';
|
||||
import CurrentPlugin from '../main';
|
||||
import { DialogModal } from 'src/modals/DialogModal';
|
||||
|
||||
export default function (plugin: CurrentPlugin): Command {
|
||||
return {
|
||||
id: 'clear-theme-in-use-list',
|
||||
name: 'Clear the theme in use list',
|
||||
callback: () => {
|
||||
plugin.loadInUseThemes();
|
||||
const numberClear = Object.keys(plugin.inUseThemes).length;
|
||||
new DialogModal(plugin.app, `Clear ${numberClear} theme(s) permanently from in use list?`, '', () => {
|
||||
plugin.inUseThemes = {};
|
||||
plugin.saveInUseThemes();
|
||||
new Notice(`Cleared ${numberClear} themes from in use list`);
|
||||
}, () => {
|
||||
new Notice('Canceled clear themes from in use list');
|
||||
}, 'Clear', true, 'Cancel', false).open();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
import { Command, Notice } from 'obsidian';
|
||||
import CurrentPlugin from '../main';
|
||||
import { DialogModal } from 'src/modals/DialogModal';
|
||||
|
||||
export default function (plugin: CurrentPlugin): Command {
|
||||
return {
|
||||
id: 'clear-theme-known-list',
|
||||
name: 'Clear the theme known list',
|
||||
callback: () => {
|
||||
plugin.loadKnownThemes();
|
||||
const numberClear = plugin.knownThemes.length;
|
||||
new DialogModal(plugin.app, `Clear ${numberClear} theme(s) permanently from known list?`, '', () => {
|
||||
plugin.knownThemes = [];
|
||||
plugin.saveKnownThemes();
|
||||
new Notice(`Cleared ${numberClear} themes from known list`);
|
||||
}, () => {
|
||||
new Notice('Canceled clear themes from known list');
|
||||
}, 'Clear', true, 'Cancel', false).open();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
import { Command, normalizePath, Notice } from 'obsidian';
|
||||
import CurrentPlugin from '../main';
|
||||
import { PLUGIN_BACKUP_BASE_PATH } from 'src/constants';
|
||||
|
||||
export default function (plugin: CurrentPlugin): Command {
|
||||
return {
|
||||
id: 'export-lists',
|
||||
name: 'Export lists to file',
|
||||
callback: async () => {
|
||||
if (plugin.favoritePlugins.length <= 0 && plugin.favoriteThemes.length <= 0 && Object.keys(plugin.inUsePlugins).length <= 0 && Object.keys(plugin.inUseThemes).length <= 0 && plugin.knownPlugins.length <= 0 && plugin.knownThemes.length <= 0) {
|
||||
new Notice('No lists to backup');
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure backup path does exist
|
||||
const backupPath = normalizePath(`${plugin.app.vault.configDir}${PLUGIN_BACKUP_BASE_PATH}`);
|
||||
await plugin.app.vault.adapter.mkdir(backupPath);
|
||||
|
||||
// Create the file name
|
||||
const pad = (n: number) => n.toString().padStart(2, '0');
|
||||
const date = new Date();
|
||||
const dateString = `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}-${pad(date.getHours())}-${pad(date.getMinutes())}`;
|
||||
const backupFilePath = normalizePath(`${backupPath}/favorite-${dateString}.json`);
|
||||
|
||||
// Write backup file for lists
|
||||
await plugin.app.vault.adapter.write(backupFilePath, JSON.stringify({
|
||||
favoritePlugins: plugin.favoritePlugins,
|
||||
favoriteThemes: plugin.favoriteThemes,
|
||||
inUsePlugins: plugin.inUsePlugins,
|
||||
inUseThemes: plugin.inUseThemes,
|
||||
knownPlugins: plugin.knownPlugins,
|
||||
knownThemes: plugin.knownThemes,
|
||||
}));
|
||||
new Notice(`Lists backup successful written to: ${backupFilePath}`);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
import { Command, normalizePath, Notice } from 'obsidian';
|
||||
import CurrentPlugin from '../main';
|
||||
import { PLUGIN_BACKUP_BASE_PATH } from 'src/constants';
|
||||
import { StringSuggestModal } from 'src/modals/StringSuggestModal';
|
||||
import { DialogModal } from 'src/modals/DialogModal';
|
||||
|
||||
export default function (plugin: CurrentPlugin): Command {
|
||||
return {
|
||||
id: 'import-lists',
|
||||
name: 'Import lists from file',
|
||||
callback: async () => {
|
||||
const backupPath = normalizePath(`${plugin.app.vault.configDir}${PLUGIN_BACKUP_BASE_PATH}`);
|
||||
if (!(await plugin.app.vault.adapter.exists(backupPath))) {
|
||||
// Backup path does not exist
|
||||
new Notice(`Backup path does not exist: ${backupPath}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const backupFiles = (await plugin.app.vault.adapter.list(backupPath)).files;
|
||||
if (backupFiles.length <= 0) {
|
||||
// Backup path is empty
|
||||
new Notice('Backup path is empty');
|
||||
return;
|
||||
}
|
||||
|
||||
new StringSuggestModal(plugin.app, 'Select backup file to load from', backupFiles, async (result) => {
|
||||
const content = await plugin.app.vault.adapter.read(result);
|
||||
const json = JSON.parse(content);
|
||||
const loadedFavoritePlugins = json.favoritePlugins || [];
|
||||
const loadedFavoriteThemes = json.favoriteThemes || [];
|
||||
const loadedInUsePlugins = json.inUsePlugins || [];
|
||||
const loadedInUseThemes = json.inUseThemes || [];
|
||||
const loadedKnownPlugins = json.knownPlugins || [];
|
||||
const loadedKnownThemes = json.knownThemes || [];
|
||||
new DialogModal(plugin.app, 'Are you sure you want to overwrite current lists?', `The following lists will be overwritten: favorite plugins will change from ${plugin.favoritePlugins.length} items to ${loadedFavoritePlugins.length} items, favorite themes will change from ${plugin.favoriteThemes.length} items to ${loadedFavoriteThemes.length} items, in use plugins will change from ${plugin.inUsePlugins.length} items to ${loadedInUsePlugins.length} items, in use themes will change from ${plugin.inUseThemes.length} items to ${loadedInUseThemes.length} items, known plugins will change from ${plugin.knownPlugins.length} items to ${loadedKnownPlugins.length} items, and known themes will change from ${plugin.knownThemes.length} items to ${loadedKnownThemes.length} items.`, () => {
|
||||
plugin.favoritePlugins = loadedFavoritePlugins;
|
||||
plugin.favoriteThemes = loadedFavoriteThemes;
|
||||
plugin.inUsePlugins = loadedInUsePlugins;
|
||||
plugin.inUseThemes = loadedInUseThemes;
|
||||
plugin.knownPlugins = loadedKnownPlugins;
|
||||
plugin.knownThemes = loadedKnownThemes;
|
||||
plugin.saveLists();
|
||||
|
||||
new Notice('Loaded backup successfully');
|
||||
}, () => {
|
||||
new Notice('Canceled loading backup by user');
|
||||
}, 'Overwrite', true, 'Cancel', false).open();
|
||||
}).open();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
import { Command, Notice } from 'obsidian';
|
||||
import CurrentPlugin from '../main';
|
||||
|
||||
export default function (plugin: CurrentPlugin): Command {
|
||||
return {
|
||||
id: 'load-lists',
|
||||
name: 'Manually load the lists',
|
||||
callback: () => {
|
||||
plugin.loadLists();
|
||||
new Notice('Loaded lists');
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
import { Command, Notice } from 'obsidian';
|
||||
import CurrentPlugin from '../main';
|
||||
|
||||
export default function (plugin: CurrentPlugin): Command {
|
||||
return {
|
||||
id: 'save-lists',
|
||||
name: 'Manually save the lists',
|
||||
callback: () => {
|
||||
plugin.saveLists();
|
||||
new Notice('Saved lists');
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
import { Command, Notice } from 'obsidian';
|
||||
import CurrentPlugin from '../main';
|
||||
import { CommunitySuggestModal } from 'src/modals/CommunitySuggestModal';
|
||||
import { CommunityPlugin, fetchCommunityPluginList } from 'src/util/GitHub';
|
||||
|
||||
export default function (plugin: CurrentPlugin): Command {
|
||||
return {
|
||||
id: 'search-and-add-plugin-to-favorite-list',
|
||||
name: 'Search and add plugin to favorite list',
|
||||
callback: async () => {
|
||||
let items = await fetchCommunityPluginList();
|
||||
if (!items) {
|
||||
new Notice('Failed to fetch community plugins. See console for more information.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Filter out favorites
|
||||
plugin.loadFavoritePlugins();
|
||||
items = items.filter(value => !plugin.favoritePlugins.contains(value.id));
|
||||
|
||||
if (items.length <= 0) {
|
||||
new Notice('No plugin left which is could be added to favorite list');
|
||||
return;
|
||||
}
|
||||
|
||||
new CommunitySuggestModal<CommunityPlugin>(plugin.app, 'Select plugin which should be added to favorites list...', items, (result) => {
|
||||
plugin.favoritePlugins.push(result.id);
|
||||
plugin.saveFavoritePlugins();
|
||||
new Notice(`Added ${result.name} to favorite list`);
|
||||
}).open();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
import { Command, Notice } from 'obsidian';
|
||||
import CurrentPlugin from '../main';
|
||||
import { CommunitySuggestModal } from 'src/modals/CommunitySuggestModal';
|
||||
import { CommunityTheme, fetchCommunityThemeList } from 'src/util/GitHub';
|
||||
|
||||
export default function (plugin: CurrentPlugin): Command {
|
||||
return {
|
||||
id: 'search-and-add-theme-to-favorite-list',
|
||||
name: 'Search and add theme to favorite list',
|
||||
callback: async () => {
|
||||
let items = await fetchCommunityThemeList();
|
||||
if (!items) {
|
||||
new Notice('Failed to fetch community themes. See console for more information.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Filter out favorites
|
||||
plugin.loadFavoriteThemes();
|
||||
items = items.filter(value => !plugin.favoriteThemes.contains(value.name));
|
||||
|
||||
if (items.length <= 0) {
|
||||
new Notice('No theme left which is could be added to favorite list');
|
||||
return;
|
||||
}
|
||||
|
||||
new CommunitySuggestModal<CommunityTheme>(plugin.app, 'Select theme which should be added to favorites list...', items, (result) => {
|
||||
plugin.favoriteThemes.push(result.name);
|
||||
plugin.saveFavoriteThemes();
|
||||
new Notice(`Added ${result.name} to favorite list`);
|
||||
}).open();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
import { Command, Notice } from 'obsidian';
|
||||
import CurrentPlugin from '../main';
|
||||
import { CommunityPlugin, fetchCommunityPluginList } from 'src/util/GitHub';
|
||||
import { CommunitySuggestModal } from 'src/modals/CommunitySuggestModal';
|
||||
|
||||
export default function (plugin: CurrentPlugin): Command {
|
||||
return {
|
||||
id: 'search-and-remove-plugin-from-favorite-list',
|
||||
name: 'Search and remove plugin from favorite list',
|
||||
callback: async () => {
|
||||
plugin.loadFavoritePlugins();
|
||||
if (plugin.favoritePlugins.length <= 0) {
|
||||
new Notice('Plugin favorite list is empty');
|
||||
return;
|
||||
}
|
||||
const communityItems = await fetchCommunityPluginList();
|
||||
const installedItems = Object.values(plugin.app.plugins.manifests);
|
||||
const items = plugin.favoritePlugins.map((value) => {
|
||||
return communityItems?.find((communityValue) => value === communityValue.id) || installedItems.find(installedValue => value === installedValue.id) as unknown as CommunityPlugin || { id: value, name: value, author: 'unknown' } as CommunityPlugin;
|
||||
});
|
||||
|
||||
new CommunitySuggestModal<CommunityPlugin>(plugin.app, 'Select plugin which should be removed from the favorites list...', items, (result) => {
|
||||
plugin.favoritePlugins.remove(result.id);
|
||||
plugin.saveFavoritePlugins();
|
||||
new Notice(`Removed ${result.name} from favorite list`);
|
||||
}).open();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
import { Command, Notice } from 'obsidian';
|
||||
import CurrentPlugin from '../main';
|
||||
import { CommunityTheme, fetchCommunityThemeList } from 'src/util/GitHub';
|
||||
import { CommunitySuggestModal } from 'src/modals/CommunitySuggestModal';
|
||||
|
||||
export default function (plugin: CurrentPlugin): Command {
|
||||
return {
|
||||
id: 'search-and-remove-theme-from-favorite-list',
|
||||
name: 'Search and remove theme from favorite list',
|
||||
callback: async () => {
|
||||
plugin.loadFavoriteThemes();
|
||||
if (plugin.favoriteThemes.length <= 0) {
|
||||
new Notice('Theme favorite list is empty');
|
||||
return;
|
||||
}
|
||||
const communityItems = await fetchCommunityThemeList();
|
||||
const installedItems = Object.values(plugin.app.customCss.themes);
|
||||
const items = plugin.favoriteThemes.map((value) => {
|
||||
return communityItems?.find((communityValue) => value === communityValue.name) || installedItems.find(installedValue => value === installedValue.name) as unknown as CommunityTheme || { name: value, author: 'unknown' } as CommunityTheme;
|
||||
});
|
||||
|
||||
new CommunitySuggestModal<CommunityTheme>(plugin.app, 'Select theme which should be removed from the favorites list...', items, (result) => {
|
||||
plugin.favoriteThemes.remove(result.name);
|
||||
plugin.saveFavoriteThemes();
|
||||
new Notice(`Removed ${result.name} from favorite list`);
|
||||
}).open();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
import CurrentPlugin from '../main';
|
||||
import ClearPluginFavoritesList from './ClearPluginFavoritesList';
|
||||
import ClearPluginInUseList from './ClearPluginInUseList';
|
||||
import ClearPluginKnownList from './ClearPluginKnownList';
|
||||
import ClearThemeFavoritesList from './ClearThemeFavoritesList';
|
||||
import ClearThemeInUseList from './ClearThemeInUseList';
|
||||
import ClearThemeKnownList from './ClearThemeKnownList';
|
||||
import ExportLists from './ExportLists';
|
||||
import ImportLists from './ImportLists';
|
||||
import LoadLists from './LoadLists';
|
||||
import SaveLists from './SaveLists';
|
||||
import SearchAndAddPluginToFavoriteList from './SearchAndAddPluginToFavoriteList';
|
||||
import SearchAndAddThemeToFavoriteList from './SearchAndAddThemeToFavoriteList';
|
||||
import SearchAndRemovePluginFromFavoriteList from './SearchAndRemovePluginFromFavoriteList';
|
||||
import SearchAndRemoveThemeFromFavoriteList from './SearchAndRemoveThemeFromFavoriteList';
|
||||
|
||||
export async function addAllCommands(plugin: CurrentPlugin) {
|
||||
// TODO: Dynamically import all files in the commands folder during bundling time
|
||||
|
||||
plugin.addCommand(ClearPluginFavoritesList(plugin));
|
||||
plugin.addCommand(ClearPluginInUseList(plugin));
|
||||
plugin.addCommand(ClearPluginKnownList(plugin));
|
||||
plugin.addCommand(ClearThemeFavoritesList(plugin));
|
||||
plugin.addCommand(ClearThemeInUseList(plugin));
|
||||
plugin.addCommand(ClearThemeKnownList(plugin));
|
||||
plugin.addCommand(ExportLists(plugin));
|
||||
plugin.addCommand(ImportLists(plugin));
|
||||
plugin.addCommand(LoadLists(plugin));
|
||||
plugin.addCommand(SaveLists(plugin));
|
||||
plugin.addCommand(SearchAndAddPluginToFavoriteList(plugin));
|
||||
plugin.addCommand(SearchAndAddThemeToFavoriteList(plugin));
|
||||
plugin.addCommand(SearchAndRemovePluginFromFavoriteList(plugin));
|
||||
plugin.addCommand(SearchAndRemoveThemeFromFavoriteList(plugin));
|
||||
}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
export const PLUGIN_ID = 'favorites';
|
||||
export const PLUGIN_BACKUP_BASE_PATH = `/plugins/${PLUGIN_ID}/backup`;
|
||||
688
src/main.ts
688
src/main.ts
|
|
@ -1,429 +1,297 @@
|
|||
import { Plugin } from 'obsidian';
|
||||
import { addAllCommands } from './commands';
|
||||
import patchSettingsModal from './patches/patch.SettingsModal';
|
||||
import patchModal from './patches/patch.Modal';
|
||||
import patchPluginManager from './patches/patch.PluginManager';
|
||||
import patchStyleManager from './patches/patch.StyleManager';
|
||||
import { CommunityItem, CommunityModal, Modal, Plugin } from 'obsidian';
|
||||
|
||||
export default class FavoritesPlugin extends Plugin {
|
||||
pluginFavoritesKey: string;
|
||||
favoritePlugins: string[];
|
||||
themeFavoritesKey: string;
|
||||
favoriteThemes: string[];
|
||||
pluginInUseKey: string;
|
||||
inUsePlugins: Record<string, string[]>;
|
||||
themeInUseKey: string;
|
||||
inUseThemes: Record<string, string[]>;
|
||||
pluginKnownKey: string;
|
||||
knownPlugins: string[];
|
||||
themeKnownKey: string;
|
||||
knownThemes: string[];
|
||||
uninstallCommunityPluginModalPatch?: () => void;
|
||||
uninstallCommunityPluginsSettingTabPatch?: () => void;
|
||||
uninstallCommunityThemeModalPatch?: () => void;
|
||||
uninstallModalPatch?: () => void;
|
||||
uninstallPluginManagerPatch?: () => void;
|
||||
uninstallSettingsModalPatch?: () => void;
|
||||
uninstallStyleManagerPatch?: () => void;
|
||||
favoritePlugins?: string[];
|
||||
favoriteThemes?: string[];
|
||||
communityPluginModalPrototype?: CommunityModal;
|
||||
communityThemesModalPrototype?: CommunityModal;
|
||||
|
||||
async onload() {
|
||||
this.loadStorageKeys();
|
||||
this.loadLists();
|
||||
await this.loadSettings();
|
||||
|
||||
// Patch SettingsModal
|
||||
if (!this.uninstallSettingsModalPatch) {
|
||||
// console.debug('Patch SettingsModal');
|
||||
this.uninstallSettingsModalPatch = patchSettingsModal(this);
|
||||
if (!Modal.prototype.originalOpen) {
|
||||
Modal.prototype.originalOpen = Modal.prototype.open;
|
||||
const originalModalOpen = Modal.prototype.open;
|
||||
|
||||
Modal.prototype.open = (function (originalModalOpen, plugin) {
|
||||
return function () {
|
||||
originalModalOpen?.apply(this);
|
||||
|
||||
// Check the opened Modal is the Community plugin browse modal
|
||||
if (this.containerEl?.querySelector('.mod-community-plugin')) {
|
||||
// Store the Community Plugin Browse Modal prototype to be able to reset to the original
|
||||
plugin.communityPluginModalPrototype = this.constructor.prototype;
|
||||
|
||||
// Check the plugin updateItems is already overwritten
|
||||
if (!this.constructor.prototype.originalUpdateItems) {
|
||||
// Save original method
|
||||
this.constructor.prototype.originalUpdateItems = this.constructor.prototype.updateItems;
|
||||
const originalUpdateItems = this.constructor.prototype.updateItems;
|
||||
if (!this.constructor.prototype.originalUpdateItems) {
|
||||
console.error('Favorites plugin: Failed to access original updateItems method!');
|
||||
return;
|
||||
}
|
||||
|
||||
// Overwrite method with additional functionality
|
||||
this.constructor.prototype.updateItems = (function (originalUpdateItems, plugin) {
|
||||
return function () {
|
||||
// Load the favorite plugins
|
||||
plugin.favoritePlugins = JSON.parse(localStorage.getItem('favorite-plugins') || '[]');
|
||||
|
||||
const result = originalUpdateItems.apply(this);
|
||||
|
||||
// Add to the favorite plugins a tag to visualize it for the user
|
||||
if (plugin.favoritePlugins) {
|
||||
plugin.favoritePlugins.forEach(id => {
|
||||
if (this.items && this.items[id]?.nameEl) {
|
||||
this.items[id].nameEl.createSpan({
|
||||
cls: 'flair',
|
||||
text: 'favorite',
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
})(originalUpdateItems, plugin);
|
||||
}
|
||||
|
||||
// Check the plugin showItem is already overwritten
|
||||
if (!this.constructor.prototype.originalShowItem) {
|
||||
// Save original method
|
||||
this.constructor.prototype.originalShowItem = this.constructor.prototype.showItem;
|
||||
const originalShowItem = this.constructor.prototype.showItem;
|
||||
if (!this.constructor.prototype.originalShowItem) {
|
||||
console.error('Favorites: Failed to access original showItem method!');
|
||||
return;
|
||||
}
|
||||
|
||||
// Overwrite method with additional functionality
|
||||
this.constructor.prototype.showItem = (function (originalShowItem, plugin) {
|
||||
return function (...args: CommunityItem[]) {
|
||||
// Load the favorite plugins
|
||||
plugin.favoritePlugins = JSON.parse(localStorage.getItem('favorite-plugins') || '[]');
|
||||
|
||||
return originalShowItem.apply(this, args).then(async (r: void) => {
|
||||
const infoEl = await this.detailsEl.getElementsByClassName('community-modal-info')[0];
|
||||
const infoNameEl = await infoEl?.getElementsByClassName('community-modal-info-name')[0];
|
||||
const buttonContainerEl = await infoEl?.getElementsByClassName('community-modal-button-container')[0];
|
||||
|
||||
const isFavorite = plugin.favoritePlugins?.contains(this.selectedItemId);
|
||||
|
||||
// Add to the favorite plugins a tag to visualize it for the user
|
||||
if (isFavorite) {
|
||||
if (infoNameEl) {
|
||||
infoNameEl.createSpan({
|
||||
cls: 'flair',
|
||||
text: 'favorite',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
plugin.registerEvent(buttonContainerEl?.createEl('button', { text: isFavorite ? 'Unfavorite' : 'Favorite' }).addEventListener('click', () => {
|
||||
if (isFavorite) {
|
||||
plugin.favoritePlugins?.remove(this.selectedItemId);
|
||||
}
|
||||
else {
|
||||
plugin.favoritePlugins?.push(this.selectedItemId);
|
||||
}
|
||||
|
||||
plugin.saveSettings();
|
||||
|
||||
// Redraw
|
||||
infoEl.detach();
|
||||
this.showItem(this.items[this.selectedItemId]);
|
||||
this.update();
|
||||
}));
|
||||
|
||||
return r;
|
||||
});
|
||||
};
|
||||
})(originalShowItem, plugin);
|
||||
}
|
||||
}
|
||||
|
||||
// Check the opened Modal is the Community themes browse modal
|
||||
if (this.containerEl?.querySelector('.mod-community-theme')) {
|
||||
// Store the Community Theme Browse Modal prototype to be able to reset to the original
|
||||
plugin.communityThemesModalPrototype = this.constructor.prototype;
|
||||
|
||||
// Check the theme updateItems is already overwritten
|
||||
if (!this.constructor.prototype.originalUpdateItems) {
|
||||
// Save original method
|
||||
this.constructor.prototype.originalUpdateItems = this.constructor.prototype.updateItems;
|
||||
const originalUpdateItems = this.constructor.prototype.updateItems;
|
||||
if (!this.constructor.prototype.originalUpdateItems) {
|
||||
console.error('Favorites: Failed to access original updateItems method!');
|
||||
return;
|
||||
}
|
||||
|
||||
// Overwrite method with additional functionality
|
||||
this.constructor.prototype.updateItems = (function (originalUpdateItems, plugin) {
|
||||
return function () {
|
||||
// Load the favorite themes
|
||||
plugin.favoriteThemes = JSON.parse(localStorage.getItem('favorite-themes') || '[]');
|
||||
|
||||
const result = originalUpdateItems.apply(this);
|
||||
|
||||
// Ignore the default theme
|
||||
if (this.selectedItemId === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add to the favorite themes a tag to visualize it for the user
|
||||
if (plugin.favoriteThemes) {
|
||||
plugin.favoriteThemes.forEach(id => {
|
||||
if (this.items && this.items[id]?.nameEl) {
|
||||
this.items[id].nameEl.createSpan({
|
||||
cls: 'flair',
|
||||
text: 'favorite',
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
})(originalUpdateItems, plugin);
|
||||
}
|
||||
|
||||
// Check the theme showItem is already overwritten
|
||||
if (!this.constructor.prototype.originalShowItem) {
|
||||
// Save original method
|
||||
this.constructor.prototype.originalShowItem = this.constructor.prototype.showItem;
|
||||
const originalShowItem = this.constructor.prototype.showItem;
|
||||
if (!this.constructor.prototype.originalShowItem) {
|
||||
console.error('Favorites: Failed to access original showItem method!');
|
||||
return;
|
||||
}
|
||||
|
||||
// Overwrite method with additional functionality
|
||||
this.constructor.prototype.showItem = (function (originalShowItem, plugin) {
|
||||
// Load the favorite themes
|
||||
plugin.favoriteThemes = JSON.parse(localStorage.getItem('favorite-themes') || '[]');
|
||||
|
||||
return function (...args: CommunityItem[]) {
|
||||
return originalShowItem.apply(this, args).then(async (r: void) => {
|
||||
// Ignore the default theme
|
||||
if (this.selectedItemId === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
const infoEl = await this.detailsEl.getElementsByClassName('community-modal-info')[0];
|
||||
const infoNameEl = await infoEl?.getElementsByClassName('community-modal-info-name')[0];
|
||||
const buttonContainerEl = await infoEl?.getElementsByClassName('community-modal-button-container')[0];
|
||||
|
||||
const isFavorite = plugin.favoriteThemes?.contains(this.selectedItemId);
|
||||
|
||||
// Add to the favorite themes a tag to visualize it for the user
|
||||
if (isFavorite) {
|
||||
if (infoNameEl) {
|
||||
infoNameEl.createSpan({
|
||||
cls: 'flair',
|
||||
text: 'favorite',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
plugin.registerEvent(buttonContainerEl?.createEl('button', { text: isFavorite ? 'Unfavorite' : 'Favorite' }).addEventListener('click', () => {
|
||||
if (isFavorite) {
|
||||
plugin.favoriteThemes?.remove(this.selectedItemId);
|
||||
}
|
||||
else {
|
||||
plugin.favoriteThemes?.push(this.selectedItemId);
|
||||
}
|
||||
|
||||
plugin.saveSettings();
|
||||
|
||||
// Redraw
|
||||
infoEl.detach();
|
||||
this.showItem(this.items[this.selectedItemId]);
|
||||
this.update();
|
||||
}));
|
||||
|
||||
return r;
|
||||
});
|
||||
};
|
||||
})(originalShowItem, plugin);
|
||||
}
|
||||
}
|
||||
|
||||
// Restore the original Modal open function as soon as the CommunityPluginModal and CommunityThemesModal is opened once
|
||||
if (Modal.prototype.originalOpen && plugin.communityPluginModalPrototype && plugin.communityThemesModalPrototype) {
|
||||
Modal.prototype.open = Modal.prototype.originalOpen;
|
||||
delete Modal.prototype.originalOpen;
|
||||
}
|
||||
};
|
||||
})(originalModalOpen, this);
|
||||
}
|
||||
else {
|
||||
console.warn('Favorites plugin: Modal prototype already has originalOpen, this is not intended!');
|
||||
}
|
||||
|
||||
// Patch Modal
|
||||
if (!this.uninstallModalPatch) {
|
||||
// console.debug('Patch Modal');
|
||||
this.uninstallModalPatch = patchModal(this);
|
||||
}
|
||||
|
||||
// Patch PluginManager
|
||||
if (!this.uninstallPluginManagerPatch) {
|
||||
// console.debug('Patch PluginManager');
|
||||
this.uninstallPluginManagerPatch = patchPluginManager(this);
|
||||
}
|
||||
|
||||
// Patch StyleManager
|
||||
if (!this.uninstallStyleManagerPatch) {
|
||||
// console.debug('Patch StyleManager');
|
||||
this.uninstallStyleManagerPatch = patchStyleManager(this);
|
||||
}
|
||||
|
||||
// Check the state of the vault and update lists
|
||||
this.updateListsForVault();
|
||||
|
||||
// Add all commands registered
|
||||
addAllCommands(this);
|
||||
/*
|
||||
* TODO: Add command to save and reload the favorites list
|
||||
* TODO: Add command to remove all favorites from list
|
||||
* TODO: Add command to search for plugin to add to favorites list
|
||||
*/
|
||||
}
|
||||
|
||||
async onunload() {
|
||||
try {
|
||||
// Restore the original functions
|
||||
if (this.uninstallCommunityPluginModalPatch) {
|
||||
// console.debug('Uninstall CommunityPluginModal patch');
|
||||
this.uninstallCommunityPluginModalPatch();
|
||||
this.uninstallCommunityPluginModalPatch = undefined;
|
||||
// Restore the original Modal open function
|
||||
|
||||
if (Modal.prototype.originalOpen) {
|
||||
Modal.prototype.open = Modal.prototype.originalOpen;
|
||||
delete Modal.prototype.originalOpen;
|
||||
}
|
||||
|
||||
// Restore the original plugin updateItems function
|
||||
if (this.communityPluginModalPrototype && this.communityPluginModalPrototype.originalUpdateItems) {
|
||||
this.communityPluginModalPrototype.updateItems = this.communityPluginModalPrototype.originalUpdateItems;
|
||||
delete this.communityPluginModalPrototype.originalUpdateItems;
|
||||
}
|
||||
|
||||
// Restore the original plugin showItem function
|
||||
if (this.communityPluginModalPrototype && this.communityPluginModalPrototype.originalShowItem) {
|
||||
this.communityPluginModalPrototype.showItem = this.communityPluginModalPrototype.originalShowItem;
|
||||
delete this.communityPluginModalPrototype.originalShowItem;
|
||||
}
|
||||
|
||||
// Restore the original theme updateItems function
|
||||
if (this.communityThemesModalPrototype && this.communityThemesModalPrototype.originalUpdateItems) {
|
||||
this.communityThemesModalPrototype.updateItems = this.communityThemesModalPrototype.originalUpdateItems;
|
||||
delete this.communityThemesModalPrototype.originalUpdateItems;
|
||||
}
|
||||
|
||||
// Restore the original theme showItem function
|
||||
if (this.communityThemesModalPrototype && this.communityThemesModalPrototype.originalShowItem) {
|
||||
this.communityThemesModalPrototype.showItem = this.communityThemesModalPrototype.originalShowItem;
|
||||
delete this.communityThemesModalPrototype.originalShowItem;
|
||||
}
|
||||
}
|
||||
|
||||
async loadSettings() {
|
||||
|
||||
}
|
||||
|
||||
async saveSettings() {
|
||||
if (this.favoritePlugins) {
|
||||
if (this.favoritePlugins.length > 0) {
|
||||
localStorage.setItem('favorite-plugins', JSON.stringify(this.favoritePlugins));
|
||||
}
|
||||
|
||||
if (this.uninstallCommunityPluginsSettingTabPatch) {
|
||||
// console.debug('Uninstall CommunityPluginsSettingTab patch');
|
||||
this.uninstallCommunityPluginsSettingTabPatch();
|
||||
this.uninstallCommunityPluginsSettingTabPatch = undefined;
|
||||
}
|
||||
|
||||
if (this.uninstallCommunityThemeModalPatch) {
|
||||
// console.debug('Uninstall CommunityThemeModal patch');
|
||||
this.uninstallCommunityThemeModalPatch();
|
||||
this.uninstallCommunityThemeModalPatch = undefined;
|
||||
}
|
||||
|
||||
if (this.uninstallModalPatch) {
|
||||
// console.debug('Uninstall Modal patch');
|
||||
this.uninstallModalPatch();
|
||||
this.uninstallModalPatch = undefined;
|
||||
}
|
||||
|
||||
if (this.uninstallPluginManagerPatch) {
|
||||
// console.debug('Uninstall PluginManager patch');
|
||||
this.uninstallPluginManagerPatch();
|
||||
this.uninstallPluginManagerPatch = undefined;
|
||||
}
|
||||
|
||||
if (this.uninstallSettingsModalPatch) {
|
||||
// console.debug('Uninstall SettingsModal patch');
|
||||
this.uninstallSettingsModalPatch();
|
||||
this.uninstallSettingsModalPatch = undefined;
|
||||
}
|
||||
|
||||
if (this.uninstallStyleManagerPatch) {
|
||||
// console.debug('Uninstall StyleManager patch');
|
||||
this.uninstallStyleManagerPatch();
|
||||
this.uninstallStyleManagerPatch = undefined;
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
console.error('Failed uninstalling patch functions!');
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
loadStorageKeys() {
|
||||
// favorite keys
|
||||
if (process.env.FAVORITE_PLUGINS_KEY) {
|
||||
this.pluginFavoritesKey = process.env.FAVORITE_PLUGINS_KEY;
|
||||
}
|
||||
else {
|
||||
throw Error('Missing environment variable \'FAVORITE_PLUGINS_KEY\'');
|
||||
}
|
||||
if (process.env.FAVORITE_THEMES_KEY) {
|
||||
this.themeFavoritesKey = process.env.FAVORITE_THEMES_KEY;
|
||||
}
|
||||
else {
|
||||
throw Error('Missing environment variable \'FAVORITE_THEMES_KEY\'');
|
||||
}
|
||||
|
||||
// console.debug(`Plugins favorite key: ${this.pluginFavoritesKey} Themes favorite key: ${this.themeFavoritesKey}`);
|
||||
|
||||
// In use keys
|
||||
if (process.env.INUSE_PLUGINS_KEY) {
|
||||
this.pluginInUseKey = process.env.INUSE_PLUGINS_KEY;
|
||||
}
|
||||
else {
|
||||
throw Error('Missing environment variable \'INUSE_PLUGINS_KEY\'');
|
||||
}
|
||||
if (process.env.INUSE_THEMES_KEY) {
|
||||
this.themeInUseKey = process.env.INUSE_THEMES_KEY;
|
||||
}
|
||||
else {
|
||||
throw Error('Missing environment variable \'INUSE_THEMES_KEY\'');
|
||||
}
|
||||
|
||||
// console.debug(`Plugins in use key: ${this.pluginInUseKey} Themes in use key: ${this.themeInUseKey}`);
|
||||
|
||||
// Known keys
|
||||
if (process.env.KNOWN_PLUGINS_KEY) {
|
||||
this.pluginKnownKey = process.env.KNOWN_PLUGINS_KEY;
|
||||
}
|
||||
else {
|
||||
throw Error('Missing environment variable \'KNOWN_PLUGINS_KEY\'');
|
||||
}
|
||||
if (process.env.KNOWN_THEMES_KEY) {
|
||||
this.themeKnownKey = process.env.KNOWN_THEMES_KEY;
|
||||
}
|
||||
else {
|
||||
throw Error('Missing environment variable \'KNOWN_THEMES_KEY\'');
|
||||
}
|
||||
|
||||
// console.debug(`Plugins known key: ${this.pluginKnownKey} Themes known key: ${this.themeKnownKey}`);
|
||||
|
||||
// Register for storage key changes
|
||||
this.registerDomEvent(window, 'storage', (event) => {
|
||||
if (event.key === this.pluginFavoritesKey) {
|
||||
// console.debug('Plugins favorites key content changed', event);
|
||||
this.onFavoritePluginsChanged(event.newValue);
|
||||
}
|
||||
if (event.key === this.themeFavoritesKey) {
|
||||
// console.debug('Themes favorites key content changed', event);
|
||||
this.onFavoriteThemesChanged(event.newValue);
|
||||
}
|
||||
if (event.key === this.pluginInUseKey) {
|
||||
// console.debug('Plugins in use key content changed', event);
|
||||
this.onInUsePluginsChanged(event.newValue);
|
||||
}
|
||||
if (event.key === this.themeInUseKey) {
|
||||
// console.debug('Themes in use key content changed', event);
|
||||
this.onInUseThemesChanged(event.newValue);
|
||||
}
|
||||
if (event.key === this.pluginKnownKey) {
|
||||
// console.debug('Plugins known key content changed', event);
|
||||
this.onKnownPluginsChanged(event.newValue);
|
||||
}
|
||||
if (event.key === this.themeKnownKey) {
|
||||
// console.debug('Themes known key content changed', event);
|
||||
this.onKnownThemesChanged(event.newValue);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onFavoritePluginsChanged(newValue: string | null) {
|
||||
// console.debug(`onFavoritePluginsChanged: ${newValue}`);
|
||||
if (newValue) {
|
||||
this.favoritePlugins = JSON.parse(newValue);
|
||||
}
|
||||
else {
|
||||
this.favoritePlugins = [];
|
||||
}
|
||||
}
|
||||
|
||||
onFavoriteThemesChanged(newValue: string | null) {
|
||||
// console.debug(`onFavoriteThemesChanged: ${newValue}`);
|
||||
if (newValue) {
|
||||
this.favoriteThemes = JSON.parse(newValue);
|
||||
}
|
||||
else {
|
||||
this.favoriteThemes = [];
|
||||
}
|
||||
}
|
||||
|
||||
onInUsePluginsChanged(newValue: string | null) {
|
||||
// console.debug(`onInUsePluginsChanged: ${newValue}`);
|
||||
if (newValue) {
|
||||
this.inUsePlugins = JSON.parse(newValue);
|
||||
}
|
||||
else {
|
||||
this.inUsePlugins = {};
|
||||
}
|
||||
}
|
||||
|
||||
onInUseThemesChanged(newValue: string | null) {
|
||||
// console.debug(`onInUseThemesChanged: ${newValue}`);
|
||||
if (newValue) {
|
||||
this.inUseThemes = JSON.parse(newValue);
|
||||
}
|
||||
else {
|
||||
this.inUseThemes = {};
|
||||
}
|
||||
}
|
||||
|
||||
onKnownPluginsChanged(newValue: string | null) {
|
||||
// console.debug(`onKnownPluginsChanged: ${newValue}`);
|
||||
if (newValue) {
|
||||
this.knownPlugins = JSON.parse(newValue);
|
||||
}
|
||||
else {
|
||||
this.knownPlugins = [];
|
||||
}
|
||||
}
|
||||
|
||||
onKnownThemesChanged(newValue: string | null) {
|
||||
// console.debug(`onKnownThemesChanged: ${newValue}`);
|
||||
if (newValue) {
|
||||
this.knownThemes = JSON.parse(newValue);
|
||||
}
|
||||
else {
|
||||
this.knownThemes = [];
|
||||
}
|
||||
}
|
||||
|
||||
loadFavoritePlugins() {
|
||||
// Load the favorite plugins
|
||||
this.favoritePlugins = JSON.parse(localStorage.getItem(this.pluginFavoritesKey) || '[]');
|
||||
}
|
||||
|
||||
loadFavoriteThemes() {
|
||||
// Load the favorite plugins
|
||||
this.favoriteThemes = JSON.parse(localStorage.getItem(this.themeFavoritesKey) || '[]');
|
||||
}
|
||||
|
||||
loadInUsePlugins() {
|
||||
// Load the in use plugins
|
||||
this.inUsePlugins = JSON.parse(localStorage.getItem(this.pluginInUseKey) || '{}');
|
||||
}
|
||||
|
||||
loadInUseThemes() {
|
||||
// Load the in use plugins
|
||||
this.inUseThemes = JSON.parse(localStorage.getItem(this.themeInUseKey) || '{}');
|
||||
}
|
||||
|
||||
loadKnownPlugins() {
|
||||
// Load the known plugins
|
||||
this.knownPlugins = JSON.parse(localStorage.getItem(this.pluginKnownKey) || '[]');
|
||||
}
|
||||
|
||||
loadKnownThemes() {
|
||||
// Load the known plugins
|
||||
this.knownThemes = JSON.parse(localStorage.getItem(this.themeKnownKey) || '[]');
|
||||
}
|
||||
|
||||
loadLists() {
|
||||
this.loadFavoritePlugins();
|
||||
this.loadFavoriteThemes();
|
||||
this.loadInUsePlugins();
|
||||
this.loadInUseThemes();
|
||||
this.loadKnownPlugins();
|
||||
this.loadKnownThemes();
|
||||
}
|
||||
|
||||
saveFavoritePlugins() {
|
||||
if (this.favoritePlugins.length > 0) {
|
||||
localStorage.setItem(this.pluginFavoritesKey, JSON.stringify(this.favoritePlugins));
|
||||
}
|
||||
else {
|
||||
localStorage.removeItem(this.pluginFavoritesKey);
|
||||
}
|
||||
}
|
||||
|
||||
saveFavoriteThemes() {
|
||||
if (this.favoriteThemes.length > 0) {
|
||||
localStorage.setItem(this.themeFavoritesKey, JSON.stringify(this.favoriteThemes));
|
||||
}
|
||||
else {
|
||||
localStorage.removeItem(this.themeFavoritesKey);
|
||||
}
|
||||
}
|
||||
|
||||
saveInUsePlugins() {
|
||||
if (Object.keys(this.inUsePlugins).length > 0) {
|
||||
localStorage.setItem(this.pluginInUseKey, JSON.stringify(this.inUsePlugins));
|
||||
}
|
||||
else {
|
||||
localStorage.removeItem(this.pluginInUseKey);
|
||||
}
|
||||
}
|
||||
|
||||
saveInUseThemes() {
|
||||
if (Object.keys(this.inUseThemes).length > 0) {
|
||||
localStorage.setItem(this.themeInUseKey, JSON.stringify(this.inUseThemes));
|
||||
}
|
||||
else {
|
||||
localStorage.removeItem(this.themeInUseKey);
|
||||
}
|
||||
}
|
||||
|
||||
saveKnownPlugins() {
|
||||
if (this.knownPlugins.length > 0) {
|
||||
localStorage.setItem(this.pluginKnownKey, JSON.stringify(this.knownPlugins));
|
||||
}
|
||||
else {
|
||||
localStorage.removeItem(this.pluginKnownKey);
|
||||
}
|
||||
}
|
||||
|
||||
saveKnownThemes() {
|
||||
if (this.knownThemes.length > 0) {
|
||||
localStorage.setItem(this.themeKnownKey, JSON.stringify(this.knownThemes));
|
||||
}
|
||||
else {
|
||||
localStorage.removeItem(this.themeKnownKey);
|
||||
}
|
||||
}
|
||||
|
||||
saveLists() {
|
||||
this.saveFavoritePlugins();
|
||||
this.saveFavoriteThemes();
|
||||
this.saveInUsePlugins();
|
||||
this.saveInUseThemes();
|
||||
this.saveKnownPlugins();
|
||||
this.saveKnownThemes();
|
||||
}
|
||||
|
||||
updateListsForVault() {
|
||||
const currentVault = this.app.appId;
|
||||
|
||||
// Check the installed plugins and update known plugins list
|
||||
for (const id of Object.keys(this.app.plugins.manifests)) {
|
||||
// Add Plugin to known list if not already
|
||||
if (!this.knownPlugins.contains(id)) {
|
||||
this.knownPlugins.push(id);
|
||||
else {
|
||||
localStorage.removeItem('favorite-plugins');
|
||||
}
|
||||
}
|
||||
|
||||
// Check the enabled plugins and update in use plugins list
|
||||
for (const id of this.app.plugins.enabledPlugins) {
|
||||
// Add the plugin to the in use list with this vault as user
|
||||
if (!this.inUsePlugins[id] || !Array.isArray(this.inUsePlugins[id])) {
|
||||
this.inUsePlugins[id] = [];
|
||||
if (this.favoriteThemes) {
|
||||
if (this.favoriteThemes.length > 0) {
|
||||
localStorage.setItem('favorite-themes', JSON.stringify(this.favoriteThemes));
|
||||
}
|
||||
if (!this.inUsePlugins[id].contains(currentVault)) {
|
||||
this.inUsePlugins[id].push(currentVault);
|
||||
else {
|
||||
localStorage.removeItem('favorite-themes');
|
||||
}
|
||||
}
|
||||
|
||||
// Check the in use plugins list does not contain old entries of this vault
|
||||
for (const id of Object.keys(this.inUsePlugins)) {
|
||||
if (Array.isArray(this.inUsePlugins[id]) && this.inUsePlugins[id].contains(currentVault)) {
|
||||
if (!this.app.plugins.enabledPlugins.has(id)) {
|
||||
this.inUsePlugins[id].remove(currentVault);
|
||||
|
||||
// Cleanup in use if last vault stops using it
|
||||
if (this.inUsePlugins[id].length <= 0) {
|
||||
delete this.inUsePlugins[id];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check the installed themes and update known themes list
|
||||
for (const name of Object.keys(this.app.customCss.themes)) {
|
||||
// Add theme to known list if not already
|
||||
if (!this.knownThemes.contains(name)) {
|
||||
this.knownThemes.push(name);
|
||||
}
|
||||
}
|
||||
|
||||
// Check the enabled theme and update in use themes list
|
||||
const name = this.app.customCss.theme;
|
||||
|
||||
// Ignore the default theme
|
||||
if (name !== '') {
|
||||
// Add the theme to the in use list with this vault as user
|
||||
if (!this.inUseThemes[name] || !Array.isArray(this.inUseThemes[name])) {
|
||||
this.inUseThemes[name] = [];
|
||||
}
|
||||
if (!this.inUseThemes[name].contains(currentVault)) {
|
||||
this.inUseThemes[name].push(currentVault);
|
||||
}
|
||||
}
|
||||
|
||||
// Check the in use themes list does not contain old entries of this vault
|
||||
for (const name of Object.keys(this.inUseThemes)) {
|
||||
if (Array.isArray(this.inUseThemes[name]) && this.inUseThemes[name].contains(currentVault)) {
|
||||
if (this.app.customCss.theme !== name) {
|
||||
this.inUseThemes[name].remove(currentVault);
|
||||
|
||||
// Cleanup in use if last vault stops using it
|
||||
if (this.inUseThemes[name].length <= 0) {
|
||||
delete this.inUseThemes[name];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.saveLists();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,35 +0,0 @@
|
|||
import { App, FuzzyMatch, FuzzySuggestModal, renderResults } from 'obsidian';
|
||||
|
||||
export class CommunitySuggestModal<T extends { name: string, author: string }> extends FuzzySuggestModal<T> {
|
||||
private items: T[] = [];
|
||||
private onSubmit: (result: T) => void = () => { };
|
||||
|
||||
constructor(app: App, title: string, items: T[], onSubmit: (result: T) => void) {
|
||||
super(app);
|
||||
this.setPlaceholder(title);
|
||||
this.items = items;
|
||||
this.onSubmit = onSubmit;
|
||||
}
|
||||
|
||||
getItemText(item: T): string {
|
||||
return `${item.name} ${item.author}`;
|
||||
}
|
||||
|
||||
getItems(): T[] {
|
||||
return this.items;
|
||||
}
|
||||
|
||||
onChooseItem(item: T): void {
|
||||
this.onSubmit(item);
|
||||
}
|
||||
|
||||
renderSuggestion(match: FuzzyMatch<T>, el: HTMLElement) {
|
||||
const titleEl = el.createDiv();
|
||||
renderResults(titleEl, match.item.name, match.match);
|
||||
|
||||
// Only render the matches in the author name.
|
||||
const authorEl = el.createEl('small');
|
||||
const offset = -(match.item.name.length + 1);
|
||||
renderResults(authorEl, match.item.author, match.match, offset);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
import { App, Modal, Setting } from 'obsidian';
|
||||
|
||||
export class DialogModal extends Modal {
|
||||
message: string;
|
||||
submit: string;
|
||||
submitWarning: boolean;
|
||||
deny: string;
|
||||
denyWarning: boolean;
|
||||
onSubmit: () => void;
|
||||
onDeny: () => void;
|
||||
|
||||
constructor(app: App, title: string, message: string, onSubmit: () => void, onDeny: () => void, submit = 'Agree', submitWarning = false, deny = 'Cancel', denyWarning = true) {
|
||||
super(app);
|
||||
|
||||
this.titleEl.setText(title);
|
||||
|
||||
this.message = message;
|
||||
this.onSubmit = onSubmit;
|
||||
this.onDeny = onDeny;
|
||||
this.submit = submit;
|
||||
this.submitWarning = submitWarning;
|
||||
this.deny = deny;
|
||||
this.denyWarning = denyWarning;
|
||||
}
|
||||
|
||||
onOpen(): void {
|
||||
const { contentEl } = this;
|
||||
|
||||
if (this.message && this.message !== '') {
|
||||
contentEl.createEl('span', { text: this.message });
|
||||
}
|
||||
|
||||
const setting = new Setting(contentEl);
|
||||
if (this.submitWarning) {
|
||||
setting.addButton(button => button
|
||||
.setButtonText(this.submit)
|
||||
.setWarning()
|
||||
.onClick(() => {
|
||||
this.close();
|
||||
this.onSubmit();
|
||||
}));
|
||||
}
|
||||
else {
|
||||
setting.addButton(button => button
|
||||
.setButtonText(this.submit)
|
||||
.onClick(() => {
|
||||
this.close();
|
||||
this.onSubmit();
|
||||
}));
|
||||
}
|
||||
|
||||
if (this.denyWarning) {
|
||||
setting.addButton(button => button
|
||||
.setButtonText(this.deny)
|
||||
.setWarning()
|
||||
.onClick(() => {
|
||||
this.close();
|
||||
this.onDeny();
|
||||
}));
|
||||
}
|
||||
else {
|
||||
setting.addButton(button => button
|
||||
.setButtonText(this.deny)
|
||||
.onClick(() => {
|
||||
this.close();
|
||||
this.onDeny();
|
||||
}));
|
||||
}
|
||||
|
||||
setting.setClass('modal-buttons');
|
||||
}
|
||||
|
||||
onClose(): void {
|
||||
const { contentEl } = this;
|
||||
contentEl.empty();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
import { App, FuzzySuggestModal } from 'obsidian';
|
||||
|
||||
export class StringSuggestModal extends FuzzySuggestModal<string> {
|
||||
private items: string[] = [];
|
||||
onSubmit: (result: string) => void = () => { };
|
||||
|
||||
constructor(app: App, title: string, items: string[], onSubmit: (result: string) => void) {
|
||||
super(app);
|
||||
this.setPlaceholder(title);
|
||||
this.items = items;
|
||||
this.onSubmit = onSubmit;
|
||||
}
|
||||
|
||||
getItems(): string[] {
|
||||
return this.items;
|
||||
}
|
||||
getItemText(item: string): string {
|
||||
return item;
|
||||
}
|
||||
onChooseItem(item: string): void {
|
||||
this.onSubmit(item);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,100 +0,0 @@
|
|||
import { around, dedupe } from 'monkey-around';
|
||||
import MyPlugin from '../main';
|
||||
import { PLUGIN_ID } from 'src/constants';
|
||||
import { CommunityItem, CommunityPluginModal } from 'obsidian';
|
||||
import FavoriteFlair from 'src/ui-components/FavoriteFlair';
|
||||
import InUseFlair from 'src/ui-components/InUseFlair';
|
||||
import KnownFlair from 'src/ui-components/KnownFlair';
|
||||
import InstalledFlair from 'src/ui-components/InstalledFlair';
|
||||
|
||||
const MONKEY_KEY = `${PLUGIN_ID}-CommunityPluginModal-`;
|
||||
|
||||
export default (context: CommunityPluginModal, plugin: MyPlugin) => around(context.constructor.prototype, {
|
||||
showItem(oldMethod) {
|
||||
return dedupe(`${MONKEY_KEY}showItem`, oldMethod, async function (item: CommunityItem) {
|
||||
// console.debug('Call CommunityPluginModal.showItem');
|
||||
|
||||
const result = oldMethod && await oldMethod.apply(this, [item]);
|
||||
|
||||
const infoEl = await this.detailsEl.getElementsByClassName('community-modal-info')[0];
|
||||
const infoNameEl = await infoEl?.getElementsByClassName('community-modal-info-name')[0];
|
||||
const buttonContainerEl = await infoEl?.getElementsByClassName('community-modal-button-container')[0];
|
||||
|
||||
// Load the plugin lists
|
||||
plugin.loadFavoritePlugins();
|
||||
plugin.loadInUsePlugins();
|
||||
plugin.loadKnownPlugins();
|
||||
|
||||
// Add aria label to installed flair
|
||||
new InstalledFlair(infoNameEl);
|
||||
|
||||
// Add to the favorite plugins a flair to visualize it for the user
|
||||
const isFavorite = plugin.favoritePlugins.contains(this.selectedItemId);
|
||||
if (isFavorite) {
|
||||
new FavoriteFlair(infoNameEl);
|
||||
}
|
||||
|
||||
// Add to the in use plugins a flair to visualize it for the user
|
||||
if (Object.keys(plugin.inUsePlugins).contains(this.selectedItemId)) {
|
||||
new InUseFlair(infoNameEl);
|
||||
}
|
||||
|
||||
// Add to the known plugins a flair to visualize it for the user
|
||||
if (plugin.knownPlugins.contains(this.selectedItemId)) {
|
||||
new KnownFlair(infoNameEl);
|
||||
}
|
||||
|
||||
plugin.registerDomEvent(buttonContainerEl?.createEl('button', { text: isFavorite ? 'Unfavorite' : 'Favorite' }), 'click', async () => {
|
||||
if (isFavorite) {
|
||||
plugin.favoritePlugins.remove(this.selectedItemId);
|
||||
}
|
||||
else {
|
||||
plugin.favoritePlugins.push(this.selectedItemId);
|
||||
}
|
||||
|
||||
plugin.saveFavoritePlugins();
|
||||
|
||||
// Redraw
|
||||
infoEl.detach();
|
||||
await this.showItem(this.items[this.selectedItemId]);
|
||||
this.update();
|
||||
});
|
||||
|
||||
return result;
|
||||
});
|
||||
},
|
||||
updateItems(oldMethod) {
|
||||
return dedupe(`${MONKEY_KEY}updateItems`, oldMethod, function () {
|
||||
// console.debug('Call PluginBrowserModal.updateItems');
|
||||
|
||||
// Load the plugin lists
|
||||
plugin.loadFavoritePlugins();
|
||||
plugin.loadInUsePlugins();
|
||||
plugin.loadKnownPlugins();
|
||||
|
||||
const result = oldMethod && oldMethod.apply(this);
|
||||
|
||||
// Add aria label to installed flair
|
||||
Object.keys(plugin.app.plugins.manifests).forEach(id => {
|
||||
new InstalledFlair(this.items[id]?.nameEl);
|
||||
});
|
||||
|
||||
// Add to the favorite plugins a flair to visualize it for the user
|
||||
plugin.favoritePlugins.forEach(id => {
|
||||
new FavoriteFlair(this.items[id]?.nameEl);
|
||||
});
|
||||
|
||||
// Add to the in use plugins a flair to visualize it for the user
|
||||
Object.keys(plugin.inUsePlugins).forEach(id => {
|
||||
new InUseFlair(this.items[id]?.nameEl);
|
||||
});
|
||||
|
||||
// Add to the known plugins a flair to visualize it for the user
|
||||
plugin.knownPlugins.forEach(id => {
|
||||
new KnownFlair(this.items[id]?.nameEl);
|
||||
});
|
||||
|
||||
return result;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
import { CommunityItem, CommunityPluginsSettingTab, setIcon, setTooltip } from 'obsidian';
|
||||
import MyPlugin from '../main';
|
||||
import { around, dedupe } from 'monkey-around';
|
||||
import { PLUGIN_ID } from 'src/constants';
|
||||
|
||||
const MONKEY_KEY = `${PLUGIN_ID}-CommunityPluginsSettingTab-`;
|
||||
|
||||
export default (context: CommunityPluginsSettingTab, plugin: MyPlugin) => around(context, {
|
||||
renderInstalledPlugin(oldMethod) {
|
||||
return dedupe(`${MONKEY_KEY}renderInstalledPlugin`, oldMethod, function (item: CommunityItem, containerEl: HTMLElement, n: unknown, i: unknown, r: unknown) {
|
||||
// console.debug('Call CommunityPluginsSettingTab.renderInstalledPlugin');
|
||||
oldMethod && oldMethod.apply(this, [item, containerEl, n, i, r]);
|
||||
|
||||
// Load the favorite plugins
|
||||
plugin.loadFavoritePlugins();
|
||||
|
||||
const selectedPluginID = item.id;
|
||||
const isFavorite = plugin.favoritePlugins.contains(selectedPluginID);
|
||||
|
||||
const favEl = createDiv('clickable-icon extra-setting-button');
|
||||
|
||||
plugin.registerDomEvent(favEl, 'click', () => {
|
||||
if (isFavorite) {
|
||||
plugin.favoritePlugins.remove(selectedPluginID);
|
||||
}
|
||||
else {
|
||||
plugin.favoritePlugins.push(selectedPluginID);
|
||||
}
|
||||
|
||||
plugin.saveFavoritePlugins();
|
||||
|
||||
// Redraw
|
||||
this.render(false);
|
||||
});
|
||||
|
||||
if (isFavorite) {
|
||||
setIcon(favEl, 'star-off');
|
||||
setTooltip(favEl, 'Unfavorite');
|
||||
}
|
||||
else {
|
||||
setIcon(favEl, 'star');
|
||||
setTooltip(favEl, 'Favorite');
|
||||
}
|
||||
|
||||
// Add Favorite Icon to plugin control
|
||||
const controlEl: HTMLElement = this.installedPlugins.listEl.lastChild?.getElementsByClassName('setting-item-control')[0];
|
||||
controlEl.insertBefore(favEl, controlEl.children[0]);
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
@ -1,114 +0,0 @@
|
|||
import { CommunityItem, CommunityThemeModal } from 'obsidian';
|
||||
import MyPlugin from '../main';
|
||||
import { around, dedupe } from 'monkey-around';
|
||||
import { PLUGIN_ID } from 'src/constants';
|
||||
import InstalledFlair from 'src/ui-components/InstalledFlair';
|
||||
import FavoriteFlair from 'src/ui-components/FavoriteFlair';
|
||||
import InUseFlair from 'src/ui-components/InUseFlair';
|
||||
import KnownFlair from 'src/ui-components/KnownFlair';
|
||||
import ActiveFlair from 'src/ui-components/ActiveFlair';
|
||||
|
||||
const MONKEY_KEY = `${PLUGIN_ID}-ThemePluginModal-`;
|
||||
|
||||
export default (context: CommunityThemeModal, plugin: MyPlugin) => around(context.constructor.prototype, {
|
||||
showItem(oldMethod) {
|
||||
return dedupe(`${MONKEY_KEY}showItem`, oldMethod, async function (item: CommunityItem) {
|
||||
// console.debug('Call CommunityThemeModal.showItem');
|
||||
|
||||
const result = oldMethod && await oldMethod.apply(this, [item]);
|
||||
|
||||
const infoEl = await this.detailsEl.getElementsByClassName('community-modal-info')[0];
|
||||
const infoNameEl = await infoEl?.getElementsByClassName('community-modal-info-name')[0];
|
||||
|
||||
// Add aria label to installed flair
|
||||
new InstalledFlair(infoNameEl);
|
||||
|
||||
// Ignore the default theme
|
||||
if (this.selectedItemId === '') {
|
||||
return result;
|
||||
}
|
||||
const buttonContainerEl = await infoEl?.getElementsByClassName('community-modal-button-container')[0];
|
||||
|
||||
// Load the theme lists
|
||||
plugin.loadFavoriteThemes();
|
||||
plugin.loadInUseThemes();
|
||||
plugin.loadKnownThemes();
|
||||
|
||||
// Add to the favorite themes a flair to visualize it for the user
|
||||
const isFavorite = plugin.favoriteThemes.contains(this.selectedItemId);
|
||||
if (isFavorite) {
|
||||
new FavoriteFlair(infoNameEl);
|
||||
}
|
||||
|
||||
// Add to the in use themes a flair to visualize it for the user
|
||||
if (Object.keys(plugin.inUseThemes).contains(this.selectedItemId)) {
|
||||
new InUseFlair(infoNameEl);
|
||||
}
|
||||
|
||||
// Add to the known themes a flair to visualize it for the user
|
||||
if (plugin.knownThemes.contains(this.selectedItemId)) {
|
||||
new KnownFlair(infoNameEl);
|
||||
}
|
||||
|
||||
plugin.registerDomEvent(buttonContainerEl?.createEl('button', { text: isFavorite ? 'Unfavorite' : 'Favorite' }), 'click', async () => {
|
||||
if (isFavorite) {
|
||||
plugin.favoriteThemes.remove(this.selectedItemId);
|
||||
}
|
||||
else {
|
||||
plugin.favoriteThemes.push(this.selectedItemId);
|
||||
}
|
||||
|
||||
plugin.saveFavoriteThemes();
|
||||
|
||||
// Redraw
|
||||
infoEl.detach();
|
||||
await this.showItem(this.items[this.selectedItemId]);
|
||||
this.update();
|
||||
});
|
||||
|
||||
return result;
|
||||
});
|
||||
},
|
||||
updateItems(oldMethod) {
|
||||
return dedupe(`${MONKEY_KEY}updateItems`, oldMethod, function () {
|
||||
// console.debug('Call CommunityThemeModal.updateItems');
|
||||
|
||||
// Load the theme lists
|
||||
plugin.loadFavoriteThemes();
|
||||
plugin.loadInUseThemes();
|
||||
plugin.loadKnownThemes();
|
||||
|
||||
const result = oldMethod && oldMethod.apply(this);
|
||||
|
||||
// Add aria label to installed flair
|
||||
Object.keys(plugin.app.customCss.themes).forEach(id => {
|
||||
new InstalledFlair(this.items[id]?.nameEl);
|
||||
});
|
||||
|
||||
// Add aria label to active flair
|
||||
new ActiveFlair(this.items[plugin.app.customCss.theme]?.nameEl);
|
||||
|
||||
// Ignore the default theme
|
||||
if (this.selectedItemId === '') {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Add to the favorite themes a flair to visualize it for the user
|
||||
plugin.favoriteThemes.forEach(id => {
|
||||
new FavoriteFlair(this.items[id]?.nameEl);
|
||||
});
|
||||
|
||||
// Add to the in use themes a flair to visualize it for the user
|
||||
Object.keys(plugin.inUseThemes).forEach(id => {
|
||||
new InUseFlair(this.items[id]?.nameEl);
|
||||
});
|
||||
|
||||
// Add to the known themes a flair to visualize it for the user
|
||||
plugin.knownThemes.forEach(id => {
|
||||
new KnownFlair(this.items[id]?.nameEl);
|
||||
});
|
||||
|
||||
return result;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
import { Modal } from 'obsidian';
|
||||
import MyPlugin from '../main';
|
||||
import { around, dedupe } from 'monkey-around';
|
||||
import { PLUGIN_ID } from 'src/constants';
|
||||
import patchCommunityPluginModal from './patch.CommunityPluginModal';
|
||||
import patchCommunityThemeModal from './patch.CommunityThemeModal';
|
||||
|
||||
const MONKEY_KEY = `${PLUGIN_ID}-Modal-`;
|
||||
|
||||
export default (plugin: MyPlugin) => around(Modal.prototype, {
|
||||
open(oldMethod) {
|
||||
return dedupe(`${MONKEY_KEY}open`, oldMethod, function () {
|
||||
// console.debug('Call Modal.open');
|
||||
const result = oldMethod && oldMethod.apply(this);
|
||||
|
||||
// Check the opened Modal is the Community plugin browse modal
|
||||
if (this.containerEl?.querySelector('.mod-community-plugin')) {
|
||||
// Patch CommunityPluginModal
|
||||
if (!plugin.uninstallCommunityPluginModalPatch) {
|
||||
// console.debug('Patch CommunityPluginModal');
|
||||
plugin.uninstallCommunityPluginModalPatch = patchCommunityPluginModal(this, plugin);
|
||||
}
|
||||
}
|
||||
|
||||
// Check the opened Modal is the Community themes browse modal
|
||||
if (this.containerEl?.querySelector('.mod-community-theme')) {
|
||||
// Patch CommunityThemeModal
|
||||
if (!plugin.uninstallCommunityThemeModalPatch) {
|
||||
// console.debug('Patch CommunityThemeModal');
|
||||
plugin.uninstallCommunityThemeModalPatch = patchCommunityThemeModal(this, plugin);
|
||||
}
|
||||
}
|
||||
|
||||
if (plugin.uninstallModalPatch && plugin.uninstallCommunityPluginModalPatch && plugin.uninstallCommunityThemeModalPatch) {
|
||||
// console.debug('Uninstall Modal patch');
|
||||
plugin.uninstallModalPatch();
|
||||
plugin.uninstallModalPatch = undefined;
|
||||
}
|
||||
|
||||
return result;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
import MyPlugin from '../main';
|
||||
import { around, dedupe } from 'monkey-around';
|
||||
import { PluginManifest } from 'obsidian';
|
||||
import { PLUGIN_ID } from 'src/constants';
|
||||
|
||||
const MONKEY_KEY = `${PLUGIN_ID}-PluginManager-`;
|
||||
|
||||
export default (plugin: MyPlugin) => around(plugin.app.plugins, {
|
||||
installPlugin(oldMethod) {
|
||||
return dedupe(`${MONKEY_KEY}installPlugin`, oldMethod, async function (repo: string, version: string, manifest: PluginManifest) {
|
||||
// console.debug('Call PluginManager.installPlugin');
|
||||
|
||||
const result = oldMethod && await oldMethod.apply(this, [repo, version, manifest]);
|
||||
|
||||
// Load the plugin lists
|
||||
plugin.loadKnownPlugins();
|
||||
|
||||
// Add Plugin to known list if not already
|
||||
if (!plugin.knownPlugins.contains(manifest.id)) {
|
||||
plugin.knownPlugins.push(manifest.id);
|
||||
}
|
||||
|
||||
plugin.saveKnownPlugins();
|
||||
|
||||
return result;
|
||||
});
|
||||
},
|
||||
loadPlugin(oldMethod) {
|
||||
return dedupe(`${MONKEY_KEY}loadPlugin`, oldMethod, async function (id: string) {
|
||||
// console.debug('Call PluginManager.loadPlugin');
|
||||
|
||||
const currentVault = plugin.app.appId;
|
||||
|
||||
// Load the plugin lists
|
||||
plugin.loadInUsePlugins();
|
||||
|
||||
// Add the plugin to the in use list with this vault as user
|
||||
if (!plugin.inUsePlugins[id] || !Array.isArray(plugin.inUsePlugins[id])) {
|
||||
plugin.inUsePlugins[id] = [];
|
||||
}
|
||||
if (!plugin.inUsePlugins[id].contains(currentVault)) {
|
||||
plugin.inUsePlugins[id].push(currentVault);
|
||||
}
|
||||
|
||||
plugin.saveInUsePlugins();
|
||||
|
||||
return oldMethod && oldMethod.apply(this, [id]);
|
||||
});
|
||||
},
|
||||
unloadPlugin(oldMethod) {
|
||||
return dedupe(`${MONKEY_KEY}unloadPlugin`, oldMethod, async function (id: string) {
|
||||
// console.debug('Call PluginManager.unloadPlugin');
|
||||
|
||||
const currentVault = plugin.app.appId;
|
||||
|
||||
// Load the plugin lists
|
||||
plugin.loadInUsePlugins();
|
||||
|
||||
// Remove current vault from unloaded plugin
|
||||
if (plugin.inUsePlugins[id] && Array.isArray(plugin.inUsePlugins[id]) && plugin.inUsePlugins[id].contains(currentVault)) {
|
||||
plugin.inUsePlugins[id].remove(currentVault);
|
||||
|
||||
// Cleanup in use if last vault stops using it
|
||||
if (plugin.inUsePlugins[id].length <= 0) {
|
||||
delete plugin.inUsePlugins[id];
|
||||
}
|
||||
}
|
||||
|
||||
plugin.saveInUsePlugins();
|
||||
|
||||
return oldMethod && oldMethod.apply(this, [id]);
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
import { CommunityPluginsSettingTab, SettingsModal, SettingTab } from 'obsidian';
|
||||
import MyPlugin from '../main';
|
||||
import { around, dedupe } from 'monkey-around';
|
||||
import { PLUGIN_ID } from 'src/constants';
|
||||
import patchCommunityPluginsSettingTab from './patch.CommunityPluginsSettingTab';
|
||||
|
||||
const MONKEY_KEY = `${PLUGIN_ID}-SettingsModal-`;
|
||||
|
||||
export default (plugin: MyPlugin) => around(plugin.app.setting as SettingsModal, {
|
||||
openTab(oldMethod) {
|
||||
return dedupe(`${MONKEY_KEY}openTab`, oldMethod, function (tab: SettingTab) {
|
||||
// console.debug('Call SettingsModal.openTab');
|
||||
|
||||
if (tab.id === 'community-plugins') {
|
||||
if (!plugin.uninstallCommunityPluginsSettingTabPatch) {
|
||||
// console.debug('Patch CommunityPluginsSettingTab');
|
||||
plugin.uninstallCommunityPluginsSettingTabPatch = patchCommunityPluginsSettingTab(tab as CommunityPluginsSettingTab, plugin);
|
||||
}
|
||||
}
|
||||
|
||||
if (plugin.uninstallSettingsModalPatch && plugin.uninstallCommunityPluginsSettingTabPatch) {
|
||||
// console.debug('Uninstall SettingsModal patch');
|
||||
plugin.uninstallSettingsModalPatch();
|
||||
plugin.uninstallSettingsModalPatch = undefined;
|
||||
}
|
||||
|
||||
return oldMethod && oldMethod.apply(this, [tab]);
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
import MyPlugin from '../main';
|
||||
import { around, dedupe } from 'monkey-around';
|
||||
import { ThemeManifest } from 'obsidian';
|
||||
import { PLUGIN_ID } from 'src/constants';
|
||||
|
||||
const MONKEY_KEY = `${PLUGIN_ID}-StyleManager-installTheme`;
|
||||
|
||||
export default (plugin: MyPlugin) => around(plugin.app.customCss, {
|
||||
installTheme(oldMethod) {
|
||||
return dedupe(`${MONKEY_KEY}installTheme`, oldMethod, async function (manifest: ThemeManifest, version: string) {
|
||||
// console.debug('Call StyleManager.installTheme');
|
||||
|
||||
const result = oldMethod && await oldMethod.apply(this, [manifest, version]);
|
||||
|
||||
// Load the theme lists
|
||||
plugin.loadKnownThemes();
|
||||
|
||||
// Add Theme to known list if not already
|
||||
if (!plugin.knownThemes.contains(manifest.name)) {
|
||||
plugin.knownThemes.push(manifest.name);
|
||||
}
|
||||
|
||||
plugin.saveKnownThemes();
|
||||
|
||||
return result;
|
||||
});
|
||||
},
|
||||
setTheme(oldMethod) {
|
||||
return dedupe(`${MONKEY_KEY}setTheme`, oldMethod, function (name: string) {
|
||||
// console.debug('Call StyleManager.setTheme', this);
|
||||
|
||||
const currentVault = plugin.app.appId;
|
||||
|
||||
// Load the theme lists
|
||||
plugin.loadInUseThemes();
|
||||
|
||||
// Remove current vault from replaced theme
|
||||
const oldTheme = this.theme;
|
||||
if (plugin.inUseThemes[oldTheme] && Array.isArray(plugin.inUseThemes[oldTheme]) && plugin.inUseThemes[oldTheme].contains(currentVault)) {
|
||||
plugin.inUseThemes[oldTheme].remove(currentVault);
|
||||
|
||||
// Cleanup in use if last vault stops using it
|
||||
if (plugin.inUseThemes[oldTheme].length <= 0) {
|
||||
delete plugin.inUseThemes[oldTheme];
|
||||
}
|
||||
}
|
||||
|
||||
const result = oldMethod && oldMethod.apply(this, [name]);
|
||||
|
||||
// Ignore the default theme
|
||||
if (name === '') {
|
||||
plugin.saveInUseThemes();
|
||||
return result;
|
||||
}
|
||||
|
||||
// Add the theme to the in use list with this vault as user
|
||||
if (!plugin.inUseThemes[name] || !Array.isArray(plugin.inUseThemes[name])) {
|
||||
plugin.inUseThemes[name] = [];
|
||||
}
|
||||
if (!plugin.inUseThemes[name].contains(currentVault)) {
|
||||
plugin.inUseThemes[name].push(currentVault);
|
||||
}
|
||||
|
||||
plugin.saveInUseThemes();
|
||||
|
||||
return result;
|
||||
});
|
||||
},
|
||||
});
|
||||
195
src/types.d.ts
vendored
195
src/types.d.ts
vendored
|
|
@ -1,200 +1,37 @@
|
|||
import { } from 'obsidian';
|
||||
|
||||
declare module 'obsidian' {
|
||||
interface App {
|
||||
appId: string;
|
||||
setting: SettingsModal;
|
||||
plugins: PluginManager;
|
||||
customCss: StyleManager;
|
||||
}
|
||||
|
||||
interface ThemeManifest {
|
||||
author: string;
|
||||
authorUrl: string;
|
||||
dir: string;
|
||||
minAppVersion: string;
|
||||
name: string;
|
||||
version: string;
|
||||
}
|
||||
|
||||
interface CommunityItem {
|
||||
id: string;
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
interface CommunityModal extends Modal {
|
||||
sortOrder: string;
|
||||
items: unknown;
|
||||
itemsVisible: unknown;
|
||||
selectedItemId: string | null;
|
||||
dimBackground: unknown;
|
||||
onCloseCallback: () => void;
|
||||
interface CommunityModal {
|
||||
update(): void;
|
||||
returnToGridView(): void;
|
||||
selectItem(id: string | null): unknown;
|
||||
showSortMenu(event: unknown): void;
|
||||
sortItems(items: unknown): unknown;
|
||||
scrollIntoView(): unknown;
|
||||
addCustomControls(): unknown;
|
||||
updateItems(): CommunityItem[];
|
||||
showItem(item: CommunityItem): Promise<void>;
|
||||
}
|
||||
showItem(item: CommunityItem): void;
|
||||
|
||||
interface CommunityThemeModal extends CommunityModal {
|
||||
// ...
|
||||
|
||||
}
|
||||
|
||||
interface CommunityPluginModal extends CommunityModal {
|
||||
setAutoOpen(id: string): CommunityPluginModal;
|
||||
loadItems(): unknown;
|
||||
}
|
||||
|
||||
interface SettingsModal extends Modal {
|
||||
openTab(settingTab: SettingTab): void;
|
||||
}
|
||||
|
||||
interface SettingTab {
|
||||
// Additional from this plugin
|
||||
/**
|
||||
* This is the backup of the original ``updateItems()`` function. Do not use otherwise than restoring!
|
||||
*/
|
||||
originalUpdateItems?(): CommunityItem[];
|
||||
|
||||
/**
|
||||
* Used to identify the tab
|
||||
*
|
||||
* @private reverse engineered
|
||||
* This is the backup of the original ``showItem()`` function. Do not use otherwise than restoring!
|
||||
*/
|
||||
id: string;
|
||||
setting: unknown;
|
||||
navEl: HTMLElement;
|
||||
originalShowItem?(item: CommunityItem): void;
|
||||
}
|
||||
|
||||
interface CommunityPluginsSettingTab extends SettingTab {
|
||||
id: 'community-plugins';
|
||||
installedPlugins: {
|
||||
listEl: HTMLElement
|
||||
};
|
||||
|
||||
render(e: boolean): void;
|
||||
renderInstalledPlugin(plugin: CommunityItem, containerEl: HTMLElement, n: unknown, i: unknown, r: unknown): void;
|
||||
updateSearch(e: unknown): void
|
||||
}
|
||||
|
||||
interface HotkeysSettingTab extends SettingTab {
|
||||
name: string;
|
||||
id: 'hotkeys';
|
||||
setHotkeyScope: unknown;
|
||||
commandBeingCustomized: unknown;
|
||||
filterHotkeyScope: unknown;
|
||||
filterHotkeyEl: unknown;
|
||||
filterHotkeyActiveEl: unknown;
|
||||
hotkeyListContainerEl: unknown;
|
||||
hotkeyFilter: unknown;
|
||||
}
|
||||
|
||||
interface StyleManager extends Component {
|
||||
app: App;
|
||||
styleEl: HTMLStyleElement;
|
||||
extraStyleEls: HTMLStyleElement[];
|
||||
boundRaw: () => unknown;
|
||||
oldThemes: unknown[];
|
||||
interface Modal {
|
||||
|
||||
// Additional form this plugin
|
||||
/**
|
||||
* Holds the manifest of the installed themes in this vault
|
||||
*
|
||||
* @private reverse engineered
|
||||
* This is the backup of the original ``open()`` function. Do not use otherwise than restoring!
|
||||
*/
|
||||
themes: Record<string, ThemeManifest>;
|
||||
updates: Record<string, { themeInfo: unknown, version: string }>;
|
||||
snippets: string[];
|
||||
enabledSnippets: Set<string>;
|
||||
csscache: Map<number, unknown>;
|
||||
|
||||
/**
|
||||
* Holds the id of the enabled theme
|
||||
*
|
||||
* @private reverse engineered
|
||||
*/
|
||||
theme: string;
|
||||
requestLoadTheme: () => unknown;
|
||||
requestLoadSnippets: () => unknown;
|
||||
requestReadThemes: () => unknown;
|
||||
queue: unknown;
|
||||
|
||||
onload(): Promise<unknown>;
|
||||
loadData(): void;
|
||||
readThemes(e: unknown): unknown;
|
||||
readSnippets(e: unknown): unknown;
|
||||
onRaw(e: unknown): void;
|
||||
loadTheme(e: undefined): unknown;
|
||||
loadSnippets(): unknown;
|
||||
loadCss(path: string): Promise<unknown>;
|
||||
setCssEnabledStatus(e: unknown, t: unknown): void;
|
||||
setTheme(name: string): void;
|
||||
setTranslucency(e: unknown): void;
|
||||
enableTranslucency(): void;
|
||||
disableTranslucency(): void;
|
||||
getThemeFolder(): string;
|
||||
getSnippetsFolder(): string;
|
||||
getThemePath(e: unknown): string;
|
||||
getSnippetPath(e: unknown): string;
|
||||
removeTheme(e: unknown): Promise<unknown>;
|
||||
downloadLegacyTheme(e: unknown): Promise<unknown>;
|
||||
isThemeInstalled(e: unknown): unknown;
|
||||
hasUpdates(): unknown;
|
||||
checkForUpdate(e: unknown): Promise<unknown>;
|
||||
checkForUpdates(): Promise<unknown>;
|
||||
installLegacyTheme(e: unknown): Promise<unknown>;
|
||||
installTheme(manifest: ThemeManifest, version: string): Promise<unknown>;
|
||||
getManifest(e: unknown): Promise<unknown>;
|
||||
}
|
||||
|
||||
interface PluginManager {
|
||||
|
||||
/**
|
||||
* Holds the manifest of the installed plugins in this vault
|
||||
*
|
||||
* @private reverse engineered
|
||||
*/
|
||||
manifests: Record<string, PluginManifest>;
|
||||
|
||||
/**
|
||||
* Holds references to the loaded plugins identified by there id
|
||||
*
|
||||
* @private reverse engineered
|
||||
*/
|
||||
plugins: Record<string, Plugin>;
|
||||
|
||||
/**
|
||||
* Holds a the ids of the enabled plugins in this vault
|
||||
*
|
||||
* @private reverse engineered
|
||||
*/
|
||||
enabledPlugins: Set<string>;
|
||||
|
||||
/**
|
||||
* Holds the available updates identified by there id with information about the update
|
||||
*
|
||||
* @private reverse engineered
|
||||
*/
|
||||
updates: Record<string, { repo: string, version: string, manifest: PluginManifest }>;
|
||||
requestSaveConfig: () => unknown;
|
||||
app: App;
|
||||
|
||||
onRaw(e: unknown): void;
|
||||
loadManifests(): Promise<unknown>;
|
||||
loadManifest(path: string): Promise<unknown>;
|
||||
loadPlugin(id: string): Promise<unknown>;
|
||||
unloadPlugin(id: string): Promise<unknown>;
|
||||
initialize(): Promise<unknown>;
|
||||
getPluginFolder(): string;
|
||||
enablePlugin(id: string): Promise<unknown>;
|
||||
disablePlugin(id: string): Promise<unknown>;
|
||||
enablePluginAndSave(id: string): Promise<unknown>;
|
||||
disablePluginAndSave(id: string): Promise<unknown>;
|
||||
uninstallPlugin(id: string): Promise<unknown>;
|
||||
getPlugin(id: string): unknown | null;
|
||||
saveConfig(): Promise<unknown>;
|
||||
isEnabled(): boolean;
|
||||
setEnable(e: unknown): Promise<unknown>;
|
||||
checkForDeprecations(): Promise<unknown>;
|
||||
isDeprecated(e: unknown): unknown;
|
||||
installPlugin(repo: string, version: string, manifest: PluginManifest): Promise<unknown>;
|
||||
checkForUpdates(): Promise<unknown>;
|
||||
originalOpen?(): void;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
export default class ActiveFlair {
|
||||
constructor(parentEl: HTMLElement) {
|
||||
if (parentEl) {
|
||||
const flair = Array.from(parentEl.getElementsByClassName('flair')).find(el => el.textContent?.trim().toLowerCase() === 'active');
|
||||
|
||||
if (flair) {
|
||||
flair.setAttribute('aria-label', 'Active theme in this vault');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
import Flair from './Flair';
|
||||
|
||||
export default class FavoriteFlair extends Flair {
|
||||
constructor(parentEl: HTMLElement) {
|
||||
super(parentEl, 'Favorite', 'Marked as favorite');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
export default class Flair {
|
||||
constructor(parentEl: HTMLElement, text: string, ariaLabel: string | null = null) {
|
||||
if (parentEl) {
|
||||
const flair = parentEl.createSpan({
|
||||
cls: 'flair',
|
||||
text: text,
|
||||
});
|
||||
if (ariaLabel) {
|
||||
flair.setAttribute('aria-label', ariaLabel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
import Flair from './Flair';
|
||||
|
||||
export default class InUseFlair extends Flair {
|
||||
constructor(parentEl: HTMLElement) {
|
||||
super(parentEl, 'In Use', 'Enabled in at least one vault');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
export default class InstalledFlair {
|
||||
constructor(parentEl: HTMLElement) {
|
||||
if (parentEl) {
|
||||
const flair = Array.from(parentEl.getElementsByClassName('flair')).find(el => el.textContent?.trim().toLowerCase() === 'installed');
|
||||
|
||||
if (flair) {
|
||||
flair.setAttribute('aria-label', 'Installed in this vault');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
import Flair from './Flair';
|
||||
|
||||
export default class KnownFlair extends Flair {
|
||||
constructor(parentEl: HTMLElement) {
|
||||
super(parentEl, 'Known', 'Installed at least once in a vault');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
/**
|
||||
* Credits: https://github.com/TfTHacker/obsidian42-brat
|
||||
*/
|
||||
|
||||
import { request } from 'obsidian';
|
||||
|
||||
export interface CommunityEntry {
|
||||
name: string;
|
||||
author: string;
|
||||
repo: string;
|
||||
}
|
||||
|
||||
export interface CommunityPlugin extends CommunityEntry {
|
||||
id: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export interface CommunityTheme extends CommunityEntry {
|
||||
screenshot: string;
|
||||
modes: string[];
|
||||
legacy?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all community plugin entries.
|
||||
* @returns A list of community plugins
|
||||
*/
|
||||
export async function fetchCommunityPluginList(): Promise<CommunityPlugin[] | undefined> {
|
||||
const URL = 'https://raw.githubusercontent.com/obsidianmd/obsidian-releases/HEAD/community-plugins.json';
|
||||
try {
|
||||
// Do a request to the url
|
||||
const response = await request({ url: URL });
|
||||
|
||||
// Process the response
|
||||
return (await JSON.parse(response)) as CommunityPlugin[];
|
||||
}
|
||||
catch (e) {
|
||||
(e as Error).message = 'Failed to fetch community plugin list! ' + (e as Error).message;
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all community theme entries.
|
||||
* @returns A list of community themes
|
||||
*/
|
||||
export async function fetchCommunityThemeList(): Promise<CommunityTheme[] | undefined> {
|
||||
const URL = 'https://raw.githubusercontent.com/obsidianmd/obsidian-releases/refs/heads/master/community-css-themes.json';
|
||||
try {
|
||||
// Do a request to the url
|
||||
const response = await request({ url: URL });
|
||||
|
||||
// Process the response
|
||||
return (await JSON.parse(response)) as CommunityTheme[];
|
||||
}
|
||||
catch (e) {
|
||||
(e as Error).message = 'Failed to fetch community plugin list! ' + (e as Error).message;
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
.community-item-name {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
|
@ -1,11 +1,9 @@
|
|||
import { version as manifestVersion, minAppVersion as manifestMinAppVersion } from '../manifest.json';
|
||||
import { version as packageVersion } from '../package.json';
|
||||
import { version as packageLockVersion } from '../package.json';
|
||||
import versions from '../versions.json';
|
||||
|
||||
test('Versions matching', () => {
|
||||
expect(manifestVersion).toBe(packageVersion);
|
||||
expect(manifestVersion).toBe(packageLockVersion);
|
||||
expect(Object.keys(versions).find(value => value === manifestVersion)).toBe(manifestVersion);
|
||||
expect(Object.entries(versions).find(value => value[0] === manifestVersion)?.[1]).toBe(manifestMinAppVersion);
|
||||
});
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
import { execSync } from 'child_process';
|
||||
import { readFileSync, writeFileSync } from 'fs';
|
||||
import { valid } from 'semver';
|
||||
import { readFileSync, writeFileSync } from "fs";
|
||||
import { valid } from "semver";
|
||||
|
||||
const newVersion = process.argv.find(value => value.startsWith('--new_version'));
|
||||
if (!newVersion) {
|
||||
|
|
@ -15,30 +14,23 @@ if (!valid(targetVersion)) {
|
|||
}
|
||||
|
||||
// read minAppVersion from manifest.json
|
||||
let manifestFile = JSON.parse(readFileSync('manifest.json', 'utf8'));
|
||||
let manifestFile = JSON.parse(readFileSync("manifest.json", "utf8"));
|
||||
const { minAppVersion } = manifestFile;
|
||||
if (!minAppVersion || minAppVersion === '') {
|
||||
throw Error(`Missing minAppVersion in 'manifest.json'`);
|
||||
if (!minAppVersion || minAppVersion === "") {
|
||||
throw Error('Missing minAppVersion in "manifest.json"');
|
||||
}
|
||||
|
||||
// update version to target version
|
||||
manifestFile.version = targetVersion;
|
||||
writeFileSync('manifest.json', JSON.stringify(manifestFile, null, '\t'));
|
||||
writeFileSync("manifest.json", JSON.stringify(manifestFile, null, "\t"));
|
||||
|
||||
// update version in package
|
||||
let packageFile = JSON.parse(readFileSync('package.json', 'utf8'));
|
||||
let packageFile = JSON.parse(readFileSync("package.json", "utf8"));
|
||||
packageFile.version = targetVersion;
|
||||
writeFileSync('package.json', JSON.stringify(packageFile, null, '\t'));
|
||||
|
||||
// update version in package-lock
|
||||
try {
|
||||
execSync('npm install', { stdio: 'inherit' });
|
||||
} catch (error) {
|
||||
throw Error('npm installed failed: ' + error);
|
||||
}
|
||||
writeFileSync("package.json", JSON.stringify(packageFile, null, "\t"));
|
||||
|
||||
// read versions file
|
||||
let versionsFile = JSON.parse(readFileSync('versions.json', 'utf8'));
|
||||
let versionsFile = JSON.parse(readFileSync("versions.json", "utf8"));
|
||||
let keys = Object.keys(versionsFile);
|
||||
|
||||
// remove existing versions with same minAppVersion
|
||||
|
|
@ -50,4 +42,4 @@ keys.forEach(key => {
|
|||
|
||||
// update versions.json with target version and minAppVersion from manifest.json
|
||||
versionsFile[targetVersion] = minAppVersion;
|
||||
writeFileSync('versions.json', JSON.stringify(versionsFile, null, '\t'));
|
||||
writeFileSync("versions.json", JSON.stringify(versionsFile, null, "\t"));
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
{
|
||||
"1.4.0": "1.8.10"
|
||||
"1.0.0": "1.8.10"
|
||||
}
|
||||
Loading…
Reference in a new issue