summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--resources/locales/en.yml20
-rw-r--r--resources/locales/zh-CN.yml19
-rw-r--r--src/bin/jv.rs129
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());