From bb2b1763386428b6087b9d8c3e21660a77021e42 Mon Sep 17 00:00:00 2001 From: Joseph Cochran Date: Tue, 6 Jun 2023 13:34:09 -0500 Subject: [PATCH] format view and add frontend scoring --- main.ts | 68 +++++++++++++++++++++++++-------------- src/Modals/PromptModal.ts | 29 +++++++---------- src/PromptView.ts | 67 +++++++++++++++++++++++++++++++++----- 3 files changed, 114 insertions(+), 50 deletions(-) diff --git a/main.ts b/main.ts index 8630406..f17892c 100644 --- a/main.ts +++ b/main.ts @@ -1,7 +1,9 @@ -import { App, Editor, MarkdownView, Modal, EventRef, Plugin, PluginSettingTab, Setting, View, Workspace, WorkspaceLeaf, getAllTags, MetadataCache, CachedMetadata } from 'obsidian'; +import { Console } from 'console'; +import { App, Editor, MarkdownView, Modal, FrontMatterCache, Plugin, PluginSettingTab, Setting, View, Workspace, WorkspaceLeaf, getAllTags, MetadataCache, CachedMetadata, TagCache, TAbstractFile, TFile } from 'obsidian'; import { PromptModal } from 'src/Modals/PromptModal'; import { Notes } from 'src/Models/Notes'; -import { VIEW_TYPE_EXAMPLE, PromptView } from 'src/PromptView'; +import { LEARNING_TYPE, PromptView } from 'src/PromptView'; +import { json } from 'stream/consumers'; // Remember to rename these classes and interfaces! @@ -15,30 +17,12 @@ const DEFAULT_SETTINGS: MyPluginSettings = { export default class Learning extends Plugin { settings: MyPluginSettings; - private notes:Array + private notes: Array - async activateView() { - this.app.workspace.detachLeavesOfType(VIEW_TYPE_EXAMPLE); - - await this.app.workspace.getLeaf(false).setViewState({ - type: VIEW_TYPE_EXAMPLE, - active: true, - }); - - this.app.workspace.revealLeaf( - this.app.workspace.getLeavesOfType(VIEW_TYPE_EXAMPLE)[0] - ); - } - async onload() { await this.loadSettings(); this.notes = [] - this.registerView( - VIEW_TYPE_EXAMPLE, - (leaf) => new PromptView(leaf) - ) - this.app.workspace.onLayoutReady( () => { const files = this.app.vault.getMarkdownFiles() let notes: Notes[] = []; @@ -58,7 +42,6 @@ export default class Learning extends Plugin { // This creates an icon in the left ribbon. const ribbonIconEl = this.addRibbonIcon('star', 'Learning', (evt: MouseEvent) => { // Called when the user clicks the icon. - this.app.workspace.detachLeavesOfType(VIEW_TYPE_EXAMPLE); new PromptModal(this.app, this.notes).open() }); // Perform additional things with the ribbon @@ -76,6 +59,7 @@ export default class Learning extends Plugin { new SampleModal(this.app).open(); } }); + // This adds an editor command that can perform some operation on the current editor instance this.addCommand({ id: 'sample-editor-command', @@ -84,6 +68,7 @@ export default class Learning extends Plugin { editor.replaceSelection('Sample Editor Command'); } }); + // This adds a complex command that can check whether the current state of the app allows execution of the command this.addCommand({ id: 'open-sample-modal-complex', @@ -95,7 +80,7 @@ export default class Learning extends Plugin { // If checking is true, we're simply "checking" if the command can be run. // If checking is false, then we want to actually perform the operation. if (!checking) { - new SampleModal(this.app).open(); + new PromptModal(this.app, this.notes).open() } // This command will only show up in Command Palette when the check function returns true @@ -109,14 +94,47 @@ export default class Learning extends Plugin { // If the plugin hooks up any global DOM events (on parts of the app that doesn't belong to this plugin) // Using this function will automatically remove the event listener when this plugin is disabled. - this.registerDomEvent(document, 'click', (evt: MouseEvent) => { - console.log('click', evt); + this.registerDomEvent(document, 'click', async (evt: PointerEvent) => { + const element = evt.composedPath()[0] as HTMLInputElement; + if(element.id.contains("learning-plugin")){ + const activeView = this.app.workspace.getActiveViewOfType(MarkdownView); + if (activeView) { + const file = activeView.file; + const metadata = this.app.metadataCache.getFileCache(file); + + const newTag = { tag: "hm", position: { start: { line: 0, col: 0, offset: 0 }, end: { line: 0, col: 0, offset: 0 } } }; + metadata?.tags?.push(newTag) + + let content = await this.app.vault.read(file) + let finalContent = "" + + if (content.includes('learning-score')){ + const regex = /#learning-score-\d+/g + finalContent = content.replace(regex, `#learning-score-${element.value}`) + + } else + { + finalContent = content + `\n\n\n #learning-score-${element.value}` + } + + this.app.vault.modify(file, finalContent) + } + } }); + + this.registerEvent( + this.app.workspace.on('file-open', this.onFileOpen) + ) + // When registering intervals, this function will automatically clear the interval when the plugin is disabled. this.registerInterval(window.setInterval(() => console.log('setInterval'), 5 * 60 * 1000)); } + onFileOpen = async (file: TFile) => { + // Do something on file open + } + onunload() { } diff --git a/src/Modals/PromptModal.ts b/src/Modals/PromptModal.ts index 3f6c1f7..838962b 100644 --- a/src/Modals/PromptModal.ts +++ b/src/Modals/PromptModal.ts @@ -1,13 +1,11 @@ -import { Modal, App, DropdownComponent } from 'obsidian' +import { Modal, App, TAbstractFile, TFile } from 'obsidian' import { Notes } from 'src/Models/Notes' -const myTokenizer = (text: string) => { - const tokens = text.split(/\s+/); - return tokens.filter((token) => token.includes('_') || token.includes('-') || token.length > 1); - }; +import { PromptView, LEARNING_TYPE } from 'src/PromptView'; export class PromptModal extends Modal { - private notes:Array + private notes: Array private docs: Array + private file: TAbstractFile | null constructor(app: App, notes: Notes[]) { super(app); @@ -21,7 +19,7 @@ export class PromptModal extends Modal { titles: this.notes.filter((o) => o.tags?.includes(tag)).map((o) => o.title), paths: this.notes.filter((o) => o.tags?.includes(tag)).map((o) => o.path) })); - }); + }); } calculateSuggestions(input: string): any[] { @@ -31,7 +29,8 @@ export class PromptModal extends Modal { const value = (doc as { value: String }).value const lowerCase = value.toLowerCase() const formattedValue = lowerCase.substring(1) - if (formattedValue.contains(input) || value.contains(input)) { + + if ((formattedValue.contains(input) || value.contains(input)) && !value.contains("learning-score")) { if(!suggestions.contains(value.toString())) { suggestions.push({tag: value.toString(), titles: doc.titles, paths: doc.paths }) } @@ -76,13 +75,12 @@ export class PromptModal extends Modal { suggestionsContainer.style.visibility = 'hidden' } - suggestions.forEach((sugg) => { + suggestions.forEach((suggestion) => { const item = document.createElement('div') - item.textContent = sugg.tag + item.textContent = suggestion.tag item.addEventListener('mouseenter', () => { item.style.color = 'grey' - console.log("hover: " + item.textContent) }) item.addEventListener('mouseleave', () => { @@ -90,16 +88,13 @@ export class PromptModal extends Modal { }) item.addEventListener('click', async () => { - const VIEW_TYPE_EXAMPLE = "LearningView"; - await this.app.workspace.getLeaf(false).setViewState({ - type: VIEW_TYPE_EXAMPLE, + type: LEARNING_TYPE, active: true, }); - this.app.workspace.revealLeaf( - this.app.workspace.getLeavesOfType(VIEW_TYPE_EXAMPLE)[0] - ); + const leaf = this.app.workspace.getLeavesOfType(LEARNING_TYPE)[0] + this.app.workspace.getLeaf().open(new PromptView(leaf, suggestion)) this.app.workspace.onLayoutReady( () => { this.close(); diff --git a/src/PromptView.ts b/src/PromptView.ts index 35ed89a..3ce32d0 100644 --- a/src/PromptView.ts +++ b/src/PromptView.ts @@ -1,27 +1,78 @@ -import { ItemView, WorkspaceLeaf } from "obsidian"; +import { ItemView, TAbstractFile, TFile, WorkspaceLeaf } from "obsidian"; -export const VIEW_TYPE_EXAMPLE = "LearningView"; +export const LEARNING_TYPE = "LearningView"; export class PromptView extends ItemView { - constructor(leaf: WorkspaceLeaf) { + private params: any + private file: TAbstractFile | null + + constructor(leaf: WorkspaceLeaf, params: any) { super(leaf); + this.params = params } getViewType() { - return VIEW_TYPE_EXAMPLE; + return LEARNING_TYPE; } getDisplayText() { return "Example view"; } + async onload() { + + } + async onOpen() { - const container = this.containerEl.children[1]; - container.empty(); - container.createEl("h4", { text: "Example view" }); + const filteredTitles = this.params.titles.filter((str: string) => !str.includes("[Learning-Plugin]")); + + let fileName = filteredTitles[0]; + const lastPeriodIndex = fileName.lastIndexOf("."); + if (lastPeriodIndex !== -1) { + const beforePeriod = fileName.slice(0, lastPeriodIndex); + + fileName = `[Learning-Plugin]-${beforePeriod}${fileName.slice(lastPeriodIndex)}`; + } + + const originalFile = this.app.vault.getAbstractFileByPath(filteredTitles[0]) + + let content = await this.app.vault.read(originalFile as TFile) + const formattedContent = content.replace(/[\r\n]+/g, '\n>') + + content = '>[!INFO]- ' + formattedContent + content += '\n\n\n\n
\ + \ + \ +
\ + \ + \ +
\ + \ + \ +
\ + \ + \ +
\ + \ + \ +
' + + + + + + + try { + this.file = await this.app.vault.create(fileName, content) + await this.app.workspace.openLinkText(fileName, fileName, true, { state: { mode: 'preview' } }) + } + catch(error) { + await this.app.workspace.openLinkText(fileName, fileName, false, { state: { mode: 'preview' } }) + } } async onClose() { - // Nothing to clean up. + console.log("closed") + this.app.workspace.detachLeavesOfType(LEARNING_TYPE); } } \ No newline at end of file