From 86b5fd432a1f4ea0ceb491d09ca0570d5f8777a1 Mon Sep 17 00:00:00 2001 From: trendschau Date: Wed, 2 Apr 2025 20:45:48 +0200 Subject: [PATCH] fix api call --- cache/timer.yaml | 2 +- system/typemill/Models/ApiCalls.php | 29 +-- system/typemill/author/js/vue-kixote.js | 242 +++++++++++++++++++++++- system/typemill/author/js/vue-meta.js | 3 +- 4 files changed, 260 insertions(+), 16 deletions(-) diff --git a/cache/timer.yaml b/cache/timer.yaml index e55b790..e606a74 100644 --- a/cache/timer.yaml +++ b/cache/timer.yaml @@ -1 +1 @@ -licenseupdate: 1743531622 +licenseupdate: 1743542694 diff --git a/system/typemill/Models/ApiCalls.php b/system/typemill/Models/ApiCalls.php index 18ca6da..8e9a62b 100644 --- a/system/typemill/Models/ApiCalls.php +++ b/system/typemill/Models/ApiCalls.php @@ -31,7 +31,7 @@ class ApiCalls return $this->makeFileGetContentsCall($url, 'GET', null, $authHeader); } - private function makeCurlCall($url, $method, $data = false, $customHeader = '') + private function makeCurlCall($url, $method, $data = false, $customHeaders = '') { $this->error = null; @@ -39,7 +39,7 @@ class ApiCalls "Content-Type: application/json", ]; - $headers = $this->addCustomHeader($customHeader); + $headers = $this->addCustomHeaders($headers, $customHeaders); $curl = curl_init($url); if (defined('CURLSSLOPT_NATIVE_CA') && version_compare(curl_version()['version'], '7.71', '>=')) @@ -75,7 +75,7 @@ class ApiCalls return $response; } - private function makeFileGetContentsCall($url, $method, $data = null, $customHeader = '') + private function makeFileGetContentsCall($url, $method, $data = null, $customHeaders = '') { $this->error = null; @@ -83,7 +83,7 @@ class ApiCalls "Content-Type: application/json" ]; - $headers = $this->addCustomHeader($headers, $customHeader); + $headers = $this->addCustomHeader($headers, $customHeaders); $options = [ 'http' => [ @@ -128,23 +128,28 @@ class ApiCalls return $response; } - private function addCustomHeader(array $header, $customHeader = '') + private function addCustomHeaders($headers, $customHeaders = '') { - if(!empty($customHeader)) + if(!is_array($headers)) { - if(is_array($customHeader)) + return false; + } + + if(!empty($customHeaders)) + { + if(is_array($customHeaders)) { - foreach($customHeader as $cHeader) + foreach($customHeaders as $cHeader) { - $header[] = $cHeader; + $headers[] = $cHeader; } } - elseif(is_string($customHeader)) + elseif(is_string($customHeaders)) { - $header[] = $customHeader; + $headers[] = $customHeaders; } } - return $header; + return $headers; } } \ No newline at end of file diff --git a/system/typemill/author/js/vue-kixote.js b/system/typemill/author/js/vue-kixote.js index 2bc29c0..9077c74 100644 --- a/system/typemill/author/js/vue-kixote.js +++ b/system/typemill/author/js/vue-kixote.js @@ -130,9 +130,9 @@ const kixote = Vue.createApp({ tabs: [ "Admin", "Generate", + "SEO", /* "Automate", "Translate", - "SEO", "RAG" */ ], icons: { @@ -1005,6 +1005,246 @@ kixote.component('tab-generate', { } }) + +kixote.component('tab-seo', { + props: ['content', 'item', 'labels', 'urlinfo', 'settings', 'kixoteSettings', 'settingsSaved', 'aiservice', 'useragreement', 'tokenstats'], + data: function () { + return { + article: '', + }; + }, + template: `
+ +
+
+

Your AI Assistant for Typemill

+

+ To get started with AI-powered assistance, go to System Settings, open the AI tab, and follow these steps: +

+
    +
  1. Select an AI service.
  2. +
  3. Choose a model.
  4. +
  5. Enter your API key.
  6. +
+

Once set up, you can start using AI assistance right away!

+
+
+ +
+ +
+
+ +
+
Activate {{aiservice}}
+ +
+ +
+
+ +
+ +
{{ promptError }}
+
+
+ Ki> + + + | + +
+
+ +
+ + +
+ + +
+

Content Generation only works on content pages. You are currently in the settings area.

+
+ +
`, + mounted: function() + { + this.initAutosize(); + + if(this.versions.length == 0) + { + this.initializeContent() + } + }, + watch: { + currentTab(newTab, oldTab) { + if (newTab === 'article') + { + this.$nextTick(() => { + this.initAutosize(); // Trigger the resizing when switching back to the article tab + }); + } + } + }, + methods: { + initAutosize() + { + let kieditor = this.$refs["kieditor"]; + let prompteditor = this.$refs["prompteditor"]; + + if (kieditor) + { + autosize(kieditor); + } + if (prompteditor) + { + autosize(prompteditor); + } + }, + agreeTo(aiservice) + { + var self = this; + + tmaxios.post('/api/v1/agreetoaiservice',{ + 'aiservice': aiservice + }) + .then(function (response) + { + eventBus.$emit('agreetoservice'); + self.$nextTick(() => { + self.initAutosize(); + }); + }) + }, + initializeContent() + { + let markdown = ''; + + for(block in this.content) + { + markdown += this.content[block].markdown + '\n\n'; + } + this.originalmd = markdown; + this.versions.push(markdown); + this.resizeAiEditor(); + }, + resizeAiEditor() + { + this.$nextTick(() => { + let kieditor = this.$refs["kieditor"]; + if (kieditor) + { + autosize.update(kieditor); + } + }); + }, + resizePromptEditor() + { + this.$nextTick(() => { + let prompteditor = this.$refs["prompteditor"]; + if (prompteditor) + { + autosize.update(prompteditor); + } + }); + }, + submitPrompt() + { + this.promptError = false; + + var self = this; + eventBus.$emit('switchLoading'); + + tmaxios.post('/api/v1/prompt',{ + 'prompt': this.prompt, + 'article': this.versions[this.activeversion] + }) + .then(function (response) + { + eventBus.$emit('switchLoading'); + if (response.data.message === 'Success') + { + let answer = response.data.answer; + answer = answer.replace(/<\/?focus>/g, ''); + self.versions.push(answer); + self.activeversion = self.versions.length-1; + self.prompt = ''; + self.resizePromptEditor(); + self.resizeAiEditor(); + } + }) + .catch(function (error) + { + eventBus.$emit('switchLoading'); + if(error.response) + { + self.disabled = false; + self.promptError = handleErrorMessage(error); + self.licensemessage = error.response.data.message; + if(error.response.data.errors !== undefined) + { + self.promptError = error.response.data.errors; + } + } + }); + }, + handleKeydown(event) + { + if (event.key === 'Enter' && !event.shiftKey) + { + event.preventDefault(); + this.submitPrompt(); + } + else if (event.key === 'Enter' && event.shiftKey) + { + // Allow line break + const textarea = event.target; + const start = textarea.selectionStart; + const end = textarea.selectionEnd; + textarea.value = textarea.value.slice(0, start) + '\n' + textarea.value.slice(end); + textarea.selectionStart = textarea.selectionEnd = start + 1; + + let prompteditor = this.$refs["prompteditor"]; + autosize.update(prompteditor); + + event.preventDefault(); + } + }, + exit() + { + eventBus.$emit('kiExit'); + }, + } +}) + + // publish tree // unpublish tree // load page diff --git a/system/typemill/author/js/vue-meta.js b/system/typemill/author/js/vue-meta.js index 653c8a7..559a2ee 100644 --- a/system/typemill/author/js/vue-meta.js +++ b/system/typemill/author/js/vue-meta.js @@ -53,8 +53,7 @@ const app = Vue.createApp({ const componentName = 'tab-' + this.currentTab.toLowerCase(); - - if (this.$root.$options.components && this.$root.$options.components[componentName]) + if(this.$root.$.appContext.components[componentName]) { return componentName; }