Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 39 additions & 1 deletion src/apps/desktop/src/api/dto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ impl WorkspaceInfoDto {

Self {
id: info.id.clone(),
name: info.name.clone(),
name: workspace_display_name(info),
root_path,
workspace_type: WorkspaceTypeDto::from_workspace_type(&info.workspace_type),
workspace_kind: WorkspaceKindDto::from_workspace_kind(&info.workspace_kind),
Expand Down Expand Up @@ -161,6 +161,44 @@ impl WorkspaceInfoDto {
}
}

fn workspace_display_name(
info: &openbitfun_core::service::workspace::manager::WorkspaceInfo,
) -> String {
let name = info.name.trim();
let normalized = name.to_ascii_lowercase();
if info.workspace_kind != WorkspaceKind::Remote
|| (!name.is_empty()
&& normalized != "unknown"
&& normalized != "unknown project"
&& name != "未知"
&& name != "未知项目")
{
return info.name.clone();
}

if let Some(path_name) = info
.root_path
.file_name()
.and_then(|value| value.to_str())
.map(str::trim)
.filter(|value| !value.is_empty())
{
return path_name.to_string();
}
for key in ["connectionName", "sshHost"] {
if let Some(value) = info
.metadata
.get(key)
.and_then(|value| value.as_str())
.map(str::trim)
.filter(|value| !value.is_empty())
{
return value.to_string();
}
}
"Remote workspace".to_string()
}

impl WorkspaceIdentityDto {
pub fn from_workspace_identity(
identity: &openbitfun_core::service::workspace::manager::WorkspaceIdentity,
Expand Down
2 changes: 1 addition & 1 deletion src/apps/mobile/harmonyos/AppScope/app.json5
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// upgrades retain encrypted sessions, preferences, and watch handoff data.
"bundleName": "com.bitfun.app",
"vendor": "OpenBitFun",
"versionCode": 4,
"versionCode": 5,
"versionName": "1.0.0", // x-release-please-version
"buildVersion": "1",
"icon": "$media:openbitfun_app_icon",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ export const EN_US_MESSAGES: [string, string][] = [
['workspaceTools.download', 'Download'],
['workspaceTools.title', 'Tools'],
['workspaceTools.files', 'Files'],
['sidebar.controlledDevice', 'Controlled device'],
['sidebar.currentPath', 'Current path'],
['sidebar.recentWorkspaces', 'Recent workspaces'],
['sidebar.tapToSwitch', 'Tap to switch'],
['workspaceTools.selectTerminal', 'Select an existing terminal'],
['workspaceTools.terminal', 'Terminal'],
['workspaceTools.up', 'Parent'],
Expand Down Expand Up @@ -197,6 +201,8 @@ export const EN_US_MESSAGES: [string, string][] = [
['sidebar.addWorkspace', 'Add workspace'],
['sidebar.targetWorkspacePath', 'Path on controlled device'],
['sidebar.openWorkspacePath', 'Open workspace'],
['sidebar.remoteRootBrowseOnly', 'The remote root is for browsing. Choose a specific workspace folder.'],
['sidebar.browseRemoteRoot', 'Browse remote root'],
['sidebar.selectWorkspace', 'Select workspace'],
['sidebar.workspacesOffline', 'Disconnected'],
['sidebar.connectDesktop', 'Connect a computer'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ export const ZH_CN_MESSAGES: [string, string][] = [
['workspaceTools.download', '下载'],
['workspaceTools.title', '工具'],
['workspaceTools.files', '文件'],
['sidebar.controlledDevice', '受控设备'],
['sidebar.currentPath', '当前路径'],
['sidebar.recentWorkspaces', '最近工作区'],
['sidebar.tapToSwitch', '点击切换'],
['workspaceTools.selectTerminal', '选择已有终端'],
['workspaceTools.terminal', '终端'],
['workspaceTools.up', '上级目录'],
Expand Down Expand Up @@ -197,6 +201,8 @@ export const ZH_CN_MESSAGES: [string, string][] = [
['sidebar.addWorkspace', '添加工作区'],
['sidebar.targetWorkspacePath', '受控设备上的路径'],
['sidebar.openWorkspacePath', '打开工作区'],
['sidebar.remoteRootBrowseOnly', '远程根目录仅用于浏览,请选择具体工作区目录'],
['sidebar.browseRemoteRoot', '浏览远程根目录'],
['sidebar.selectWorkspace', '选择工作区'],
['sidebar.workspacesOffline', '未连接'],
['sidebar.connectDesktop', '连接电脑'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ struct SidebarWorkspaceGroup {
@Param connectionId: string = '';
/** Stable record ID of this row; empty only for rows from pre-ID hosts. */
@Param workspaceId: string = '';
@Param workspaceKind: string = 'normal';
@Event onWorkspaceTools: (intent: WorkspaceToolsIntent) => void = (_intent: WorkspaceToolsIntent) => {};
@Param deviceId: string = '';
@Param path: string = '';
Expand Down Expand Up @@ -110,7 +111,7 @@ struct SidebarWorkspaceGroup {
.hitTestBehavior(HitTestMode.None)
}
.width(24)
.height(46)
.height(54)
.accessibilityText(this.expanded ?
RemoteI18n.t('chat.showLess') : RemoteI18n.t('chat.showMore'))
.onClick(() => {
Expand All @@ -124,18 +125,31 @@ struct SidebarWorkspaceGroup {
.width(21)
.height(21)
.hitTestBehavior(HitTestMode.None)
Text(this.name || this.basename(this.path))
.fontSize(MobileDesignTypography.titleSmall.size)
.fontWeight(this.currentWorkspace ? FontWeight.Medium : FontWeight.Regular)
.fontColor(SIDEBAR_INK)
.layoutWeight(1)
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.wordBreak(WordBreak.BREAK_ALL)
.hitTestBehavior(HitTestMode.None)
Column({ space: 2 }) {
Text(this.workspaceLabel())
.fontSize(MobileDesignTypography.titleSmall.size)
.fontWeight(this.currentWorkspace ? FontWeight.Medium : FontWeight.Regular)
.fontColor(SIDEBAR_INK)
.width('100%')
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.wordBreak(WordBreak.BREAK_ALL)
.hitTestBehavior(HitTestMode.None)
if (this.sshHost.trim().length > 0) {
Text(this.sshHost.trim())
.fontSize(MobileDesignTypography.bodySmall.size)
.fontColor(SIDEBAR_MUTED)
.width('100%')
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.hitTestBehavior(HitTestMode.None)
}
}
.layoutWeight(1)
.alignItems(HorizontalAlign.Start)
}
.layoutWeight(1)
.height(46)
.height(54)
.alignItems(VerticalAlign.Center)
.onClick(() => {
void this.toggleExpanded();
Expand Down Expand Up @@ -174,7 +188,7 @@ struct SidebarWorkspaceGroup {
})
}
.width('100%')
.height(46)
.height(54)
.padding({ left: Math.max(0, this.bodyIndent - 4), right: 6 })
.alignItems(VerticalAlign.Center)
.borderRadius(10)
Expand Down Expand Up @@ -331,6 +345,20 @@ struct SidebarWorkspaceGroup {
const index = normalized.lastIndexOf('/');
return index >= 0 ? normalized.substring(index + 1) : normalized;
}

private workspaceLabel(): string {
const path = this.path.trim();
if (path === '/' && this.workspaceKind.toLowerCase() === 'remote') {
return RemoteI18n.t('sidebar.browseRemoteRoot');
}
const value = this.name.trim();
const host = this.sshHost.trim();
const connection = this.connectionId.trim();
if (value.length > 0 && value !== host && value !== connection) {
return value;
}
return this.basename(path);
}
}

/**
Expand Down Expand Up @@ -405,10 +433,14 @@ export struct SidebarDeviceGroup {
connectionId: this.currentWorkspace(row).remoteConnectionId || '',
sshHost: this.currentWorkspace(row).remoteSshHost || '',
workspaceId: this.currentWorkspace(row).workspaceId || '',
workspaceKind: this.currentWorkspace(row).workspaceKind || 'normal',
onWorkspaceTools: this.onWorkspaceTools,
deviceId: this.device.deviceId,
path: this.currentWorkspace(row).path,
name: this.currentWorkspace(row).remoteSshHost?.trim() ? `${this.currentWorkspace(row).name} · ${(this.currentWorkspace(row).remoteSshHost || '').trim()}` : this.currentWorkspace(row).name,
// The device row already identifies the remote host. Keep the
// workspace row focused on the workspace name instead of appending
// an IP address to it.
name: this.currentWorkspace(row).name,
sessions: this.sessionsFor(this.currentWorkspace(row)),
selectedSessionId: this.selectedSessionId,
runningSessionId: this.runningSessionId,
Expand Down
Loading
Loading