Skip to content

Commit 0cd8435

Browse files
committed
chore: release v0.35.1
1 parent 96ec344 commit 0cd8435

10 files changed

Lines changed: 1009 additions & 140 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## 0.35.1
4+
5+
### Patch Changes
6+
7+
- Improve the workbench composer model picker, add in-app feedback submission, and let Anthropic Subscription OAuth be enabled without an API token.
8+
39
## 0.35.0
410

511
### Minor Changes

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "lovcode",
33
"private": true,
4-
"version": "0.35.0",
4+
"version": "0.35.1",
55
"type": "module",
66
"packageManager": "pnpm@10.18.1",
77
"scripts": {

src-tauri/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src-tauri/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "lovcode"
3-
version = "0.35.0"
3+
version = "0.35.1"
44
description = "A Tauri App"
55
authors = ["you"]
66
edition = "2021"

src-tauri/src/lib.rs

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12450,6 +12450,127 @@ async fn fetch_remote_image_data_url(url: String) -> Result<String, String> {
1245012450
Ok(format!("data:{};base64,{}", mime, STANDARD.encode(&bytes)))
1245112451
}
1245212452

12453+
const FEEDBACK_ENDPOINT: &str = "https://lovstudio.ai/api/lovcode/feedback";
12454+
const FEEDBACK_RECIPIENT_EMAIL: &str = "mark@lovstudio.ai";
12455+
const MAX_FEEDBACK_MESSAGE_CHARS: usize = 5000;
12456+
const MAX_FEEDBACK_FIELD_CHARS: usize = 300;
12457+
12458+
#[derive(Debug, Deserialize)]
12459+
#[serde(rename_all = "camelCase")]
12460+
struct FeedbackSubmission {
12461+
category: String,
12462+
message: String,
12463+
contact: Option<String>,
12464+
path: Option<String>,
12465+
app_version: Option<String>,
12466+
user_agent: Option<String>,
12467+
locale: Option<String>,
12468+
timezone: Option<String>,
12469+
metadata: Option<Value>,
12470+
}
12471+
12472+
#[derive(Debug, Serialize)]
12473+
#[serde(rename_all = "camelCase")]
12474+
struct FeedbackSubmitResult {
12475+
feedback_id: String,
12476+
endpoint: String,
12477+
recipient_email: String,
12478+
}
12479+
12480+
fn normalize_feedback_field(value: Option<String>) -> Option<String> {
12481+
value
12482+
.map(|v| {
12483+
v.trim()
12484+
.chars()
12485+
.take(MAX_FEEDBACK_FIELD_CHARS)
12486+
.collect::<String>()
12487+
})
12488+
.filter(|v| !v.is_empty())
12489+
}
12490+
12491+
#[tauri::command]
12492+
async fn submit_feedback(payload: FeedbackSubmission) -> Result<FeedbackSubmitResult, String> {
12493+
use reqwest::header::{ACCEPT, CONTENT_TYPE, USER_AGENT};
12494+
12495+
let message = payload.message.trim().to_string();
12496+
let message_len = message.chars().count();
12497+
if message_len < 4 {
12498+
return Err("反馈内容太短,请至少输入 4 个字符。".to_string());
12499+
}
12500+
if message_len > MAX_FEEDBACK_MESSAGE_CHARS {
12501+
return Err(format!(
12502+
"反馈内容过长,请控制在 {} 个字符以内。",
12503+
MAX_FEEDBACK_MESSAGE_CHARS
12504+
));
12505+
}
12506+
12507+
let category = match payload.category.trim() {
12508+
"bug" | "idea" | "contact" => payload.category.trim().to_string(),
12509+
_ => "idea".to_string(),
12510+
};
12511+
let feedback_id = uuid::Uuid::new_v4().to_string();
12512+
12513+
let body = serde_json::json!({
12514+
"id": feedback_id,
12515+
"source": "lovcode-desktop",
12516+
"category": category,
12517+
"message": message,
12518+
"contact": normalize_feedback_field(payload.contact),
12519+
"path": normalize_feedback_field(payload.path),
12520+
"appVersion": normalize_feedback_field(payload.app_version),
12521+
"userAgent": normalize_feedback_field(payload.user_agent),
12522+
"locale": normalize_feedback_field(payload.locale),
12523+
"timezone": normalize_feedback_field(payload.timezone),
12524+
"recipientEmail": FEEDBACK_RECIPIENT_EMAIL,
12525+
"metadata": payload.metadata.unwrap_or(Value::Null),
12526+
});
12527+
12528+
let client = reqwest::Client::builder()
12529+
.timeout(Duration::from_secs(15))
12530+
.redirect(reqwest::redirect::Policy::limited(3))
12531+
.build()
12532+
.map_err(|e| format!("创建反馈请求失败: {}", e))?;
12533+
12534+
let response = client
12535+
.post(FEEDBACK_ENDPOINT)
12536+
.header(USER_AGENT, "Lovcode Feedback")
12537+
.header(ACCEPT, "application/json")
12538+
.header(CONTENT_TYPE, "application/json")
12539+
.json(&body)
12540+
.send()
12541+
.await
12542+
.map_err(|e| format!("反馈提交网络失败: {}", e))?;
12543+
12544+
let status = response.status();
12545+
let response_text = response.text().await.unwrap_or_default();
12546+
if !status.is_success() {
12547+
let detail: String = response_text.chars().take(300).collect();
12548+
let suffix = if detail.is_empty() {
12549+
String::new()
12550+
} else {
12551+
format!(": {}", detail)
12552+
};
12553+
return Err(format!("反馈接口返回 HTTP {}{}", status.as_u16(), suffix));
12554+
}
12555+
12556+
let returned_id = serde_json::from_str::<Value>(&response_text)
12557+
.ok()
12558+
.and_then(|value| {
12559+
value
12560+
.get("feedbackId")
12561+
.or_else(|| value.get("id"))
12562+
.and_then(|id| id.as_str())
12563+
.map(str::to_string)
12564+
})
12565+
.unwrap_or(feedback_id);
12566+
12567+
Ok(FeedbackSubmitResult {
12568+
feedback_id: returned_id,
12569+
endpoint: FEEDBACK_ENDPOINT.to_string(),
12570+
recipient_email: FEEDBACK_RECIPIENT_EMAIL.to_string(),
12571+
})
12572+
}
12573+
1245312574
/// Run a shell command in specified directory using login shell (async, non-blocking)
1245412575
#[tauri::command]
1245512576
async fn exec_shell_command(command: String, cwd: String) -> Result<String, String> {
@@ -14406,6 +14527,7 @@ pub fn run() {
1440614527
delete_project_logo,
1440714528
read_file_base64,
1440814529
fetch_remote_image_data_url,
14530+
submit_feedback,
1440914531
exec_shell_command,
1441014532
hook_get_monitored,
1441114533
hook_notify_complete,

0 commit comments

Comments
 (0)