mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-30 01:27:26 +08:00
1 parent
68c58ef8c9
commit
7682a7dd5d
2 files changed
+51
-6
No files matched your search
+13
-5
@@ -5053,6 +5053,7 @@ async function boot() {
|
|||||||
applyTitleBarInfo(await nativeHost.call("window.info", {}));
|
applyTitleBarInfo(await nativeHost.call("window.info", {}));
|
||||||
new ResizeObserver(updateTitleBarRegions).observe(el.documentTitleBar);
|
new ResizeObserver(updateTitleBarRegions).observe(el.documentTitleBar);
|
||||||
await nativeHost.start(openNativeFiles, error => showError(error, !state.doc));
|
await nativeHost.start(openNativeFiles, error => showError(error, !state.doc));
|
||||||
|
watchApplicationUpdates();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const remote = remoteDocumentOptions(window.location.hash);
|
const remote = remoteDocumentOptions(window.location.hash);
|
||||||
@@ -5140,18 +5141,20 @@ function watchApplicationUpdates(checksum) {
|
|||||||
if (force === true) retry = true;
|
if (force === true) retry = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (document.hidden || !navigator.onLine) {
|
if (document.hidden || !nativeHost && !navigator.onLine) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
checking = true;
|
checking = true;
|
||||||
try {
|
try {
|
||||||
if (!checksum) {
|
if (!nativeHost && !checksum) {
|
||||||
if (!navigator.serviceWorker.controller) return;
|
if (!navigator.serviceWorker.controller) return;
|
||||||
checksum = await applicationChecksum("./ofdgo.js");
|
checksum = await applicationChecksum("./ofdgo.js");
|
||||||
if (!checksum) return;
|
if (!checksum) return;
|
||||||
}
|
}
|
||||||
const latest = await applicationChecksum("./", { method: "HEAD", cache: "no-store" });
|
const latest = nativeHost ? await nativeHost.call("update.check", {}) : await applicationChecksum("./", { method: "HEAD", cache: "no-store" });
|
||||||
if (latest) {
|
if (nativeHost) {
|
||||||
|
el.refreshAppButton.hidden = !latest;
|
||||||
|
} else if (latest) {
|
||||||
el.refreshAppButton.hidden = latest === checksum;
|
el.refreshAppButton.hidden = latest === checksum;
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
@@ -5240,7 +5243,12 @@ function requestOffline(worker, type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function refreshApplication() {
|
async function refreshApplication() {
|
||||||
if (nativeHost || state.exporting || document.body.hasAttribute("data-busy")) {
|
if (nativeHost) {
|
||||||
|
try { await nativeHost.call("update.open", {}); }
|
||||||
|
catch (err) { showError(err, false); }
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (state.exporting || document.body.hasAttribute("data-busy")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (workspace.tabs.some(tab => tab.state.saving)) {
|
if (workspace.tabs.some(tab => tab.state.saving)) {
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/xiaoqidun/guigo"
|
"github.com/xiaoqidun/guigo"
|
||||||
"github.com/xiaoqidun/ofdgo"
|
"github.com/xiaoqidun/ofdgo"
|
||||||
@@ -44,6 +45,9 @@ import (
|
|||||||
// applicationID 标识原生应用,与版本及可执行文件路径无关
|
// applicationID 标识原生应用,与版本及可执行文件路径无关
|
||||||
const applicationID = "me.aite.ofdgo"
|
const applicationID = "me.aite.ofdgo"
|
||||||
|
|
||||||
|
const applicationVersionURL = "https://ofdgo.aite.me/"
|
||||||
|
const applicationDownloadURL = "https://ofdgo.aite.me/releases/"
|
||||||
|
|
||||||
// Host 连接桌面系统能力和共用文档业务
|
// Host 连接桌面系统能力和共用文档业务
|
||||||
type Host struct {
|
type Host struct {
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
@@ -102,7 +106,7 @@ func Run(ctx context.Context, paths []string, dataDir string) error {
|
|||||||
h.conversionPool = h.resources.ConversionPool()
|
h.conversionPool = h.resources.ConversionPool()
|
||||||
defer h.close()
|
defer h.close()
|
||||||
bindings := make(map[string]guigo.HandlerFunc)
|
bindings := make(map[string]guigo.HandlerFunc)
|
||||||
for _, name := range []string{"engine.open", "engine.close", "engine.call", "engine.start", "engine.cancel", "engine.finish", "batch", "open", "save", "directory", "file", "release", "drop.release", "child", "remove", "write.begin", "write.data", "write.commit", "write.abort", "fonts", "ready", "title", "window.info", "window.drag", "window.close"} {
|
for _, name := range []string{"engine.open", "engine.close", "engine.call", "engine.start", "engine.cancel", "engine.finish", "batch", "open", "save", "directory", "file", "release", "drop.release", "child", "remove", "write.begin", "write.data", "write.commit", "write.abort", "fonts", "ready", "title", "window.info", "window.drag", "window.close", "update.check", "update.open"} {
|
||||||
bindings["ofdgo.host."+name] = func(ctx context.Context, args any) (any, error) { return h.call(ctx, name, args) }
|
bindings["ofdgo.host."+name] = func(ctx context.Context, args any) (any, error) { return h.call(ctx, name, args) }
|
||||||
}
|
}
|
||||||
static := http.FileServerFS(webuiassets.NativeFS)
|
static := http.FileServerFS(webuiassets.NativeFS)
|
||||||
@@ -326,6 +330,10 @@ func (h *Host) call(ctx context.Context, name string, value any) (any, error) {
|
|||||||
return guigo.Result{Value: map[string]any{"engine": id, "parallelism": parallelism, "cacheBytes": cacheBytes}, Discard: func() { _ = h.closeEngine(id) }}, nil
|
return guigo.Result{Value: map[string]any{"engine": id, "parallelism": parallelism, "cacheBytes": cacheBytes}, Discard: func() { _ = h.closeEngine(id) }}, nil
|
||||||
case "batch":
|
case "batch":
|
||||||
return map[string]any{"parallelism": h.conversionPool.Parallelism()}, nil
|
return map[string]any{"parallelism": h.conversionPool.Parallelism()}, nil
|
||||||
|
case "update.check":
|
||||||
|
return applicationUpdate(ctx, build.Version, applicationVersionURL)
|
||||||
|
case "update.open":
|
||||||
|
return nil, guigo.OpenURL(applicationDownloadURL)
|
||||||
case "engine.close":
|
case "engine.close":
|
||||||
return nil, h.closeEngine(text("engine"))
|
return nil, h.closeEngine(text("engine"))
|
||||||
case "engine.finish":
|
case "engine.finish":
|
||||||
@@ -588,6 +596,35 @@ func (h *Host) call(ctx context.Context, name string, value any) (any, error) {
|
|||||||
return nil, fmt.Errorf("未知宿主操作")
|
return nil, fmt.Errorf("未知宿主操作")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// applicationUpdate 比较官网和当前程序的完整构建版本
|
||||||
|
// 入参: ctx 请求上下文, version 当前版本, endpoint 官网地址
|
||||||
|
// 返回: bool 是否有更新, error 检查错误
|
||||||
|
func applicationUpdate(ctx context.Context, version, endpoint string) (bool, error) {
|
||||||
|
if version == "" {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
ctx, cancel := context.WithTimeout(ctx, 8*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
request, err := http.NewRequestWithContext(ctx, http.MethodHead, endpoint, nil)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
request.Header.Set("Cache-Control", "no-store")
|
||||||
|
response, err := http.DefaultClient.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
defer response.Body.Close()
|
||||||
|
if response.StatusCode != http.StatusOK {
|
||||||
|
return false, fmt.Errorf("检查更新失败: %s", response.Status)
|
||||||
|
}
|
||||||
|
latest := response.Header.Get("X-OFDGo-Build-Version")
|
||||||
|
if latest == "" {
|
||||||
|
return false, errors.New("未提供构建版")
|
||||||
|
}
|
||||||
|
return latest != version, nil
|
||||||
|
}
|
||||||
|
|
||||||
// dialogFilters 将共用界面的文件类型映射到系统对话框
|
// dialogFilters 将共用界面的文件类型映射到系统对话框
|
||||||
// 入参: args 对话框参数
|
// 入参: args 对话框参数
|
||||||
// 返回: []guigo.FileFilter 文件类型列表
|
// 返回: []guigo.FileFilter 文件类型列表
|
||||||
|
|||||||
Reference in new issue
Block a user