mirror of
https://github.com/lencx/ChatGPT.git
synced 2024-10-01 01:06:13 -04:00
feat: dalle2 (#122)
This commit is contained in:
parent
53a240953f
commit
594260ce5d
@ -1,16 +1,23 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
|
app::window,
|
||||||
conf::{ChatConfJson, GITHUB_PROMPTS_CSV_URL},
|
conf::{ChatConfJson, GITHUB_PROMPTS_CSV_URL},
|
||||||
utils::{self, exists},
|
utils,
|
||||||
};
|
};
|
||||||
use log::info;
|
use log::info;
|
||||||
use std::{collections::HashMap, fs, path::PathBuf};
|
use std::{collections::HashMap, fs, path::PathBuf};
|
||||||
use tauri::{api, command, AppHandle, Manager};
|
use tauri::{api, command, AppHandle, Manager};
|
||||||
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
#[command]
|
#[command]
|
||||||
pub fn drag_window(app: AppHandle) {
|
pub fn drag_window(app: AppHandle) {
|
||||||
app.get_window("core").unwrap().start_dragging().unwrap();
|
app.get_window("core").unwrap().start_dragging().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
pub fn dalle2_window(app: AppHandle, query: String) {
|
||||||
|
window::dalle2_window(&app.app_handle(), query);
|
||||||
|
}
|
||||||
|
|
||||||
#[command]
|
#[command]
|
||||||
pub fn fullscreen(app: AppHandle) {
|
pub fn fullscreen(app: AppHandle) {
|
||||||
let win = app.get_window("core").unwrap();
|
let win = app.get_window("core").unwrap();
|
||||||
@ -122,9 +129,6 @@ pub fn window_reload(app: AppHandle, label: &str) {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
use utils::chat_root;
|
|
||||||
use walkdir::WalkDir;
|
|
||||||
|
|
||||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||||
pub struct ModelRecord {
|
pub struct ModelRecord {
|
||||||
pub cmd: String,
|
pub cmd: String,
|
||||||
@ -137,7 +141,7 @@ pub struct ModelRecord {
|
|||||||
#[command]
|
#[command]
|
||||||
pub fn cmd_list() -> Vec<ModelRecord> {
|
pub fn cmd_list() -> Vec<ModelRecord> {
|
||||||
let mut list = vec![];
|
let mut list = vec![];
|
||||||
for entry in WalkDir::new(chat_root().join("cache_model"))
|
for entry in WalkDir::new(utils::chat_root().join("cache_model"))
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|e| e.ok())
|
.filter_map(|e| e.ok())
|
||||||
{
|
{
|
||||||
@ -177,11 +181,13 @@ pub async fn sync_prompts(app: AppHandle, time: u64) -> Option<Vec<ModelRecord>>
|
|||||||
|
|
||||||
let data2 = data.clone();
|
let data2 = data.clone();
|
||||||
|
|
||||||
let model = chat_root().join("chat.model.json");
|
let model = utils::chat_root().join("chat.model.json");
|
||||||
let model_cmd = chat_root().join("chat.model.cmd.json");
|
let model_cmd = utils::chat_root().join("chat.model.cmd.json");
|
||||||
let chatgpt_prompts = chat_root().join("cache_model").join("chatgpt_prompts.json");
|
let chatgpt_prompts = utils::chat_root()
|
||||||
|
.join("cache_model")
|
||||||
|
.join("chatgpt_prompts.json");
|
||||||
|
|
||||||
if !exists(&model) {
|
if !utils::exists(&model) {
|
||||||
fs::write(
|
fs::write(
|
||||||
&model,
|
&model,
|
||||||
serde_json::json!({
|
serde_json::json!({
|
||||||
|
@ -261,6 +261,7 @@ pub fn menu_handler(event: WindowMenuEvent<tauri::Wry>) {
|
|||||||
"reload" => win.eval("window.location.reload()").unwrap(),
|
"reload" => win.eval("window.location.reload()").unwrap(),
|
||||||
"go_back" => win.eval("window.history.go(-1)").unwrap(),
|
"go_back" => win.eval("window.history.go(-1)").unwrap(),
|
||||||
"go_forward" => win.eval("window.history.go(1)").unwrap(),
|
"go_forward" => win.eval("window.history.go(1)").unwrap(),
|
||||||
|
// core: document.querySelector('main .overflow-y-auto')
|
||||||
"scroll_top" => win
|
"scroll_top" => win
|
||||||
.eval(
|
.eval(
|
||||||
r#"window.scroll({
|
r#"window.scroll({
|
||||||
@ -308,10 +309,7 @@ pub fn tray_menu() -> SystemTray {
|
|||||||
"hide_dock_icon".to_string(),
|
"hide_dock_icon".to_string(),
|
||||||
"Hide Dock Icon",
|
"Hide Dock Icon",
|
||||||
))
|
))
|
||||||
.add_item(CustomMenuItem::new(
|
.add_item(CustomMenuItem::new("show_core".to_string(), "Show ChatGPT"))
|
||||||
"show_core".to_string(),
|
|
||||||
"Show ChatGPT",
|
|
||||||
))
|
|
||||||
.add_native_item(SystemTrayMenuItem::Separator)
|
.add_native_item(SystemTrayMenuItem::Separator)
|
||||||
.add_item(CustomMenuItem::new("quit".to_string(), "Quit ChatGPT")),
|
.add_item(CustomMenuItem::new("quit".to_string(), "Quit ChatGPT")),
|
||||||
)
|
)
|
||||||
@ -322,10 +320,7 @@ pub fn tray_menu() -> SystemTray {
|
|||||||
"control_center".to_string(),
|
"control_center".to_string(),
|
||||||
"Control Center",
|
"Control Center",
|
||||||
))
|
))
|
||||||
.add_item(CustomMenuItem::new(
|
.add_item(CustomMenuItem::new("show_core".to_string(), "Show ChatGPT"))
|
||||||
"show_core".to_string(),
|
|
||||||
"Show ChatGPT",
|
|
||||||
))
|
|
||||||
.add_native_item(SystemTrayMenuItem::Separator)
|
.add_native_item(SystemTrayMenuItem::Separator)
|
||||||
.add_item(CustomMenuItem::new("quit".to_string(), "Quit ChatGPT")),
|
.add_item(CustomMenuItem::new("quit".to_string(), "Quit ChatGPT")),
|
||||||
)
|
)
|
||||||
|
@ -61,9 +61,12 @@ pub fn init(app: &mut App) -> std::result::Result<(), Box<dyn std::error::Error>
|
|||||||
.always_on_top(chat_conf.stay_on_top)
|
.always_on_top(chat_conf.stay_on_top)
|
||||||
.title_bar_style(ChatConfJson::titlebar())
|
.title_bar_style(ChatConfJson::titlebar())
|
||||||
.initialization_script(&utils::user_script())
|
.initialization_script(&utils::user_script())
|
||||||
.initialization_script(include_str!("../assets/html2canvas.js"))
|
.initialization_script(include_str!("../vendors/floating-ui-core.js"))
|
||||||
.initialization_script(include_str!("../assets/jspdf.js"))
|
.initialization_script(include_str!("../vendors/floating-ui-dom.js"))
|
||||||
|
.initialization_script(include_str!("../vendors/html2canvas.js"))
|
||||||
|
.initialization_script(include_str!("../vendors/jspdf.js"))
|
||||||
.initialization_script(include_str!("../assets/core.js"))
|
.initialization_script(include_str!("../assets/core.js"))
|
||||||
|
.initialization_script(include_str!("../assets/dalle2.core.js"))
|
||||||
.initialization_script(include_str!("../assets/export.js"))
|
.initialization_script(include_str!("../assets/export.js"))
|
||||||
.initialization_script(include_str!("../assets/cmd.js"))
|
.initialization_script(include_str!("../assets/cmd.js"))
|
||||||
.user_agent(&chat_conf.ua_window)
|
.user_agent(&chat_conf.ua_window)
|
||||||
@ -79,9 +82,12 @@ pub fn init(app: &mut App) -> std::result::Result<(), Box<dyn std::error::Error>
|
|||||||
.theme(theme)
|
.theme(theme)
|
||||||
.always_on_top(chat_conf.stay_on_top)
|
.always_on_top(chat_conf.stay_on_top)
|
||||||
.initialization_script(&utils::user_script())
|
.initialization_script(&utils::user_script())
|
||||||
.initialization_script(include_str!("../assets/html2canvas.js"))
|
.initialization_script(include_str!("../vendors/floating-ui-core.js"))
|
||||||
.initialization_script(include_str!("../assets/jspdf.js"))
|
.initialization_script(include_str!("../vendors/floating-ui-dom.js"))
|
||||||
|
.initialization_script(include_str!("../vendors/html2canvas.js"))
|
||||||
|
.initialization_script(include_str!("../vendors/jspdf.js"))
|
||||||
.initialization_script(include_str!("../assets/core.js"))
|
.initialization_script(include_str!("../assets/core.js"))
|
||||||
|
.initialization_script(include_str!("../assets/dalle2.core.js"))
|
||||||
.initialization_script(include_str!("../assets/export.js"))
|
.initialization_script(include_str!("../assets/export.js"))
|
||||||
.initialization_script(include_str!("../assets/cmd.js"))
|
.initialization_script(include_str!("../assets/cmd.js"))
|
||||||
.user_agent(&chat_conf.ua_window)
|
.user_agent(&chat_conf.ua_window)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use crate::{conf, utils};
|
use crate::{conf, utils};
|
||||||
|
use std::time::SystemTime;
|
||||||
use tauri::{utils::config::WindowUrl, window::WindowBuilder};
|
use tauri::{utils::config::WindowUrl, window::WindowBuilder};
|
||||||
|
|
||||||
pub fn tray_window(handle: &tauri::AppHandle) {
|
pub fn tray_window(handle: &tauri::AppHandle) {
|
||||||
@ -26,6 +27,33 @@ pub fn tray_window(handle: &tauri::AppHandle) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn dalle2_window(handle: &tauri::AppHandle, query: String) {
|
||||||
|
let timestamp = SystemTime::now()
|
||||||
|
.duration_since(SystemTime::UNIX_EPOCH)
|
||||||
|
.unwrap()
|
||||||
|
.as_secs();
|
||||||
|
let theme = conf::ChatConfJson::theme();
|
||||||
|
let app = handle.clone();
|
||||||
|
|
||||||
|
tauri::async_runtime::spawn(async move {
|
||||||
|
WindowBuilder::new(&app, format!("dalle2_{}", timestamp), WindowUrl::App("https://labs.openai.com".into()))
|
||||||
|
.title("ChatGPT & DALL·E 2")
|
||||||
|
.resizable(true)
|
||||||
|
.fullscreen(false)
|
||||||
|
.inner_size(800.0, 600.0)
|
||||||
|
.always_on_top(false)
|
||||||
|
.theme(theme)
|
||||||
|
.initialization_script(include_str!("../assets/core.js"))
|
||||||
|
.initialization_script(&format!(
|
||||||
|
"window.addEventListener('DOMContentLoaded', function() {{\nwindow.__CHATGPT_QUERY__='{}';\n}})",
|
||||||
|
query
|
||||||
|
))
|
||||||
|
.initialization_script(include_str!("../assets/dalle2.js"))
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
pub fn control_window(handle: &tauri::AppHandle) {
|
pub fn control_window(handle: &tauri::AppHandle) {
|
||||||
let app = handle.clone();
|
let app = handle.clone();
|
||||||
tauri::async_runtime::spawn(async move {
|
tauri::async_runtime::spawn(async move {
|
||||||
|
87
src-tauri/src/assets/dalle2.core.js
vendored
Normal file
87
src-tauri/src/assets/dalle2.core.js
vendored
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
// *** Core Script - DALL·E 2 Core ***
|
||||||
|
|
||||||
|
async function init() {
|
||||||
|
if (!window.FloatingUIDOM) return;
|
||||||
|
|
||||||
|
const styleDom = document.createElement('style');
|
||||||
|
styleDom.innerHTML = `
|
||||||
|
#chagpt-selection-menu {
|
||||||
|
display: none;
|
||||||
|
width: max-content;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
background: #4a4a4a;
|
||||||
|
color: white;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 5px 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
document.head.append(styleDom);
|
||||||
|
|
||||||
|
const selectionMenu = document.createElement('div');
|
||||||
|
selectionMenu.id = 'chagpt-selection-menu';
|
||||||
|
selectionMenu.innerHTML = 'DALL·E 2';
|
||||||
|
document.body.appendChild(selectionMenu);
|
||||||
|
const { computePosition, flip, offset, shift } = window.FloatingUIDOM;
|
||||||
|
|
||||||
|
document.body.addEventListener("mouseup", async (e) => {
|
||||||
|
const selection = window.getSelection();
|
||||||
|
if (window.__DALLE2_STATE__ !== 1) {
|
||||||
|
window.__DALLE2_CONTENT__ = selection.toString().trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.target.id === 'chagpt-selection-menu') {
|
||||||
|
await invoke('dalle2_window', { query: encodeURIComponent(window.__DALLE2_CONTENT__) });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window.__DALLE2_STATE__ === 1) {
|
||||||
|
delete window.__DALLE2_STATE__;
|
||||||
|
delete window.__DALLE2_CONTENT__;
|
||||||
|
}
|
||||||
|
|
||||||
|
selectionMenu.style.display = 'none';
|
||||||
|
if (!window.__DALLE2_CONTENT__) return;
|
||||||
|
|
||||||
|
if (selection.rangeCount > 0) {
|
||||||
|
const range = selection.getRangeAt(0);
|
||||||
|
const rect = range.getClientRects()[0];
|
||||||
|
|
||||||
|
const rootEl = document.createElement('div');
|
||||||
|
rootEl.style.top = `${rect.top}px`;
|
||||||
|
rootEl.style.position = 'fixed';
|
||||||
|
rootEl.style.left = `${rect.left}px`;
|
||||||
|
document.body.appendChild(rootEl);
|
||||||
|
|
||||||
|
window.__DALLE2_STATE__ = 1;
|
||||||
|
|
||||||
|
selectionMenu.style.display = 'block';
|
||||||
|
computePosition(rootEl, selectionMenu, {
|
||||||
|
placement: 'top',
|
||||||
|
middleware: [
|
||||||
|
flip(),
|
||||||
|
offset(5),
|
||||||
|
shift({ padding: 5 })
|
||||||
|
]
|
||||||
|
}).then(({x, y}) => {
|
||||||
|
Object.assign(selectionMenu.style, {
|
||||||
|
left: `${x}px`,
|
||||||
|
top: `${y}px`,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
document.readyState === "complete" ||
|
||||||
|
document.readyState === "interactive"
|
||||||
|
) {
|
||||||
|
init();
|
||||||
|
} else {
|
||||||
|
document.addEventListener("DOMContentLoaded", init);
|
||||||
|
}
|
34
src-tauri/src/assets/dalle2.js
vendored
Normal file
34
src-tauri/src/assets/dalle2.js
vendored
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// *** Core Script - DALL·E 2 ***
|
||||||
|
|
||||||
|
async function init() {
|
||||||
|
if (window.searchInterval) {
|
||||||
|
clearInterval(window.searchInterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.searchInterval = setInterval(() => {
|
||||||
|
// const searchForm = document.querySelector('.image-prompt-form-wrapper form');
|
||||||
|
// const searchBtn = document.querySelector('.image-prompt-form-wrapper form .image-prompt-btn');
|
||||||
|
const searchInput = document.querySelector('.image-prompt-form-wrapper form>.text-input');
|
||||||
|
if (searchInput) {
|
||||||
|
const query = decodeURIComponent(window.__CHATGPT_QUERY__);
|
||||||
|
searchInput.focus();
|
||||||
|
searchInput.value = query;
|
||||||
|
searchInput.setAttribute('value', query);
|
||||||
|
// searchInput.dispatchEvent(new CustomEvent('change'));
|
||||||
|
// searchForm.classList.add('focused');
|
||||||
|
// searchBtn.classList.add('active-style');
|
||||||
|
// searchBtn.removeAttribute('disabled');
|
||||||
|
// searchBtn.classList.remove('btn-disabled', 'btn-disabled-style');
|
||||||
|
clearInterval(window.searchInterval);
|
||||||
|
}
|
||||||
|
}, 200)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
document.readyState === "complete" ||
|
||||||
|
document.readyState === "interactive"
|
||||||
|
) {
|
||||||
|
init();
|
||||||
|
} else {
|
||||||
|
document.addEventListener("DOMContentLoaded", init);
|
||||||
|
}
|
@ -63,6 +63,7 @@ async fn main() {
|
|||||||
cmd::sync_prompts,
|
cmd::sync_prompts,
|
||||||
cmd::sync_user_prompts,
|
cmd::sync_user_prompts,
|
||||||
cmd::window_reload,
|
cmd::window_reload,
|
||||||
|
cmd::dalle2_window,
|
||||||
cmd::cmd_list,
|
cmd::cmd_list,
|
||||||
fs_extra::metadata,
|
fs_extra::metadata,
|
||||||
])
|
])
|
||||||
@ -76,9 +77,7 @@ async fn main() {
|
|||||||
// https://github.com/tauri-apps/tauri/discussions/2684
|
// https://github.com/tauri-apps/tauri/discussions/2684
|
||||||
if let tauri::WindowEvent::CloseRequested { api, .. } = event.event() {
|
if let tauri::WindowEvent::CloseRequested { api, .. } = event.event() {
|
||||||
let win = event.window();
|
let win = event.window();
|
||||||
if win.label() == "main" {
|
if win.label() == "core" {
|
||||||
win.close().unwrap();
|
|
||||||
} else {
|
|
||||||
// TODO: https://github.com/tauri-apps/tauri/issues/3084
|
// TODO: https://github.com/tauri-apps/tauri/issues/3084
|
||||||
// event.window().hide().unwrap();
|
// event.window().hide().unwrap();
|
||||||
// https://github.com/tauri-apps/tao/pull/517
|
// https://github.com/tauri-apps/tao/pull/517
|
||||||
@ -88,6 +87,8 @@ async fn main() {
|
|||||||
// fix: https://github.com/lencx/ChatGPT/issues/93
|
// fix: https://github.com/lencx/ChatGPT/issues/93
|
||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
event.window().hide().unwrap();
|
event.window().hide().unwrap();
|
||||||
|
} else {
|
||||||
|
win.close().unwrap();
|
||||||
}
|
}
|
||||||
api.prevent_close();
|
api.prevent_close();
|
||||||
}
|
}
|
||||||
|
1
src-tauri/src/vendors/floating-ui-core.js
vendored
Normal file
1
src-tauri/src/vendors/floating-ui-core.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
src-tauri/src/vendors/floating-ui-dom.js
vendored
Normal file
1
src-tauri/src/vendors/floating-ui-dom.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user