feat: 更新图片选择器逻辑,增强 BLE 监控错误处理;更新应用版本号;添加 Figma 服务器配置

This commit is contained in:
康猛 2026-01-12 13:37:54 +08:00
parent 5b721ae274
commit e08061fa21
7 changed files with 65 additions and 89 deletions

9
.vscode/mcp.json vendored Normal file
View File

@ -0,0 +1,9 @@
{
"servers": {
"Figma": {
"url": "https://mcp.figma.com/mcp",
"type": "http"
}
},
"inputs": []
}

View File

@ -1,9 +1,13 @@
import * as ImagePicker from 'expo-image-picker'
import Toast from '../components/Toast'
// 定义图片项类型
type PickerBaseParams = Omit<ImagePicker.ImagePickerOptions, 'mediaTypes' | 'allowsMultipleSelection' | 'selectionLimit'> & {
type PickerBaseParams = Omit<
ImagePicker.ImagePickerOptions,
'mediaTypes' | 'allowsMultipleSelection' | 'selectionLimit'
> & {
maxImages?: number
type?: ImagePicker.MediaTypeOptions
}
@ -28,7 +32,7 @@ export async function imgPicker(params: PickerUriParams | PickerAssetParams) {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: type,
allowsEditing: false,
// allowsEditing: true,
quality: 0.9,
allowsMultipleSelection: isMultiple,
selectionLimit: maxImages,

View File

@ -8,6 +8,6 @@ export const ANDROID_ID = 'com.duomi.duooomi'
export const IOS_ID = ANDROID_ID
export const IOS_UNIVERSAL_LINK = 'duooomi.bowong.cn'
export const OWNER_ID = 'x3xbTCWf7dbtWu4gGU2TeI054L77xtkt'
export const APP_VERSION = 'dev202601082028'
export const APP_VERSION = 'dev202601121337'
export const ALIPAY_SCHEMA = 'alipay2021006119657394'
export const ALIPAY_SCHEMA_SANDBOX = '9021000158673972'

View File

@ -19,7 +19,7 @@ const navItems = [
{ id: 'index', label: '探索', iconName: 'compass-outline' },
{ id: 'generate', label: '生成', iconName: 'image-outline' },
{ id: 'sync', label: '同步', iconName: 'refresh' },
// { id: 'explore', label: '蓝牙调试', iconName: 'person-outline' },
{ id: 'explore', label: '蓝牙调试', iconName: 'person-outline' },
]
function renderNavItem(item: (typeof navItems)[0], isActive: boolean, onRouteChange: (route: string) => void) {

View File

@ -42,9 +42,6 @@ const Index = observer(function Index() {
const { execute: loadFavorites } = useFavoriteTemplates()
const { runTemplate } = useTemplateActions()
// 使用MobX Store中的余额信息
const { balance } = userBalanceStore
/** ================= 状态 ================= */
const [activeTab, setActiveTab] = useState<ActiveTab>('')
@ -113,6 +110,7 @@ const Index = observer(function Index() {
let newItems: MediaItem[] = []
if (tab === 'like') {
console.log('加载收藏列表isAuthenticated=', isAuthenticated)
if (!isAuthenticated) {
setHasMore(false)
newItems = []
@ -160,7 +158,10 @@ const Index = observer(function Index() {
/** ================= tab 切换(抽象后的重点) ================= */
const changeTab = useCallback((tab: ActiveTab) => {
const changeTab = useCallback(
(tab: ActiveTab) => {
// 重置加载状态确保新的tab切换不会被旧的加载状态阻挡
loadingRef.current = false
queryRef.current = {
...queryRef.current,
tab,
@ -169,7 +170,9 @@ const Index = observer(function Index() {
setHasMore(true)
firstLoadDoneRef.current = false
fetchList('init')
}, [])
},
[isAuthenticated],
)
/** ================= 搜索 ================= */

View File

@ -282,8 +282,14 @@ class BleManager {
this.setError(null)
console.log('Starting scan...')
const hasPerms = await this.requestBluetoothPermissions()
if (!hasPerms) return
console.log('Bluetooth permissions:', hasPerms)
if (!hasPerms) {
console.log('Permissions denied, stopping scan')
bleStore.setState((prev) => ({ ...prev, isScanning: false }))
return
}
console.log('Setting isScanning to true')
bleStore.setState((prev) => ({ ...prev, isScanning: true, discoveredDevices: [] }))
try {
@ -320,6 +326,7 @@ class BleManager {
console.warn('Failed to check connected devices', e)
}
console.log('Starting BLE scan with service UUID:', BLE_UUIDS.SERVICE)
await this.bleClient.startScan(
[BLE_UUIDS.SERVICE],
{ scanMode: ScanMode.Balanced, allowDuplicates: false },
@ -337,7 +344,9 @@ class BleManager {
this.queueDevice(device)
},
)
console.log('BLE scan started successfully')
} catch (e: any) {
console.error('Start scan error:', e)
this.setError(`Start scan failed: ${e.message}`)
bleStore.setState((prev) => ({ ...prev, isScanning: false, discoveredDevices: [] }))
Alert.alert(

View File

@ -51,35 +51,25 @@ export class BleProtocolService {
this.clearFragments(deviceId)
try {
console.log('Initializing BLE protocol service for device:', deviceId)
this.subscription = await this.client.monitor(
deviceId,
BLE_UUIDS.SERVICE,
BLE_UUIDS.READ_CHARACTERISTIC,
(error, value) => {
if (error) {
// ✅ 修复:增强错误处理,避免崩溃
const errorMsg = error.message || 'Unknown monitor error'
// 忽略预期的断开连接错误
if (this.isExpectedDisconnectionError(error)) {
console.debug('Device disconnected during monitoring:', errorMsg)
// Check for known native crash error and ignore/log as debug
if (
error.errorCode === 0 &&
error.message.includes('Unknown error') &&
error.reason?.includes('PromiseImpl.reject')
) {
console.debug('Ignored native monitor error', error)
return
}
// 忽略已知的原生崩溃错误
if (this.isKnownNativeCrashError(error)) {
console.debug('Ignored known native monitor error:', errorMsg)
console.warn('Monitor error', error)
return
}
console.warn('BLE monitor error:', errorMsg)
return
}
if (value) {
try {
const buffer = Buffer.from(value, 'base64')
const hexString =
buffer
@ -90,16 +80,11 @@ export class BleProtocolService {
console.log(`[BleProtocol] Received ${buffer.byteLength} bytes:`, hexString)
this.handleRawData(deviceId, buffer)
} catch (parseError: any) {
console.warn('Failed to parse received data:', parseError.message)
}
}
},
)
console.log('BLE protocol service initialized successfully')
} catch (error: any) {
console.error('Failed to initialize protocol service:', error.message)
} catch (error) {
console.error('Failed to initialize protocol service:', error)
throw error
}
}
@ -107,24 +92,14 @@ export class BleProtocolService {
public disconnect() {
if (this.subscription) {
try {
console.log('Cleaning up BLE protocol subscription...')
this.subscription.remove()
console.log('BLE protocol subscription removed successfully')
} catch (e: any) {
// ✅ 修复:安全处理订阅清理错误,避免崩溃
const errorMsg = e?.message || String(e)
console.debug('Subscription cleanup completed with warning:', errorMsg)
} finally {
// ✅ 确保订阅引用被清理
} catch (e) {
console.warn('Failed to remove subscription', e)
}
this.subscription = null
}
}
// ✅ 清理分片缓存
this.fragments.clear()
console.log('BLE protocol service disconnected')
}
private handleRawData(deviceId: string, data: Buffer) {
const frame = ProtocolManager.parseFrame(data.buffer)
if (!frame) return
@ -234,28 +209,4 @@ export class BleProtocolService {
// console.debug("Wrote frame", result);
}
}
private isExpectedDisconnectionError(error: any): boolean {
const message = error?.message?.toLowerCase() || ''
const reason = error?.reason?.toLowerCase() || ''
return (
message.includes('disconnect') ||
message.includes('gatt_conn_terminate') ||
message.includes('connection terminated') ||
reason.includes('disconnect') ||
error?.errorCode === 19
) // GATT_CONN_TERMINATE_PEER_USER
}
private isKnownNativeCrashError(error: any): boolean {
const message = error?.message || ''
const reason = error?.reason || ''
return (
(error.errorCode === 0 && message.includes('Unknown error') && reason?.includes('PromiseImpl.reject')) ||
message.includes('Parameter specified as non-null is null') ||
reason?.includes('SafePromise.reject')
)
}
}