Skip to content
Open
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
Binary file added .DS_Store
Binary file not shown.
136 changes: 136 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -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
4 changes: 4 additions & 0 deletions .mindfs/sessions/1776746378-31906b751c86.jsonl
Original file line number Diff line number Diff line change
@@ -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"}
Binary file added .mindfs/sessions/session-list.db
Binary file not shown.
Binary file added FlowVision-Release-2026-04-19-v2.dmg
Binary file not shown.
Binary file added FlowVision-Release-2026-04-19-v2.zip
Binary file not shown.
Binary file added FlowVision-Release-2026-04-19.dmg
Binary file not shown.
Binary file added FlowVision-Release-2026-04-19.zip
Binary file not shown.
Binary file added FlowVision-Release-20260419.zip
Binary file not shown.
7 changes: 6 additions & 1 deletion FlowVision.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -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 */; };
Expand Down Expand Up @@ -175,6 +176,7 @@
F7790ED52BA5FB6A00406D35 /* CustomCollectionViewItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomCollectionViewItem.swift; sourceTree = "<group>"; };
F7790ED62BA5FB6A00406D35 /* CustomCollectionViewItem.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CustomCollectionViewItem.xib; sourceTree = "<group>"; };
F78960F12BDCC26B00C2571B /* LargeImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LargeImageView.swift; sourceTree = "<group>"; };
B513CF896032F495D8769284 /* MPVPlayerBackend.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPVPlayerBackend.swift; sourceTree = "<group>"; };
F78960F52BDFFE9200C2571B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
F78D1A692D432DCE00741908 /* mul */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; name = mul; path = mul.lproj/Main.xcstrings; sourceTree = "<group>"; };
F78D1A872D4CF31D00741908 /* GeneralSettingsViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = GeneralSettingsViewController.xib; path = Base.lproj/CustomSettingsViewController.xib; sourceTree = "<group>"; };
Expand Down Expand Up @@ -251,6 +253,7 @@
F7FAE0002F6BA00000FAE000 /* FavoritesPopoverViewController.swift */,
F78960F12BDCC26B00C2571B /* LargeImageView.swift */,
F73865D42C37B9B800837FE4 /* Layout.swift */,
B513CF896032F495D8769284 /* MPVPlayerBackend.swift */,
F7AA00002F9E000000AA0001 /* VideoPlayerControlsView.swift */,
);
path = Views;
Expand Down Expand Up @@ -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 */,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
Binary file added FlowVision/.DS_Store
Binary file not shown.
Binary file added FlowVision/Resources/.DS_Store
Binary file not shown.
8 changes: 4 additions & 4 deletions FlowVision/Resources/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="24412" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="24128" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24412"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24128"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="System colors introduced in macOS 10.14" minToolsVersion="10.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
Expand Down Expand Up @@ -1201,11 +1201,11 @@ Gw
</textView>
</subviews>
</clipView>
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="2fu-s8-8On">
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="2fu-s8-8On">
<rect key="frame" x="-100" y="-100" width="225" height="15"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" verticalHuggingPriority="750" horizontal="NO" id="SXi-ew-SdF">
<scroller key="verticalScroller" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="SXi-ew-SdF">
<rect key="frame" x="745" y="0.0" width="15" height="522"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
Expand Down
Loading