diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..5257c7ba Binary files /dev/null and b/.DS_Store differ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..e86bf26c --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,136 @@ +name: Build and Release + +on: + workflow_dispatch: + inputs: + version: + description: "Release version, for example v1.7.2" + required: true + type: string + draft: + description: "Create release as draft" + required: false + default: false + type: boolean + prerelease: + description: "Mark release as prerelease" + required: false + default: false + type: boolean + push: + tags: + - "v*" + +permissions: + contents: write + +jobs: + release: + name: Build macOS DMG and publish GitHub Release + runs-on: macos-latest + + steps: + - name: Checkout FlowVision + uses: actions/checkout@v4 + with: + path: FlowVision + + - name: Checkout Settings dependency + uses: actions/checkout@v4 + with: + repository: sindresorhus/Settings + path: Settings + + - name: Checkout BTree dependency + uses: actions/checkout@v4 + with: + repository: attaswift/BTree + path: BTree + + - name: Download FFmpegKit XCFrameworks + shell: bash + env: + FFMPEG_KIT_URL: https://github.com/netdcy/ffmpeg-kit/releases/download/v6.0/ffmpeg-kit-full-gpl-6.0-macos-xcframework.zip + run: | + set -euo pipefail + mkdir -p ffmpeg-kit-build/bundle-apple-xcframework-macos + curl --fail --location --retry 3 --output ffmpeg-kit-build/ffmpeg-kit-full-gpl-6.0-macos-xcframework.zip "$FFMPEG_KIT_URL" + unzip -q ffmpeg-kit-build/ffmpeg-kit-full-gpl-6.0-macos-xcframework.zip -d ffmpeg-kit-build/bundle-apple-xcframework-macos + + - name: Resolve release version + id: version + shell: bash + run: | + set -euo pipefail + if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then + VERSION="${GITHUB_REF_NAME}" + else + VERSION="${{ inputs.version }}" + fi + VERSION="${VERSION#refs/tags/}" + if [[ -z "$VERSION" ]]; then + echo "Release version is required." >&2 + exit 1 + fi + if [[ "$VERSION" != v* ]]; then + VERSION="v$VERSION" + fi + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + echo "dmg_name=FlowVision-${VERSION}-macOS" >> "$GITHUB_OUTPUT" + + - name: Build DMG + working-directory: FlowVision + env: + ENABLE_CODESIGN: "0" + CONFIGURATION: Release + APP_NAME: FlowVision + DMG_NAME: ${{ steps.version.outputs.dmg_name }} + XCODEBUILD_EXTRA_ARGS: "CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY=" + run: ./build_dmg.sh + + - name: Create ZIP + working-directory: FlowVision + shell: bash + run: | + set -euo pipefail + APP_PATH="$(find build/DerivedData/Build/Products/Release -maxdepth 1 -type d -name '*.app' | head -n 1)" + if [[ -z "${APP_PATH:-}" ]]; then + echo "App bundle not found." >&2 + exit 1 + fi + mkdir -p dist + ditto -c -k --sequesterRsrc --keepParent "$APP_PATH" "dist/${{ steps.version.outputs.dmg_name }}.zip" + + - name: Upload workflow artifacts + uses: actions/upload-artifact@v4 + with: + name: FlowVision-${{ steps.version.outputs.version }}-macOS + path: | + FlowVision/dist/*.dmg + FlowVision/dist/*.zip + + - name: Publish GitHub Release + working-directory: FlowVision + env: + GH_TOKEN: ${{ github.token }} + VERSION: ${{ steps.version.outputs.version }} + DRAFT: ${{ inputs.draft || false }} + PRERELEASE: ${{ inputs.prerelease || false }} + shell: bash + run: | + set -euo pipefail + + FLAGS="" + if [[ "$DRAFT" == "true" ]]; then + FLAGS="$FLAGS --draft" + fi + if [[ "$PRERELEASE" == "true" ]]; then + FLAGS="$FLAGS --prerelease" + fi + + if gh release view "$VERSION" >/dev/null 2>&1; then + gh release upload "$VERSION" dist/*.dmg dist/*.zip --clobber + else + # shellcheck disable=SC2086 + gh release create "$VERSION" dist/*.dmg dist/*.zip --title "FlowVision $VERSION" --generate-notes $FLAGS + fi diff --git a/.mindfs/sessions/1776746378-31906b751c86.jsonl b/.mindfs/sessions/1776746378-31906b751c86.jsonl new file mode 100644 index 00000000..ee7c51a6 --- /dev/null +++ b/.mindfs/sessions/1776746378-31906b751c86.jsonl @@ -0,0 +1,4 @@ +{"seq":1,"role":"user","agent":"codex","effort":"medium","content":"你看一下现在的功能,增加一个SMB的可能性,不要改代码","timestamp":"2026-04-21T04:40:41.976786Z"} +{"seq":2,"role":"agent","agent":"codex","effort":"medium","content":"我先看一下当前项目的功能边界和已有接入方式,重点判断在不改代码的前提下,`SMB` 能加到什么程度、卡点在哪里。\n\n我先沿着文档和文件系统相关代码看,判断现在支持的是“本地路径浏览”还是已经抽象成了可扩展的数据源。这个结论会直接决定 SMB 是“配置级可行”还是“需要开发”。\n\n代码里已经出现了不少“network drives / mounted directories”的处理痕迹。我继续看文件系统、权限、入口选择这几块,确认它是不是已经能“通过系统挂载后的 SMB”工作,以及缺的是不是“原生 SMB 连接能力”。\n\n结论已经比较清楚了:当前代码把“已挂载的网络盘”当成外置卷处理,但没有任何“主动发起 SMB 连接”的能力。我再补两处证据,确认 UI 和设置层面对网络盘也是按“挂载后可用”设计的。\n\n看过当前实现后,结论很明确:\n\n如果你说的 `SMB` 是“支持 Finder 已经挂载好的 SMB 共享目录”,那这个项目其实已经基本具备了,不用改代码就能用。代码里会把已挂载卷统一识别成 external volume,并对 network drive 做专门的性能策略和提示,比如 [Common.swift](/Users/mcx/Documents/OpenSpring/FlowVision/FlowVision/Sources/Common/Common.swift:671)、[FileSystem.swift](/Users/mcx/Documents/OpenSpring/FlowVision/FlowVision/Sources/ViewControllerExtension/FileSystem.swift:217)、[DirTree.swift](/Users/mcx/Documents/OpenSpring/FlowVision/FlowVision/Sources/ViewControllerExtension/DirTree.swift:95),设置文案里也直接写了 network drives 的场景,比如 [AdvancedSettingsViewController.xcstrings](/Users/mcx/Documents/OpenSpring/FlowVision/FlowVision/Sources/SettingsViews/mul.lproj/AdvancedSettingsViewController.xcstrings:1541) 和 [TaggingSettingsViewController.xcstrings](/Users/mcx/Documents/OpenSpring/FlowVision/FlowVision/Sources/SettingsViews/mul.lproj/TaggingSettingsViewController.xcstrings:100)。从入口看,应用也是通过 `NSOpenPanel` 选文件/文件夹、再按普通文件系统路径处理,[AppDelegate.swift](/Users/mcx/Documents/OpenSpring/FlowVision/FlowVision/Sources/AppDelegate.swift:492) 这一套对“已挂载的 SMB 卷”是兼容的。\n\n但如果你说的 `SMB` 是“应用里直接输入 `smb://...`,自己发起连接、认证、记住账号、自动重连”,那现在没有这个能力,而且不属于小改。当前架构本质上是 `FileManager + file:// 已挂载路径` 模型,没有看到 `smb://` 协议处理、挂载、认证、会话管理相关代码;同时 README 还写了“无网络请求”,见 [README_zh.md](/Users/mcx/Documents/OpenSpring/FlowVision/README_zh.md:70)。这意味着原生 SMB 接入不只是加一个入口,而是要改产品边界。\n\n所以实际判断是:\n\n- 已挂载 SMB 共享:现在就有可行性,属于“已有能力,只是没明说”。\n- 应用内原生 SMB 连接:当前代码基础上可做,但必须开发,且会影响架构和产品承诺。\n\n这次我没有改代码。 \n如果你需要,我下一步可以继续只做分析,帮你整理一版“最小 SMB 支持方案”的改动范围清单。","timestamp":"2026-04-21T04:40:41.978025Z"} +{"seq":3,"role":"user","agent":"codex","effort":"medium","content":"如何实现brew tap进我的github项目,完成我这个版本的安装","timestamp":"2026-04-21T04:42:26.448053Z"} +{"seq":4,"role":"agent","agent":"codex","effort":"medium","content":"我先看一下仓库里当前的发布产物和 README 现有安装说明,给你一套能直接落到这个项目上的 `brew tap` 方案,先不改代码。\n\n我已经确认 README 里现在写的是直接 `brew install flowvision`,但仓库里还没看到 tap/cask 配置。下一步我把这个项目对应的 Homebrew 发布方式具体化到可执行命令和 cask 文件。\n\n这个项目要走 `brew tap`,应该用 `Homebrew Cask`,不是普通 formula。因为你发的是 macOS GUI 应用 `.dmg`,不是命令行工具。\n\n按你现在这个仓库,最直接可落地的做法是:\n\n**1. 新建一个 tap 仓库**\n\n仓库名用这个最标准:\n\n```bash\nnetdcy/homebrew-tap\n```\n\nHomebrew 会把它识别成 tap `netdcy/tap`。\n\n**2. 在 tap 仓库里放 cask 文件**\n\n路径:\n\n```text\nCasks/flowvision.rb\n```\n\n内容可以直接用你这个版本:\n\n```ruby\ncask \"flowvision\" do\n version \"1.7.0\"\n sha256 \"9200dcaa1e4a89d64dba6788f190713e45b92c667aaa81ec10619dde5806dc92\"\n\n url \"https://github.com/netdcy/FlowVision/releases/download/v#{version}/FlowVision-Release-2026-04-19-v2.dmg\",\n verified: \"github.com/netdcy/FlowVision/\"\n name \"FlowVision\"\n desc \"Waterfall-style image viewer for macOS\"\n homepage \"https://github.com/netdcy/FlowVision\"\n\n depends_on macos: \"\u003e= :big_sur\"\n\n app \"FlowVision.app\"\nend\n```\n\n你这里有两个前提要满足:\n\n1. 你的 `FlowVision` 仓库里必须有一个 GitHub Release,tag 最好叫 `v1.7.0`\n2. 这个 Release 里必须上传 `FlowVision-Release-2026-04-19-v2.dmg`\n\n你现在这个 dmg 的 SHA256 我已经帮你算过了,就是上面这串。\n\n**3. 用户安装命令**\n\n发布后,安装命令应该写成:\n\n```bash\nbrew tap netdcy/tap\nbrew install --cask flowvision\n```\n\n或者一步到位:\n\n```bash\nbrew install --cask netdcy/tap/flowvision\n```\n\n升级:\n\n```bash\nbrew upgrade --cask flowvision\n```\n\n**4. 你 README_zh.md 现在这段要改**\n\n你现在写的是:\n\n```bash\nbrew install flowvision\n```\n\n这只有在进 `homebrew-cask` 官方仓库后才成立。对你自己的 GitHub 项目,应该改成:\n\n```md\n### Homebrew 方式安装\n\n首次安装\n```bash\nbrew tap netdcy/tap\nbrew install --cask flowvision\n```\n\n或直接:\n```bash\nbrew install --cask netdcy/tap/flowvision\n```\n\n版本升级\n```bash\nbrew update\nbrew upgrade --cask flowvision\n```\n```\n\n**5. 一个实际建议**\n\n你当前发布文件名是按日期命名的,这能用,但不利于后续维护。更适合改成这种:\n\n```text\nFlowVision-1.7.0.dmg\n```\n\n这样 cask 会更清晰:\n\n```ruby\nurl \"https://github.com/netdcy/FlowVision/releases/download/v#{version}/FlowVision-#{version}.dmg\"\n```\n\n后面每次发版只改两处:\n\n1. `version`\n2. `sha256`\n\n如果你愿意,我下一步可以直接帮你产出:\n\n1. `homebrew-tap` 仓库里的完整 `Casks/flowvision.rb`\n2. 你这个仓库里可直接替换的 `README_zh.md` 安装段落\n3. 一个自动发 GitHub Release 并更新 cask 的 GitHub Actions 方案","timestamp":"2026-04-21T04:42:26.44946Z"} diff --git a/.mindfs/sessions/session-list.db b/.mindfs/sessions/session-list.db new file mode 100644 index 00000000..949d29e6 Binary files /dev/null and b/.mindfs/sessions/session-list.db differ diff --git a/FlowVision-Release-2026-04-19-v2.dmg b/FlowVision-Release-2026-04-19-v2.dmg new file mode 100644 index 00000000..7c310f60 Binary files /dev/null and b/FlowVision-Release-2026-04-19-v2.dmg differ diff --git a/FlowVision-Release-2026-04-19-v2.zip b/FlowVision-Release-2026-04-19-v2.zip new file mode 100644 index 00000000..cdff809f Binary files /dev/null and b/FlowVision-Release-2026-04-19-v2.zip differ diff --git a/FlowVision-Release-2026-04-19.dmg b/FlowVision-Release-2026-04-19.dmg new file mode 100644 index 00000000..763f16ea Binary files /dev/null and b/FlowVision-Release-2026-04-19.dmg differ diff --git a/FlowVision-Release-2026-04-19.zip b/FlowVision-Release-2026-04-19.zip new file mode 100644 index 00000000..d0f32037 Binary files /dev/null and b/FlowVision-Release-2026-04-19.zip differ diff --git a/FlowVision-Release-20260419.zip b/FlowVision-Release-20260419.zip new file mode 100644 index 00000000..8f9e77fe Binary files /dev/null and b/FlowVision-Release-20260419.zip differ diff --git a/FlowVision.xcodeproj/project.pbxproj b/FlowVision.xcodeproj/project.pbxproj index d8075ea2..1b6c5215 100644 --- a/FlowVision.xcodeproj/project.pbxproj +++ b/FlowVision.xcodeproj/project.pbxproj @@ -72,6 +72,7 @@ F7A075582BA1D717009C47A6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F7A075572BA1D717009C47A6 /* Assets.xcassets */; }; F7A0755B2BA1D717009C47A6 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7A075592BA1D717009C47A6 /* Main.storyboard */; }; F7AA00012F9E000000AA0001 /* VideoPlayerControlsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7AA00002F9E000000AA0001 /* VideoPlayerControlsView.swift */; }; + 40694BBD27B5D5464D319BAE /* MPVPlayerBackend.swift in Sources */ = {isa = PBXBuildFile; fileRef = B513CF896032F495D8769284 /* MPVPlayerBackend.swift */; }; F7AAA8BD2D9BD1F2007CE330 /* VideoProcess.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7AAA8BC2D9BD1ED007CE330 /* VideoProcess.swift */; }; F7AC30052D37E26B00F48AEF /* CustomPathControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7AC30042D37E25800F48AEF /* CustomPathControl.swift */; }; F7C2DEB82C4E6AE9003DF765 /* Settings in Frameworks */ = {isa = PBXBuildFile; productRef = F7C2DEB72C4E6AE9003DF765 /* Settings */; }; @@ -175,6 +176,7 @@ F7790ED52BA5FB6A00406D35 /* CustomCollectionViewItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomCollectionViewItem.swift; sourceTree = ""; }; F7790ED62BA5FB6A00406D35 /* CustomCollectionViewItem.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CustomCollectionViewItem.xib; sourceTree = ""; }; F78960F12BDCC26B00C2571B /* LargeImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LargeImageView.swift; sourceTree = ""; }; + B513CF896032F495D8769284 /* MPVPlayerBackend.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPVPlayerBackend.swift; sourceTree = ""; }; F78960F52BDFFE9200C2571B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; F78D1A692D432DCE00741908 /* mul */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; name = mul; path = mul.lproj/Main.xcstrings; sourceTree = ""; }; F78D1A872D4CF31D00741908 /* GeneralSettingsViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = GeneralSettingsViewController.xib; path = Base.lproj/CustomSettingsViewController.xib; sourceTree = ""; }; @@ -251,6 +253,7 @@ F7FAE0002F6BA00000FAE000 /* FavoritesPopoverViewController.swift */, F78960F12BDCC26B00C2571B /* LargeImageView.swift */, F73865D42C37B9B800837FE4 /* Layout.swift */, + B513CF896032F495D8769284 /* MPVPlayerBackend.swift */, F7AA00002F9E000000AA0001 /* VideoPlayerControlsView.swift */, ); path = Views; @@ -485,6 +488,7 @@ F7790ED72BA5FB6A00406D35 /* CustomCollectionViewItem.swift in Sources */, F7663C162F222AAC0028DF35 /* ImageEditingView.swift in Sources */, F7AA00012F9E000000AA0001 /* VideoPlayerControlsView.swift in Sources */, + 40694BBD27B5D5464D319BAE /* MPVPlayerBackend.swift in Sources */, F74D555C2F0E501200C9AB85 /* EventHandler.swift in Sources */, F74D55522F0E46D200C9AB85 /* Search.swift in Sources */, F7FED5F32F7D0B1100E35164 /* Tagging.swift in Sources */, @@ -730,6 +734,7 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 20260422; + DEVELOPMENT_TEAM = M6WQA48PJ2; ENABLE_HARDENED_RUNTIME = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = FlowVision/Info.plist; @@ -763,7 +768,7 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 20260422; - DEVELOPMENT_TEAM = M9PR3WG2FN; + DEVELOPMENT_TEAM = M6WQA48PJ2; ENABLE_HARDENED_RUNTIME = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = FlowVision/Info.plist; diff --git a/FlowVision/.DS_Store b/FlowVision/.DS_Store new file mode 100644 index 00000000..27886a7f Binary files /dev/null and b/FlowVision/.DS_Store differ diff --git a/FlowVision/Resources/.DS_Store b/FlowVision/Resources/.DS_Store new file mode 100644 index 00000000..dbec438d Binary files /dev/null and b/FlowVision/Resources/.DS_Store differ diff --git a/FlowVision/Resources/Base.lproj/Main.storyboard b/FlowVision/Resources/Base.lproj/Main.storyboard index 4edffd50..0807d896 100644 --- a/FlowVision/Resources/Base.lproj/Main.storyboard +++ b/FlowVision/Resources/Base.lproj/Main.storyboard @@ -1,8 +1,8 @@ - + - + @@ -1201,11 +1201,11 @@ Gw -