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
2 changes: 1 addition & 1 deletion src/apps/desktop/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ pub async fn _run() {
{
let candidates = ["mobile-web/dist", "mobile-web", "dist"];
let mut found = false;
let path = PathBuf::from("/data/storage/el2/base/files/dist");
let path = PathBuf::from("/data/storage/el1/bundle/entry/resources/resfile/dist");
if path.join("index.html").exists() {
log::info!("Found bundled mobile-web at: {}", path.display());
api::remote_connect_api::set_mobile_web_resource_path(path);
Expand Down
2 changes: 1 addition & 1 deletion src/apps/vcoder/AppScope/app.json5
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"versionCode": 1000000,
"versionName": "1.0.0",
"buildVersion": "1",
"icon": "$media:layered_image",
"icon": "$media:bitfun_icon",
"label": "$string:app_name"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ export default class EntryAbility extends RustAbility {
let shareData: systemShare.SharedData = new systemShare.SharedData({
utd: uniformTypeDescriptor.UniformDataType.HYPERLINK,
content,
title: "Bitfun",
title: "BitFun",
description: "Phone",
});
sharableTable.share(shareData)
Expand Down
2 changes: 1 addition & 1 deletion src/apps/vcoder/entry/src/main/module.json5
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"description": "$string:EntryAbility_desc",
"icon": "$media:layered_image",
"icon": "$media:bitfun_icon",
"label": "$string:EntryAbility_label",
"startWindowIcon": "$media:startIcon",
"startWindowBackground": "$color:start_window_background",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
},
{
"name": "EntryAbility_label",
"value": "Bitfun"
"value": "BitFun"
}
]
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
58 changes: 25 additions & 33 deletions src/web-ui/src/app/components/AboutDialog/AboutDialog.scss
Original file line number Diff line number Diff line change
Expand Up @@ -640,50 +640,42 @@
}
}

// ==================== User agreement card sections ====================
// ==================== Privacy document layout ====================

