mirror of
https://github.com/4source/favorites-obsidian-plugin.git
synced 2026-07-22 06:44:46 +00:00
[FEAT] Favorite/Unfavorite for installed plugins (#8)
* Fix favorite themes loading logic * Validate environment variables for favorite plugins and themes on load * Add community plugins settings tab favorite icon * Enhance README with usage details and screenshots Updated the README to clarify ease of use and added additional screenshots. * Security Audit fix
This commit is contained in:
parent
7303174298
commit
40c4930ba1
5 changed files with 204 additions and 78 deletions
19
README.md
19
README.md
|
|
@ -4,14 +4,12 @@ Stop re-searching the same plugins or themes in every vault. With one central li
|
|||
|
||||
# Features
|
||||
- **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
|
||||
- **Ease of Use** - Favorite/unfavorite directly inside the Obsidian's
|
||||
- Plugin browser
|
||||
- Community plugins tab
|
||||
- Theme 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.
|
||||
|
|
@ -19,6 +17,15 @@ 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="1104" height="1004" alt="image" src="https://github.com/user-attachments/assets/61b41e7b-4569-4509-95f3-d5e8a667d653" />
|
||||
|
||||
<img width="1100" height="1000" alt="image" src="https://github.com/user-attachments/assets/a0b35f98-b194-433f-bd9e-66eecb5dd111" />
|
||||
|
||||
<img width="1104" height="1004" alt="image" src="https://github.com/user-attachments/assets/960eac0d-fea2-48e1-8faf-e54a7504149e" />
|
||||
|
||||
# Contribution
|
||||
Feel free to contribute.
|
||||
|
||||
|
|
|
|||
99
package-lock.json
generated
99
package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "favorites",
|
||||
"version": "1.1.1",
|
||||
"version": "1.1.2",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "favorites",
|
||||
"version": "1.1.1",
|
||||
"version": "1.1.2",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@stylistic/eslint-plugin": "^3.1.0",
|
||||
|
|
@ -68,6 +68,7 @@
|
|||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz",
|
||||
"integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@ampproject/remapping": "^2.2.0",
|
||||
"@babel/code-frame": "^7.26.2",
|
||||
|
|
@ -1059,10 +1060,11 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@eslint/eslintrc/node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
|
||||
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
|
|
@ -1105,10 +1107,11 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@humanwhocodes/config-array/node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
|
||||
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
|
|
@ -1175,10 +1178,11 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": {
|
||||
"version": "3.14.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
|
||||
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
|
||||
"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==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"argparse": "^1.0.7",
|
||||
"esprima": "^4.0.0"
|
||||
|
|
@ -1574,8 +1578,7 @@
|
|||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz",
|
||||
"integrity": "sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==",
|
||||
"dev": true,
|
||||
"peer": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@nodelib/fs.scandir": {
|
||||
"version": "2.1.5",
|
||||
|
|
@ -1979,6 +1982,7 @@
|
|||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz",
|
||||
"integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "7.18.0",
|
||||
"@typescript-eslint/types": "7.18.0",
|
||||
|
|
@ -2156,6 +2160,7 @@
|
|||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
|
||||
"integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
|
|
@ -2207,10 +2212,11 @@
|
|||
}
|
||||
},
|
||||
"node_modules/ajv": {
|
||||
"version": "6.12.6",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
||||
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
||||
"version": "6.14.0",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz",
|
||||
"integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
|
|
@ -2490,6 +2496,7 @@
|
|||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"caniuse-lite": "^1.0.30001688",
|
||||
"electron-to-chromium": "^1.5.73",
|
||||
|
|
@ -3108,6 +3115,7 @@
|
|||
"integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
|
||||
"deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.2.0",
|
||||
"@eslint-community/regexpp": "^4.6.1",
|
||||
|
|
@ -3226,10 +3234,11 @@
|
|||
}
|
||||
},
|
||||
"node_modules/eslint/node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
|
||||
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
|
|
@ -3443,10 +3452,11 @@
|
|||
}
|
||||
},
|
||||
"node_modules/filelist/node_modules/minimatch": {
|
||||
"version": "5.1.6",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
|
||||
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
|
||||
"version": "5.1.9",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz",
|
||||
"integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
|
|
@ -3667,10 +3677,11 @@
|
|||
}
|
||||
},
|
||||
"node_modules/glob/node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
|
||||
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
|
|
@ -4118,10 +4129,11 @@
|
|||
}
|
||||
},
|
||||
"node_modules/jake/node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
|
||||
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
|
|
@ -4134,6 +4146,7 @@
|
|||
"resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz",
|
||||
"integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@jest/core": "^29.7.0",
|
||||
"@jest/types": "^29.6.3",
|
||||
|
|
@ -4730,10 +4743,11 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/js-yaml": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
|
||||
"integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1"
|
||||
},
|
||||
|
|
@ -5026,12 +5040,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "9.0.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
||||
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
|
||||
"version": "9.0.9",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
|
||||
"integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
"brace-expansion": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
|
|
@ -5806,8 +5821,7 @@
|
|||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz",
|
||||
"integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==",
|
||||
"dev": true,
|
||||
"peer": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/supports-color": {
|
||||
"version": "7.2.0",
|
||||
|
|
@ -5864,10 +5878,11 @@
|
|||
}
|
||||
},
|
||||
"node_modules/test-exclude/node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
|
||||
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
|
|
@ -6030,6 +6045,7 @@
|
|||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
|
||||
"integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
|
|
@ -6120,8 +6136,7 @@
|
|||
"version": "2.2.8",
|
||||
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
|
||||
"integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==",
|
||||
"dev": true,
|
||||
"peer": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/w3c-xmlserializer": {
|
||||
"version": "4.0.0",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
export const PLUGIN_ID = 'favorite';
|
||||
export const MONKEY_KEY_MODAL_OPEN = `${PLUGIN_ID}-Modal-open`;
|
||||
export const MONKEY_KEY_SETTINGS_MODAL_OPEN_TAB = `${PLUGIN_ID}-SettingsModal-openTab`;
|
||||
export const MONKEY_KEY_PLUGIN_BROWSER_MODAL_UPDATE_ITEMS = `${PLUGIN_ID}-CommunityPluginModal-updateItems`;
|
||||
export const MONKEY_KEY_PLUGIN_BROWSER_MODAL_SHOW_ITEMS = `${PLUGIN_ID}-CommunityPluginModal-showItems`;
|
||||
export const MONKEY_KEY_THEME_BROWSER_MODAL_UPDATE_ITEMS = `${PLUGIN_ID}-ThemePluginModal-updateItems`;
|
||||
export const MONKEY_KEY_THEME_BROWSER_MODAL_SHOW_ITEMS = `${PLUGIN_ID}-ThemePluginModal-showItems`;
|
||||
export const MONKEY_KEY_THEME_BROWSER_MODAL_SHOW_ITEMS = `${PLUGIN_ID}-ThemePluginModal-showItems`;
|
||||
export const MONKEY_KEY_COMMUNITY_PLUGIN_SETTINGS_TAB_RENDER_INSTALLED_PLUGIN = `${PLUGIN_ID}-CommunityPluginsSettingTab-renderInstalledPlugin`;
|
||||
112
src/main.ts
112
src/main.ts
|
|
@ -1,6 +1,6 @@
|
|||
import { CommunityItem, CommunityModal, Modal, Plugin } from 'obsidian';
|
||||
import { CommunityItem, CommunityModal, CommunityPluginsSettingTab, Modal, Plugin, setIcon, SettingsModal, SettingTab, setTooltip } from 'obsidian';
|
||||
import { dedupe, around } from 'monkey-around';
|
||||
import { MONKEY_KEY_PLUGIN_BROWSER_MODAL_UPDATE_ITEMS, MONKEY_KEY_MODAL_OPEN, MONKEY_KEY_THEME_BROWSER_MODAL_UPDATE_ITEMS, MONKEY_KEY_THEME_BROWSER_MODAL_SHOW_ITEMS, MONKEY_KEY_PLUGIN_BROWSER_MODAL_SHOW_ITEMS } from './constants';
|
||||
import { MONKEY_KEY_PLUGIN_BROWSER_MODAL_UPDATE_ITEMS, MONKEY_KEY_MODAL_OPEN, MONKEY_KEY_THEME_BROWSER_MODAL_UPDATE_ITEMS, MONKEY_KEY_THEME_BROWSER_MODAL_SHOW_ITEMS, MONKEY_KEY_PLUGIN_BROWSER_MODAL_SHOW_ITEMS, MONKEY_KEY_SETTINGS_MODAL_OPEN_TAB, MONKEY_KEY_COMMUNITY_PLUGIN_SETTINGS_TAB_RENDER_INSTALLED_PLUGIN } from './constants';
|
||||
|
||||
export default class FavoritesPlugin extends Plugin {
|
||||
pluginsKey: string;
|
||||
|
|
@ -10,19 +10,103 @@ export default class FavoritesPlugin extends Plugin {
|
|||
communityPluginModalPrototype?: CommunityModal;
|
||||
communityThemesModalPrototype?: CommunityModal;
|
||||
uninstallModalOpen?: () => void;
|
||||
uninstallSettingsModalOpenTab?: () => void;
|
||||
uninstallPluginBrowserModalUpdateItems?: () => void;
|
||||
uninstallPluginBrowserModalShowItem?: () => void;
|
||||
uninstallThemeBrowserModalUpdateItems?: () => void;
|
||||
uninstallThemeBrowserModalShowItem?: () => void;
|
||||
uninstallCommunityPluginsSettingTabRenderInstalledPlugin?: () => void;
|
||||
|
||||
onload() {
|
||||
this.pluginsKey = process.env.FAVORITE_PLUGINS_KEY || '';
|
||||
this.themesKey = process.env.FAVORITE_THEMES_KEY || '';
|
||||
if (process.env.FAVORITE_PLUGINS_KEY) {
|
||||
this.pluginsKey = process.env.FAVORITE_PLUGINS_KEY;
|
||||
}
|
||||
else {
|
||||
throw Error('Missing environment variable \'FAVORITE_PLUGINS_KEY\'');
|
||||
}
|
||||
if (process.env.FAVORITE_THEMES_KEY) {
|
||||
this.themesKey = process.env.FAVORITE_THEMES_KEY;
|
||||
}
|
||||
else {
|
||||
throw Error('Missing environment variable \'FAVORITE_THEMES_KEY\'');
|
||||
}
|
||||
console.debug(`Plugins key: ${this.pluginsKey} Themes key: ${this.themesKey}`);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-this-alias -- Is required because the this context wil change inside the 'monkey-around' functions but the plugin is required to be accessible
|
||||
const plugin = this;
|
||||
|
||||
// Patch the opening of SettingsModal
|
||||
if (!this.uninstallSettingsModalOpenTab) {
|
||||
console.debug('Patch SettingsModal.openTab');
|
||||
this.uninstallSettingsModalOpenTab = around(this.app.setting as SettingsModal, {
|
||||
openTab(oldMethod) {
|
||||
return dedupe(MONKEY_KEY_SETTINGS_MODAL_OPEN_TAB, oldMethod, function (...args) {
|
||||
console.debug('Call SettingsModal.openTab');
|
||||
|
||||
const tab = args[0] as SettingTab;
|
||||
if (tab.id === 'community-plugins') {
|
||||
if (!plugin.uninstallCommunityPluginsSettingTabRenderInstalledPlugin) {
|
||||
console.debug('Patch CommunityPluginsSettingTab.renderInstalledPlugin');
|
||||
plugin.uninstallCommunityPluginsSettingTabRenderInstalledPlugin = around((tab as CommunityPluginsSettingTab), {
|
||||
renderInstalledPlugin(oldMethod) {
|
||||
return dedupe(MONKEY_KEY_COMMUNITY_PLUGIN_SETTINGS_TAB_RENDER_INSTALLED_PLUGIN, oldMethod, function (...args) {
|
||||
console.debug('Call CommunityPluginsSettingTab.renderInstalledPlugin');
|
||||
oldMethod && oldMethod.apply(this, args);
|
||||
|
||||
// Load the favorite plugins
|
||||
plugin.loadFavoritePlugins();
|
||||
|
||||
const selectedPluginID = args[0].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.saveFavorites();
|
||||
|
||||
// Redraw
|
||||
(tab as CommunityPluginsSettingTab).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]);
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
else {
|
||||
console.debug('CommunityPluginsSettingTab.renderInstalledPlugin already patched!');
|
||||
}
|
||||
}
|
||||
|
||||
if (plugin.uninstallSettingsModalOpenTab && plugin.uninstallCommunityPluginsSettingTabRenderInstalledPlugin) {
|
||||
console.debug('Uninstall SettingsModal.openTab');
|
||||
plugin.uninstallSettingsModalOpenTab();
|
||||
plugin.uninstallSettingsModalOpenTab = undefined;
|
||||
}
|
||||
return oldMethod && oldMethod.apply(this, args);
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (!this.uninstallModalOpen) {
|
||||
console.debug('Patch Modal.open');
|
||||
this.uninstallModalOpen = around(Modal.prototype, {
|
||||
|
|
@ -64,7 +148,7 @@ export default class FavoritesPlugin extends Plugin {
|
|||
});
|
||||
}
|
||||
else {
|
||||
console.warn('PluginBrowserModal.updateItems already patched!');
|
||||
console.debug('PluginBrowserModal.updateItems already patched!');
|
||||
}
|
||||
|
||||
// Patch showItem method
|
||||
|
|
@ -118,7 +202,7 @@ export default class FavoritesPlugin extends Plugin {
|
|||
});
|
||||
}
|
||||
else {
|
||||
console.warn('PluginBrowserModal.showItem already patched!');
|
||||
console.debug('PluginBrowserModal.showItem already patched!');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -160,7 +244,7 @@ export default class FavoritesPlugin extends Plugin {
|
|||
});
|
||||
}
|
||||
else {
|
||||
console.warn('ThemeBrowserModal.updateItems already patched!');
|
||||
console.debug('ThemeBrowserModal.updateItems already patched!');
|
||||
}
|
||||
|
||||
// Patch showItems method
|
||||
|
|
@ -219,7 +303,7 @@ export default class FavoritesPlugin extends Plugin {
|
|||
});
|
||||
}
|
||||
else {
|
||||
console.warn('ThemeBrowserModal.showItem already patched!');
|
||||
console.debug('ThemeBrowserModal.showItem already patched!');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -254,6 +338,11 @@ export default class FavoritesPlugin extends Plugin {
|
|||
this.uninstallModalOpen();
|
||||
this.uninstallModalOpen = undefined;
|
||||
}
|
||||
if (this.uninstallSettingsModalOpenTab) {
|
||||
console.debug('Uninstall SettingsModal.openTab');
|
||||
this.uninstallSettingsModalOpenTab();
|
||||
this.uninstallSettingsModalOpenTab = undefined;
|
||||
}
|
||||
if (this.uninstallPluginBrowserModalUpdateItems) {
|
||||
console.debug('Uninstall PluginBrowserModal.updateItem');
|
||||
this.uninstallPluginBrowserModalUpdateItems();
|
||||
|
|
@ -274,6 +363,11 @@ export default class FavoritesPlugin extends Plugin {
|
|||
this.uninstallThemeBrowserModalShowItem();
|
||||
this.uninstallThemeBrowserModalShowItem = undefined;
|
||||
}
|
||||
if (this.uninstallCommunityPluginsSettingTabRenderInstalledPlugin) {
|
||||
console.debug('Uninstall CommunityPluginsSettingTab.renderInstalledPlugin');
|
||||
this.uninstallCommunityPluginsSettingTabRenderInstalledPlugin();
|
||||
this.uninstallCommunityPluginsSettingTabRenderInstalledPlugin = undefined;
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
console.error(e);
|
||||
|
|
@ -287,7 +381,7 @@ export default class FavoritesPlugin extends Plugin {
|
|||
|
||||
loadFavoriteThemes() {
|
||||
// Load the favorite plugins
|
||||
this.favoritePlugins = JSON.parse(localStorage.getItem(this.themesKey) || '[]');
|
||||
this.favoriteThemes = JSON.parse(localStorage.getItem(this.themesKey) || '[]');
|
||||
}
|
||||
|
||||
saveFavorites() {
|
||||
|
|
|
|||
48
src/types.d.ts
vendored
48
src/types.d.ts
vendored
|
|
@ -1,37 +1,45 @@
|
|||
import { } from 'obsidian';
|
||||
|
||||
declare module 'obsidian' {
|
||||
interface App {
|
||||
setting: SettingsModal
|
||||
}
|
||||
|
||||
interface CommunityItem {
|
||||
id: string;
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
interface CommunityModal {
|
||||
update(): void;
|
||||
updateItems(): CommunityItem[];
|
||||
showItem(item: CommunityItem): void;
|
||||
|
||||
// ...
|
||||
|
||||
// Additional from this plugin
|
||||
/**
|
||||
* This is the backup of the original ``updateItems()`` function. Do not use otherwise than restoring!
|
||||
*/
|
||||
originalUpdateItems?(): CommunityItem[];
|
||||
|
||||
/**
|
||||
* This is the backup of the original ``showItem()`` function. Do not use otherwise than restoring!
|
||||
*/
|
||||
originalShowItem?(item: CommunityItem): void;
|
||||
}
|
||||
|
||||
interface Modal {
|
||||
|
||||
// Additional form this plugin
|
||||
/**
|
||||
* This is the backup of the original ``open()`` function. Do not use otherwise than restoring!
|
||||
*/
|
||||
originalOpen?(): void;
|
||||
}
|
||||
|
||||
interface SettingsModal {
|
||||
openTab(settingTab: SettingTab): unknown;
|
||||
}
|
||||
|
||||
interface SettingTab {
|
||||
id: string;
|
||||
setting: unknown;
|
||||
containerEl: HTMLElement;
|
||||
navEl: HTMLElement;
|
||||
app: App;
|
||||
}
|
||||
|
||||
interface CommunityPluginsSettingTab extends SettingTab {
|
||||
id: 'community-plugins';
|
||||
installedPlugins: {
|
||||
listEl: HTMLElement
|
||||
};
|
||||
|
||||
display(): void;
|
||||
render(e: boolean): void;
|
||||
renderInstalledPlugin(plugin: CommunityItem, t: unknown, n: unknown, i: unknown, r: unknown): void;
|
||||
updateSearch(e: unknown): void
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue