diff options
| -rw-r--r-- | resources/locales/en.yml | 20 | ||||
| -rw-r--r-- | resources/locales/zh-CN.yml | 19 | ||||
| -rw-r--r-- | src/bin/jv.rs | 129 |
3 files changed, 159 insertions, 9 deletions
diff --git a/resources/locales/en.yml b/resources/locales/en.yml index f7cd4d4..0535ebf 100644 --- a/resources/locales/en.yml +++ b/resources/locales/en.yml @@ -271,7 +271,6 @@ jv: **FILE TRANSFER**: share <FILE> <SHEET> <DESC> - Share mapping to other sheets [[cyan]][REMOTE][[/]] share <SHARE_ID> - Import share to current sheet [[cyan]][REMOTE][[/]] - share <REF_SHEET> <FILE> - Import mapping from other ref sheet [[cyan]][REMOTE][[/]] **FILE OPERATIONS**: move <FILE> <TO> - Safely rename files [[cyan]][REMOTE][[/]] @@ -452,7 +451,12 @@ jv: jv share list - View incoming shares jv share see - View share details - **Tip**: The import command can use the following parameters + **Sharing Mode** + The `jv share <FILE> <SHEET>` command can use the following parameters + --work - Start editor mode for detailed sharing control + + **Import Mode** + The `jv share <SHARE_ID>` command can use the following parameters --safe - Safe import, reject all conflicts, this is the default scheme --skip - Skip all conflicting items --overwrite - Force overwrite conflicting mappings, dangerous operation @@ -583,6 +587,9 @@ jv: The sheet `%{sheet}` you specified does not exist in your context. If you are sure it exists, please use `jv update` to update the workspace. + no_description: | + Cannot provide share description! + sheet: align: no_direction: | @@ -1295,3 +1302,12 @@ editor: new_version: NEW content: arrow: -> + + share_editor: | + # You are using editor mode to share files to another sheet + # The following files will be shared to `%{sheet}` + + %{shared_files} + ---------------------------------------------------------------------- + # Fill in the update description here, + # tell the holder of `%{sheet}`, `%{holder}`, the specific details diff --git a/resources/locales/zh-CN.yml b/resources/locales/zh-CN.yml index 9464966..655a20c 100644 --- a/resources/locales/zh-CN.yml +++ b/resources/locales/zh-CN.yml @@ -263,7 +263,6 @@ jv: **文件传递**: share <文件> <表> <描述> - 分享映射到其他表 [[cyan]][远程][[/]] share <分享ID> - 将分享导入到当前表 [[cyan]][远程][[/]] - share <REF表> <文件> - 从其他参考表中导入映射 [[cyan]][远程][[/]] **文件操作**: move <文件> <到> - 安全地重命名文件 [[cyan]][远程][[/]] @@ -444,7 +443,12 @@ jv: jv share list - 查看传入的分享 jv share see - 查看分享的详情 - **提示**:import 命令可使用如下参数 + **分享模式** + `jv share <文件> <表>` 命令可使用如下参数 + --work - 启动编辑器模式,进行详细的分享控制 + + **导入模式** + `jv share <分享ID>` 命令可使用如下参数 --safe - 安全导入,拒绝所有冲突,这是默认的方案 --skip - 跳过所有冲突项 --overwrite - 强制覆盖冲突的映射,危险的操作 @@ -574,6 +578,9 @@ jv: 您所给出的表 `%{sheet}` 在您的上下文中并不存在 若您确定它存在,请使用 `jv update` 更新工作区 + no_description: | + 无法给定分享描述! + sheet: align: no_direction: | @@ -1285,3 +1292,11 @@ editor: new_version: 新 content: arrow: -> + + share_editor: | + # 您正在使用编辑器模式分享文件至其他表 + # 以下文件将被分享至 `%{sheet}`: + + %{shared_files} + ---------------------------------------------------------------------- + # 此处填写更新描述,告诉 `%{sheet}` 的持有者 `%{holder}` 具体事项 diff --git a/src/bin/jv.rs b/src/bin/jv.rs index 0f42318..7efa70f 100644 --- a/src/bin/jv.rs +++ b/src/bin/jv.rs @@ -739,6 +739,10 @@ struct ShareMappingArgs { /// Show json output pretty #[arg(long = "pretty")] pretty: bool, + + /// Share - Editor mode + #[arg(short, long)] + work: bool, } #[derive(Parser, Debug)] @@ -4750,7 +4754,6 @@ async fn proc_mapping_edit( } async fn jv_share(args: ShareMappingArgs) { - // Import share mode if let (Some(args1), None, None) = (&args.args1, &args.args2, &args.args3) { // List mode if args1.trim() == "list" || args1.trim() == "ls" { @@ -4762,8 +4765,19 @@ async fn jv_share(args: ShareMappingArgs) { return; } - // Pull mode if let (Some(args1), Some(args2), None) = (&args.args1, &args.args2, &args.args3) { + // 如果是 work 模式,那么就是分享 + if args.work { + share_out( + args1.to_string(), + args2.to_string(), + String::default(), + args, + ) + .await; + return; + } + // See mode if args1.trim() == "see" { share_see(args2.to_string(), args).await; @@ -4774,7 +4788,6 @@ async fn jv_share(args: ShareMappingArgs) { return; } - // Share mode if let (Some(share_pattern), Some(to_sheet), Some(description)) = (&args.args1, &args.args2, &args.args3) { @@ -5080,9 +5093,9 @@ async fn share_out( share_pattern: String, to_sheet: String, description: String, - _args: ShareMappingArgs, + args: ShareMappingArgs, ) { - let shared_files = { + let mut shared_files = { let local_dir = match current_local_path() { Some(dir) => dir, None => { @@ -5109,6 +5122,11 @@ async fn share_out( None => return, }; + let Some(local_workspace) = LocalWorkspace::init_current_dir(local_config.clone()) else { + eprintln!("{}", md(t!("jv.fail.workspace_not_found")).trim()); + return; + }; + let Ok(latest_info) = LatestInfo::read_from(LatestInfo::latest_info_path( &local_dir, &local_config.current_account(), @@ -5162,6 +5180,15 @@ async fn share_out( } }; + let Some(description) = (if args.work { + start_share_editor(&local_workspace, &mut shared_files, &to_sheet_holder).await + } else { + Some(description.to_string()) + }) else { + eprintln!("{}", md(t!("jv.fail.share.no_description"))); + return; + }; + match proc_share_mapping_action( &pool, ctx, @@ -5222,6 +5249,98 @@ async fn share_out( } } +async fn start_share_editor( + workspace: &LocalWorkspace, + shared_files: &mut Vec<PathBuf>, + holder: &MemberId, +) -> Option<String> { + let config = workspace.config().lock().await.clone(); + + let sheet_name = config.sheet_in_use().clone(); + let Some(sheet_name) = sheet_name else { + eprintln!("{}", md(t!("jv.fail.status.no_sheet_in_use")).trim()); + return None; + }; + + let account = config.current_account(); + let Ok(local_sheet) = workspace.local_sheet(&account, &sheet_name).await else { + eprintln!( + "{}", + md(t!( + "jv.fail.cfg_not_found.local_sheet", + account = &account, + sheet = &sheet_name + )) + ); + return None; + }; + + // Generate shared files and automatically comment out lost mappings + let shared_files_str: String = shared_files + .iter() + .map(|p| { + if local_sheet.mapping_data(p).is_err() { + format!("# {}", p.display().to_string()) + } else { + p.display().to_string() + } + }) + .collect::<Vec<String>>() + .join("\n"); + let shared_files_str = shared_files_str.trim(); + + let editor_content = t!( + "editor.share_editor", + sheet = sheet_name, + holder = holder, + shared_files = shared_files_str + ); + + let path = workspace + .local_path() + .join(CLIENT_PATH_WORKSPACE_ROOT) + .join(".SHARE.md"); + + let result = input_with_editor(format!("{}\n", editor_content), path, "#") + .await + .unwrap_or_default(); + + // Find the last separator line (a line that, when trimmed, consists of at least 3 '-' characters) + let lines: Vec<&str> = result.lines().collect(); + let mut last_separator_index = None; + + for (i, line) in lines.iter().enumerate() { + let trimmed = line.trim(); + if trimmed.chars().all(|c| c == '-') && trimmed.len() >= 3 { + last_separator_index = Some(i); + } + } + + // Extract content after the last separator + let description = if let Some(sep_idx) = last_separator_index { + lines[sep_idx + 1..].join("\n").trim().to_string() + } else { + result.trim().to_string() + }; + + // Update shared_files with the first segment (before the first separator) + if let Some(sep_idx) = last_separator_index { + let first_segment: Vec<PathBuf> = lines[..sep_idx] + .iter() + .map(|line| line.trim()) + .filter(|line| !line.is_empty()) + .map(PathBuf::from) + .collect(); + *shared_files = first_segment; + } + + if description.trim().is_empty() { + None + } else { + Some(description) + } +} + async fn jv_account_add(user_dir: UserDirectory, args: AccountAddArgs) { let member = Member::new(args.account_name.clone()); |