.bitfun-about-dialog__sub-card {
display: flex;
flex-direction: column;
gap: 8px;
padding: 14px 16px;
background: linear-gradient(135deg,
rgba(255, 255, 255, 0.03) 0%,
rgba(255, 255, 255, 0.01) 100%
);
border: 1px solid var(--border-subtle);
border-left: 2px solid var(--color-accent-400);
border-radius: 8px;
transition: all 0.2s ease;
.bitfun-about-dialog__privacy-doc {
padding: 24px 28px 28px;
max-height: min(520px, calc(100vh - 200px));
overflow-y: auto;
line-height: 1.8;
}

&:hover {
background: linear-gradient(135deg,
rgba(59, 130, 246, 0.06) 0%,
rgba(139, 92, 246, 0.03) 100%
);
border-color: rgba(59, 130, 246, 0.2);
border-left-color: var(--color-accent-500);
box-shadow:
0 4px 12px rgba(96, 165, 250, 0.08),
0 2px 4px rgba(0, 0, 0, 0.08);
}
.bitfun-about-dialog__privacy-title {
font-size: 16px;
font-weight: 700;
color: var(--color-text-primary);
margin: 0 0 16px 0;
line-height: 1.4;
text-align: center;
}

.bitfun-about-dialog__sub-card-heading {
.bitfun-about-dialog__privacy-section {
font-size: 13px;
font-weight: 600;
color: var(--color-text-primary);
margin: 0;
display: flex;
align-items: center;
gap: 8px;
margin: 16px 0 6px 0;
line-height: 1.5;

&:first-of-type {
margin-top: 0;
}
}

.bitfun-about-dialog__sub-card-text {
.bitfun-about-dialog__privacy-text {
font-size: 12px;
color: var(--color-text-secondary);
line-height: 1.7;
margin: 0;
margin: 0 0 6px 0;
line-height: 1.8;
text-align: justify;
}

.bitfun-about-dialog__sub-footnote {
Expand Down
93 changes: 43 additions & 50 deletions src/web-ui/src/app/components/AboutDialog/AboutDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ export const AboutDialog: React.FC<AboutDialogProps> = ({
<div className="bitfun-about-dialog__dependencies-section">
<div className="bitfun-about-dialog__sub-category">
<div className="bitfun-about-dialog__sub-category-header">
<h3 className="bitfun-about-dialog__sub-category-title">Frontend</h3>
<h3 className="bitfun-about-dialog__sub-category-title">{t('about.openSourceFrontend')}</h3>
<span className="bitfun-about-dialog__sub-category-count bitfun-about-dialog__sub-category-count--frontend">
{dependencies.filter(d => d.category === 'frontend').length}
</span>
Expand All @@ -429,7 +429,7 @@ export const AboutDialog: React.FC<AboutDialogProps> = ({
</span>
</div>
<span className="bitfun-about-dialog__dependency-tag bitfun-about-dialog__dependency-tag--frontend">
FE
{t('about.openSourceTagFE')}
</span>
</div>
))}
Expand All @@ -440,7 +440,7 @@ export const AboutDialog: React.FC<AboutDialogProps> = ({
<div className="bitfun-about-dialog__dependencies-section">
<div className="bitfun-about-dialog__sub-category">
<div className="bitfun-about-dialog__sub-category-header">
<h3 className="bitfun-about-dialog__sub-category-title">Backend</h3>
<h3 className="bitfun-about-dialog__sub-category-title">{t('about.openSourceBackend')}</h3>
<span className="bitfun-about-dialog__sub-category-count bitfun-about-dialog__sub-category-count--backend">
{dependencies.filter(d => d.category === 'backend').length}
</span>
Expand All @@ -464,7 +464,7 @@ export const AboutDialog: React.FC<AboutDialogProps> = ({
</span>
</div>
<span className="bitfun-about-dialog__dependency-tag bitfun-about-dialog__dependency-tag--backend">
BE
{t('about.openSourceTagBE')}
</span>
</div>
))}
Expand All @@ -478,53 +478,46 @@ export const AboutDialog: React.FC<AboutDialogProps> = ({
</div>
</Modal>

{/* User Agreement dialog */}
<Modal
isOpen={subDialog === 'userAgreement'}
onClose={() => setSubDialog(null)}
title={t('about.userAgreement')}
showCloseButton={true}
size="medium"
>
<div className="bitfun-about-dialog__sub-content">
<section className="bitfun-about-dialog__sub-card">
<h3 className="bitfun-about-dialog__sub-card-heading">
1. 服务使用
</h3>
<p className="bitfun-about-dialog__sub-card-text">
用户在使用 BitFun 服务时应遵守相关法律法规。本软件仅供合法用途使用,不得用于任何非法或未经授权的活动。
</p>
</section>
<section className="bitfun-about-dialog__sub-card">
<h3 className="bitfun-about-dialog__sub-card-heading">
2. 免责声明
</h3>
<p className="bitfun-about-dialog__sub-card-text">
本软件按"现状"提供,不提供任何明示或暗示的保证。在适用法律允许的最大范围内,开发者不承担任何损害赔偿的责任。使用风险由用户自行承担。
</p>
</section>
<section className="bitfun-about-dialog__sub-card">
<h3 className="bitfun-about-dialog__sub-card-heading">
3. 隐私政策
</h3>
<p className="bitfun-about-dialog__sub-card-text">
我们重视你的隐私。本软件可能会收集必要的使用数据以改善服务质量。详细的隐私政策请参阅官方网站。
</p>
</section>
<p className="bitfun-about-dialog__sub-footnote">
完整协议内容将在后续版本中完善。
</p>
</div>
</Modal>
{/* Privacy Agreement dialog */}
<Modal
isOpen={subDialog === 'userAgreement'}
onClose={() => setSubDialog(null)}
title={t('about.userAgreement')}
showCloseButton={true}
size="medium"
>
<div className="bitfun-about-dialog__privacy-doc">
<h2 className="bitfun-about-dialog__privacy-title">{t('about.privacyTitle')}</h2>
<p className="bitfun-about-dialog__privacy-text">{t('about.privacyIntro')}</p>
<p className="bitfun-about-dialog__privacy-text">{t('about.privacyCommitment')}</p>

<h3 className="bitfun-about-dialog__privacy-section">{t('about.privacyS1Title')}</h3>
<p className="bitfun-about-dialog__privacy-text">{t('about.privacyS1P1')}</p>
<p className="bitfun-about-dialog__privacy-text">{t('about.privacyS1P2')}</p>
<p className="bitfun-about-dialog__privacy-text">{t('about.privacyS1P3')}</p>

<h3 className="bitfun-about-dialog__privacy-section">{t('about.privacyS2Title')}</h3>
<p className="bitfun-about-dialog__privacy-text">{t('about.privacyS2P1')}</p>

<h3 className="bitfun-about-dialog__privacy-section">{t('about.privacyS3Title')}</h3>
<p className="bitfun-about-dialog__privacy-text">{t('about.privacyS3P1')}</p>
<p className="bitfun-about-dialog__privacy-text">{t('about.privacyS3P2')}</p>

<h3 className="bitfun-about-dialog__privacy-section">{t('about.privacyS4Title')}</h3>
<p className="bitfun-about-dialog__privacy-text">{t('about.privacyS4P1')}</p>
<p className="bitfun-about-dialog__privacy-text">{t('about.privacyS4P2')}</p>
<p className="bitfun-about-dialog__privacy-text">{t('about.privacyS4P3')}</p>
</div>
</Modal>

<UpdateAvailableDialog
isOpen={manualOpen}
variant="manual"
data={manualData}
onLater={onManualLater}
onInstall={onManualInstall}
/>
</>
<UpdateAvailableDialog
isOpen={manualOpen}
variant="manual"
data={manualData}
onLater={onManualLater}
onInstall={onManualInstall}
/>
</>
);
};

Expand Down
6 changes: 6 additions & 0 deletions src/web-ui/src/app/scenes/skills/SkillsScene.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1064,6 +1064,12 @@
&__detail-link {
text-decoration: underline;
text-underline-offset: 2px;
background: none;
border: none;
padding: 0;
cursor: pointer;
font: inherit;
text-align: left;
}

&__path-input {
Expand Down
38 changes: 22 additions & 16 deletions src/web-ui/src/app/scenes/skills/SkillsScene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { Badge, Button, ConfirmDialog, Input, Modal, Search, Select } from '@/co
import { GalleryDetailModal } from '@/app/components';
import type { SkillInfo, SkillLevel, SkillMarketItem } from '@/infrastructure/config/types';
import { workspaceAPI } from '@/infrastructure/api';
import { systemAPI } from '@/infrastructure/api';
import { workspaceManager } from '@/infrastructure/services/business/workspaceManager';
import { useNotification } from '@/shared/notification-system';
import { isRemoteWorkspace } from '@/shared/types';
Expand All @@ -38,6 +39,12 @@ import { useGallerySceneAutoRefresh } from '@/app/hooks/useGallerySceneAutoRefre

const log = createLogger('SkillsScene');

function formatDisplayPath(path: string): string {
return path.replace(
'/data/storage/el2/base/files/bitfun',
'/storage/Users/currentUser/appdata/el2/base/com.huawei.BitFun/files/bitfun'
);
}
type SkillTab = 'installed' | 'discover';

const INSTALLED_PAGE_SIZE = 12;
Expand Down Expand Up @@ -667,12 +674,12 @@ const SkillsScene: React.FC = () => {
type="button"
className="bitfun-skills-scene__detail-path-btn"
title={t('list.item.openPathInExplorer')}
onClick={() => void handleRevealSkillPath(selectedInstalledSkill.path)}
onClick={() => void handleRevealSkillPath(formatDisplayPath(selectedInstalledSkill.path))}
>
{selectedInstalledSkill.path}
{formatDisplayPath(selectedInstalledSkill.path)}
</button>
) : (
<code className="bitfun-skills-scene__detail-value">{selectedInstalledSkill.path}</code>
<code className="bitfun-skills-scene__detail-value">{formatDisplayPath(selectedInstalledSkill.path)}</code>
)}
</div>
</>
Expand All @@ -692,19 +699,18 @@ const SkillsScene: React.FC = () => {
</div>
) : null}

{selectedMarketSkill?.url ? (
<div className="bitfun-skills-scene__detail-row">
<span className="bitfun-skills-scene__detail-label">{t('market.detail.linkLabel')}</span>
<a
href={selectedMarketSkill.url}
target="_blank"
rel="noreferrer"
className="bitfun-skills-scene__detail-link"
>
{selectedMarketSkill.url}
</a>
</div>
) : null}
{selectedMarketSkill?.url ? (
<div className="bitfun-skills-scene__detail-row">
<span className="bitfun-skills-scene__detail-label">{t('market.detail.linkLabel')}</span>
<button
type="button"
className="bitfun-skills-scene__detail-link"
onClick={() => systemAPI.openExternal(selectedMarketSkill.url)}
>
{selectedMarketSkill.url}
</button>
</div>
) : null}
</GalleryDetailModal>

<Modal
Expand Down
23 changes: 10 additions & 13 deletions src/web-ui/src/flow_chat/components/modern/ExportImageButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@
* Export dialog turns as long images.
* Uses React rendering to match FlowChat styles.
* Uses modern-screenshot (fork of html-to-image with better CSS var / font / CORS handling).
*
* NOTE: Temporarily disabled — the export button is hidden. Keep the export
* infrastructure in place for when the underlying capture/save issues are resolved.
*/

import React, { useState, useCallback, useRef } from 'react';
import { createRoot } from 'react-dom/client';
import { Image, Loader2 } from 'lucide-react';
import { FlowChatStore } from '../../store/FlowChatStore';
import { notificationService } from '@/shared/notification-system';
import { FlowTextBlock } from '../FlowTextBlock';
import { FlowToolCard } from '../FlowToolCard';
import { Tooltip } from '@/component-library';
import type { DialogTurn, FlowTextItem, FlowToolItem, FlowThinkingItem } from '../../types/flow-chat';
import { i18nService } from '@/infrastructure/i18n';
import { workspaceAPI } from '@/infrastructure/api';
Expand Down Expand Up @@ -534,17 +535,13 @@ export const ExportImageButton: React.FC<ExportImageButtonProps> = ({
}
}, [getDialogTurn]);

return (
<Tooltip content={isExporting ? i18nService.t('flow-chat:exportImage.exporting') : i18nService.t('flow-chat:exportImage.exportToImage')} placement="top">
<button
className={`model-round-item__action-btn model-round-item__export-btn ${className}`}
onClick={handleExport}
disabled={isExporting}
>
{isExporting ? <Loader2 size={14} className="spinning" /> : <Image size={14} />}
</button>
</Tooltip>
);
// Currently unused — kept for re-enable.
void (handleExport as unknown as React.MouseEventHandler);
void (isExporting as boolean);
void (isExportingRef as React.MutableRefObject<boolean>);
void (className as string);

return null;
};

ExportImageButton.displayName = 'ExportImageButton';
Loading
Loading