mirror of
https://github.com/kuaifan/dootask.git
synced 2026-07-31 18:35:56 +00:00
新移动端从 EEUI(weex) 切到 Expo(react-native),UA 标识从 'eeui' 改为 'DooTaskApp', 桥接底层从全局 requireModuleJs 切到 window.__nativeBridge.call(method,args) Promise RPC。 约 52 个文件批量改名(256 处引用): - 平台识别:$A.isEEUIApp/Vue.prototype.$isEEUIApp → isMobileApp / $isMobileApp app.js 顶部 UA 正则 /eeui/i → /DooTaskApp/i app.js requireModuleJs 等待逻辑替换为 window.__nativeBridge 就绪判定 - 桥接 API:$A.eeuiAppXXX → $A.nativeAppXXX - functions/eeui.js 删除,重写为 functions/native-app.js 底层走 window.__nativeBridge.call;nativeAppSendMessage 把旧 sendMessage 的 各 action 拆解为独立 method 调用(updateTheme/windowSize/setBadge/vibrate/ callTel/picturePreview/videoPreview/startMeeting/updateMeetingInfo 等) - types/dootask-globals.d.ts:方法签名同步改名 - store/actions.js:清理 saveUserInfoBase 内旧的 userChatList/userUploadUrl sendMessage(二期由 /share 接收页直接调接口替代) 二期 /share 接收页(跨 App 分享): - pages/share.vue(新增):原生 Share Extension / Android Intent 通过 dootask://share?token=... 拉起 App 后跳本页; 调 nativeAppGetSharedPayload 取分享元数据; 复用 api/users/share/list 渲染会话列表; 用户选会话 → POST api/dialog/msg/sendfiles 上传 + sendtext 发文本/URL; 完成后 nativeAppClearSharedPayload 清理 + 跳目标会话 - routes.js 注册 /share 路由 - language/original-web.txt 加 share.vue 用到的文案 构建链路(electron/build.js): - appbuild app 子命令:前端产物从复制到 resources/mobile/src/public + EEUI docker 构建 改为同步到 resources/mobile/assets/web(由 plugins/withWebAssets 注入原生 bundle) - android-upload apk 路径:从 platforms/android/eeuiApp/... 改为 android/app/build/outputs/apk/release(Expo prebuild 标准布局) 子模块 resources/mobile 指针更新到新 Expo 工程提交(feat/mobile-expo-rewrite 分支)。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
174 lines
4.8 KiB
JavaScript
Vendored
174 lines
4.8 KiB
JavaScript
Vendored
/**
|
||
* @param key
|
||
* @param requestData
|
||
* @param state
|
||
* @returns {$callData}
|
||
*/
|
||
function __callData(key, requestData, state) {
|
||
if (!$A.isJson(requestData)) {
|
||
requestData = {}
|
||
}
|
||
const callKey = key + "::" + encodeURIComponent(new URLSearchParams($A.sortObject(requestData, [
|
||
'page',
|
||
'pagesize',
|
||
'timerange',
|
||
])).toString())
|
||
const callData = state.callAt.find(item => item.key === callKey) || {}
|
||
callData.__last = $A.dayjs().unix()
|
||
if (typeof callData.key === "undefined") {
|
||
callData.key = callKey
|
||
callData.updated = 0
|
||
callData.deleted = 0
|
||
state.callAt.push(callData)
|
||
$A.IDBSet("callAt", state.callAt).catch(_ => { })
|
||
}
|
||
|
||
/**
|
||
* @returns {*}
|
||
*/
|
||
this.get = () => {
|
||
requestData.timerange = requestData.timerange || `${callData.updated || 0},${callData.deleted || 0}`
|
||
return requestData
|
||
}
|
||
|
||
/**
|
||
* @param total
|
||
* @param current_page
|
||
* @param deleted_id
|
||
* @returns {Promise<unknown>}
|
||
*/
|
||
this.save = ({total, current_page, deleted_id}) => {
|
||
return new Promise(async resolve => {
|
||
if (current_page !== 1) {
|
||
return
|
||
}
|
||
let hasUpdate = false
|
||
const time = callData.__last || $A.dayjs().unix()
|
||
if (total > 0) {
|
||
callData.updated = time
|
||
hasUpdate = true
|
||
}
|
||
if ($A.isArray(deleted_id) && deleted_id.length > 0) {
|
||
callData.deleted = time
|
||
hasUpdate = true
|
||
} else {
|
||
deleted_id = []
|
||
}
|
||
if ($A.isMobileApp) {
|
||
hasUpdate = state.isFirstPage
|
||
}
|
||
if (hasUpdate) {
|
||
if ($A.isSubElectron || ($A.isMobileApp && !state.isFirstPage)) {
|
||
// 子窗口(Electron)、不是第一个页面(App) 不保存
|
||
} else {
|
||
await $A.IDBSet("callAt", state.callAt)
|
||
}
|
||
}
|
||
resolve(deleted_id)
|
||
})
|
||
}
|
||
|
||
return this
|
||
}
|
||
|
||
export function $callData(key, requestData, state) {
|
||
return new __callData(key, requestData, state)
|
||
}
|
||
|
||
export function $urlSafe(value, encode = true) {
|
||
if (value) {
|
||
if (encode) {
|
||
value = String(value).replace(/\+/g, "-").replace(/\//g, "_").replace(/\n/g, '$')
|
||
} else {
|
||
value = String(value).replace(/\-/g, "+").replace(/\_/g, "/").replace(/\$/g, '\n')
|
||
}
|
||
}
|
||
return value
|
||
}
|
||
|
||
/**
|
||
* EventSource
|
||
*/
|
||
const SSEDefaultOptions = {
|
||
retry: 5,
|
||
interval: 3 * 1000,
|
||
}
|
||
|
||
export class SSEClient {
|
||
constructor(url, options = SSEDefaultOptions) {
|
||
this.url = url;
|
||
this.es = null;
|
||
this.options = options;
|
||
this.retry = options.retry;
|
||
this.timer = null;
|
||
}
|
||
|
||
_onOpen() {
|
||
if (window.systemInfo.debug === "yes") {
|
||
console.log("SSE open: " + this.url);
|
||
}
|
||
}
|
||
|
||
_onMessage(type, handler) {
|
||
return (event) => {
|
||
this.retry = this.options.retry;
|
||
if (typeof handler === "function") {
|
||
handler(type, event);
|
||
}
|
||
};
|
||
}
|
||
|
||
_onError(type, handler, onFailed) {
|
||
return () => {
|
||
if (window.systemInfo.debug === "yes") {
|
||
console.log("SSE retry: " + this.url);
|
||
}
|
||
if (this.es) {
|
||
this._removeAllEvent(type, handler, onFailed);
|
||
this.unsunscribe();
|
||
}
|
||
|
||
if (this.retry > 0) {
|
||
this.retry--;
|
||
this.timer = setTimeout(() => {
|
||
this.subscribe(type, handler, onFailed);
|
||
}, this.options.interval);
|
||
} else if (typeof onFailed === 'function') {
|
||
onFailed();
|
||
}
|
||
};
|
||
}
|
||
|
||
_removeAllEvent(type, handler, onFailed) {
|
||
type = $A.isArray(type) ? type : [type]
|
||
this.es.removeEventListener("open", this._onOpen);
|
||
type.some(item => {
|
||
this.es.removeEventListener(item, this._onMessage(item, handler));
|
||
})
|
||
this.es.removeEventListener("error", this._onError(type, handler, onFailed));
|
||
}
|
||
|
||
subscribe(type, handler, onFailed) {
|
||
type = $A.isArray(type) ? type : [type]
|
||
this.es = new EventSource(this.url);
|
||
this.es.addEventListener("open", this._onOpen);
|
||
type.some(item => {
|
||
this.es.addEventListener(item, this._onMessage(item, handler));
|
||
})
|
||
this.es.addEventListener("error", this._onError(type, handler, onFailed));
|
||
}
|
||
|
||
unsunscribe() {
|
||
if (this.es) {
|
||
this.es.close();
|
||
this.es = null;
|
||
}
|
||
if (this.timer) {
|
||
clearTimeout(this.timer);
|
||
}
|
||
if (window.systemInfo.debug === "yes") {
|
||
console.log("SSE cancel: " + this.url);
|
||
}
|
||
}
|
||
}
|