Skip to content

Commit

Permalink
[FEAT] Plugin version selection (#2)
Browse files Browse the repository at this point in the history
* Create basic SettingsTab

* Added function fetchManifest + add regex check

* Fix Linting

* Fix regex

* Add PluginDataModal

* Fix naming for PluginDataModal

* Add custom plugins

* Settings plugins to Record

* Update linting rules

* Add installed and saved plugins to list

* Reduced release fetch count to once a day

* Added TroubleshootingModal

* Fix manifest to info

* Rename plugindatamodal.ts to PluginDataModal.ts

* Temporary Fix PluginManifest
  • Loading branch information
4Source authored Mar 18, 2024
1 parent f902234 commit 692e920
Show file tree
Hide file tree
Showing 9 changed files with 664 additions and 29 deletions.
9 changes: 8 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,14 @@
"@stylistic/semi-spacing": "error",
"@stylistic/semi-style": "error",
"@stylistic/space-before-blocks": "error",
"@stylistic/space-before-function-paren": "error",
"@stylistic/space-before-function-paren": [
"error",
{
"anonymous": "always",
"named": "never",
"asyncArrow": "always"
}
],
"@stylistic/arrow-spacing": "error",
"@stylistic/space-in-parens": "error",
"@stylistic/space-infix-ops": "error",
Expand Down
13 changes: 13 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export const ICON_OPEN_FOLDER = 'folder-open';
export const ICON_ACCEPT = 'check';
export const ICON_DENY = 'x';
export const ICON_ADD = 'plus';
export const ICON_RELOAD = 'refresh-cw';
export const ICON_OPTIONS = 'settings';
export const ICON_REMOVE = 'trash-2';
export const ICON_SAVE = 'save';
export const ICON_INSTALL = 'download';
export const ICON_GITHUB = 'github';
export const ICON_FIX = 'wrench';
export const ICON_RESET = 'loader';
export const ICON_FETCH = 'download-cloud';
10 changes: 5 additions & 5 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@ import { DEFAULT_SETTINGS, Settings } from './settings/SettingsInterface';
export default class VarePlugin extends Plugin {
settings: Settings;

async onload () {
async onload() {
await this.loadSettings();

// This adds a settings tab so the user can configure various aspects of the plugin
this.addSettingTab(new VareSettingTab(this.app, this));
}

onunload () {
onunload() {

}

async loadSettings () {
async loadSettings() {
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
}

async saveSettings () {
async saveSettings() {
await this.saveData(this.settings);
}
}
91 changes: 91 additions & 0 deletions src/modals/PluginDataModal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { Modal, Notice, Setting } from 'obsidian';
import VarePlugin from 'src/main';
import { PluginInfo } from 'src/settings/SettingsInterface';
import { fetchManifest, fetchReleases, repositoryRegEx } from 'src/util/GitHub';

export class PluginDataModal extends Modal {
plugin: VarePlugin;
onSubmit: (result: PluginInfo) => void;

constructor(plugin: VarePlugin, onSubmit: (result: PluginInfo) => void) {
super(plugin.app);

this.plugin = plugin;
this.onSubmit = onSubmit;
}

onOpen(): void {
const { contentEl } = this;
let username: string;
let repository: string;

// Heading for Edit profile
this.setTitle('Profile options');

new Setting(contentEl)
.setName('Github username')
.setDesc('The name of the owner of the plugin')
.addText(text => text
.setPlaceholder('Username')
.onChange(value => {
// Assign value of this Setting an save it
username = value;
}));

new Setting(contentEl)
.setName('Github repository')
.setDesc('The name of the repository of the plugin')
.addText(text => text
.setPlaceholder('Repository')
.onChange(value => {
// Assign value of this Setting an save it
repository = value;
}));

new Setting(contentEl)
.addButton(button => button
.setButtonText('Save')
.onClick(async () => {
if (!username || username === '') {
new Notice('Github username cannot be empty!');
return;
}
if (!repository || repository === '') {
new Notice('Github repository cannot be empty!');
return;
}
const repo = `${username}/${repository}`;
if (!repositoryRegEx.test(repo)) {
new Notice('Github <username>/<repository> do not match the pattern!');
return;
}
const manifest = await fetchManifest(repo);
if (!manifest) {
new Notice('Github repository could not be found!');
return;
}
const releases = await fetchReleases(repo);
if (!releases || releases.length <= 0) {
new Notice('No releases found for this plugin. May it do not have any.');
return;
}
// Combine data
const pluginInfo = Object.assign({}, manifest, { repo, releases }) as PluginInfo;
pluginInfo.targetVersion = pluginInfo.version;
pluginInfo.version = '';
this.onSubmit(pluginInfo);
this.close();
}))
.addButton(button => button
.setButtonText('Cancel')
.setWarning()
.onClick(() => {
this.close();
}));
}

onClose(): void {
const { contentEl } = this;
contentEl.empty();
}
}
129 changes: 129 additions & 0 deletions src/modals/TroubleshootingModal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import { Modal, PluginManifest, Setting, debounce } from 'obsidian';
import { ICON_ACCEPT, ICON_DENY } from 'src/constants';
import VarePlugin from 'src/main';
import { PluginInfo } from 'src/settings/SettingsInterface';
import { Release, fetchManifest, fetchReleases, repositoryRegEx } from 'src/util/GitHub';

export class TroubleshootingModal extends Modal {
plugin: VarePlugin;
pluginInfo: PluginInfo;
onSubmit: (result: PluginInfo) => void;

constructor(plugin: VarePlugin, pluginInfo: PluginInfo, onSubmit: (result: PluginInfo) => void) {
super(plugin.app);

this.plugin = plugin;
this.pluginInfo = structuredClone(pluginInfo);
this.onSubmit = onSubmit;
}

async onOpen(): Promise<void> {
const { contentEl } = this;
let username = this.pluginInfo.repo.split('/').at(0) || '';
let repository = this.pluginInfo.repo.split('/').at(1) || '';
let manifest: PluginManifest | undefined;
let hasManifest = false;
let releases: Partial<Release>[] | undefined;
let hasReleases = false;

const updateRepo = debounce(() => {
this.pluginInfo.repo = `${username}/${repository}`;
this.update();
}, 1500, true);

// Heading for Edit profile
this.setTitle(`Troubleshoot plugin ${this.pluginInfo.name}`);

new Setting(contentEl)
.setName('Github username')
.setDesc('The name of the owner of the plugin')
.addText(text => text
.setPlaceholder('Username')
.setValue(username)
.onChange(value => {
username = value;
updateRepo();
}));

new Setting(contentEl)
.setName('Github repository')
.setDesc('The name of the repository of the plugin')
.addText(text => text
.setPlaceholder('Repository')
.setValue(repository)
.onChange(value => {
repository = value;
updateRepo();
}));

new Setting(contentEl)
.setName('Test pattern')
.setDesc(repositoryRegEx.test(this.pluginInfo.repo) ? '' : 'Username or repository contains invalid input.')
.addExtraButton(button => button
.setIcon(repositoryRegEx.test(this.pluginInfo.repo) ? ICON_ACCEPT : ICON_DENY)
.setTooltip(repositoryRegEx.test(this.pluginInfo.repo) ? '' : 'Try again?')
.setDisabled(repositoryRegEx.test(this.pluginInfo.repo))
.onClick(() => {
this.update();
}));

if (repositoryRegEx.test(this.pluginInfo.repo)) {
manifest = await fetchManifest(this.pluginInfo.repo);
hasManifest = manifest !== undefined;
new Setting(contentEl)
.setName('Test connection')
.setDesc(hasManifest ? '' : 'Repo could not be found on GitHub. Is everything typed correctly?')
.addExtraButton(button => button
.setIcon(hasManifest ? ICON_ACCEPT : ICON_DENY)
.setTooltip(hasManifest ? '' : 'Try again?')
.setDisabled(hasManifest)
.onClick(() => {
this.update();
}));
}

if (hasManifest) {
releases = await fetchReleases(this.pluginInfo.repo);
hasReleases = releases !== undefined && (releases.length > 0);
new Setting(contentEl)
.setName('Test releases')
.setDesc(hasReleases ? '' : 'Could not find releases on GitHub. May this plugin did not have any.')
.addExtraButton(button => button
.setIcon(hasReleases ? ICON_ACCEPT : ICON_DENY)
.setTooltip(hasReleases ? '' : 'Try again?')
.setDisabled(hasReleases)
.onClick(() => {
this.update();
}));
}

new Setting(contentEl)
.addButton(button => button
.setButtonText('Save')
.setDisabled(!repositoryRegEx.test(this.pluginInfo.repo) || !hasManifest)
.onClick(async () => {
if (hasReleases && releases) {
this.pluginInfo.releases = releases;
this.pluginInfo.lastFetch = new Date();
}
this.onSubmit(this.pluginInfo);
this.close();
}))
.addButton(button => button
.setButtonText('Cancel')
.setWarning()
.onClick(() => {
this.close();
}));
}

onClose(): void {
const { contentEl } = this;
contentEl.empty();
}

update(): void {
this.onClose();
this.onOpen();
}
}
20 changes: 18 additions & 2 deletions src/settings/SettingsInterface.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
import { Release } from 'src/util/GitHub';

export interface Settings {
mySetting: string;
plugins: Record<PluginData['id'], PluginData>
}

export const DEFAULT_SETTINGS: Settings = {
mySetting: 'default',
plugins: {},
};

export interface PluginData {
id: string;
targetVersion?: string;
repo: string;
releases: Partial<Release>[];
lastFetch?: Date;
}

export interface PluginInfo extends PluginData {
name: string;
author: string;
version: string;
}
Loading

0 comments on commit 692e920

Please sign in to comment.