diff --git a/.github/workflows/typewriter.yml b/.github/workflows/typewriter.yml new file mode 100644 index 0000000..7aca494 --- /dev/null +++ b/.github/workflows/typewriter.yml @@ -0,0 +1,107 @@ +name: Build TypewriterEffect (SE5) + +on: + push: + branches: [main] + paths: + - 'se5/TypewriterEffect/**' + - '.github/workflows/typewriter.yml' + pull_request: + paths: + - 'se5/TypewriterEffect/**' + - '.github/workflows/typewriter.yml' + workflow_dispatch: + inputs: + tag: + description: 'Release tag to publish the zips under (e.g. se5-typewriter-v1.0). Leave empty to build artifacts only.' + required: false + type: string + +jobs: + build: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - rid: win-x64 + os: windows + exe: TypewriterEffect.exe + - rid: win-arm64 + os: windows + exe: TypewriterEffect.exe + - rid: linux-x64 + os: linux + exe: TypewriterEffect + - rid: linux-arm64 + os: linux + exe: TypewriterEffect + - rid: osx-x64 + os: macos + exe: TypewriterEffect + - rid: osx-arm64 + os: macos + exe: TypewriterEffect + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup .NET 8 + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '8.0.x' + + - name: Publish self-contained (${{ matrix.rid }}) + working-directory: se5/TypewriterEffect + run: | + dotnet publish TypewriterEffect.csproj \ + -c Release \ + -r ${{ matrix.rid }} \ + --self-contained true \ + -p:PublishSingleFile=true \ + -p:IncludeNativeLibrariesForSelfExtract=true \ + -o staging/TypewriterEffect + + - name: Rewrite plugin.json for ${{ matrix.os }} + working-directory: se5/TypewriterEffect + run: | + jq ' + del(.runtime, .entry) | + .executables = { "${{ matrix.os }}": "${{ matrix.exe }}" } + ' plugin.json > staging/TypewriterEffect/plugin.json + + - name: Package zip + working-directory: se5/TypewriterEffect/staging + run: zip -r "$GITHUB_WORKSPACE/TypewriterEffect-${{ matrix.rid }}.zip" TypewriterEffect + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: TypewriterEffect-${{ matrix.rid }} + path: TypewriterEffect-${{ matrix.rid }}.zip + + release: + name: Publish GitHub Release + needs: build + if: github.event_name == 'workflow_dispatch' && github.event.inputs.tag != '' + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Download all zips + uses: actions/download-artifact@v4 + with: + path: dist + pattern: TypewriterEffect-* + merge-multiple: true + + - name: Create release and upload zips + env: + GH_TOKEN: ${{ github.token }} + run: | + gh release create "${{ github.event.inputs.tag }}" dist/TypewriterEffect-*.zip \ + --repo "${{ github.repository }}" \ + --target "${{ github.sha }}" \ + --title "TypewriterEffect ${{ github.event.inputs.tag }}" \ + --notes "Self-contained TypewriterEffect plugin builds for win/linux/osx (x64 + arm64)." diff --git a/se5-plugins.json b/se5-plugins.json index ae76ba2..add5a84 100644 --- a/se5-plugins.json +++ b/se5-plugins.json @@ -1,5 +1,22 @@ { "plugins": [ + { + "name": "Typewriter effect", + "description": "Splits each subtitle line into short timed parts that progressively reveal the text, character by character.", + "version": "1.0.0", + "author": "Subtitle Edit", + "url": "https://github.com/SubtitleEdit/plugins/tree/main/se5/TypewriterEffect", + "date": "2026-05-17", + "minSeVersion": "5.0.0", + "downloads": { + "win-x64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0/TypewriterEffect-win-x64.zip", + "win-arm64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0/TypewriterEffect-win-arm64.zip", + "linux-x64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0/TypewriterEffect-linux-x64.zip", + "linux-arm64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0/TypewriterEffect-linux-arm64.zip", + "osx-x64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0/TypewriterEffect-osx-x64.zip", + "osx-arm64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0/TypewriterEffect-osx-arm64.zip" + } + }, { "name": "Haxor", "description": "Translates the text of the selected lines (or all lines) to haxor.", diff --git a/se5/TypewriterEffect/App.axaml b/se5/TypewriterEffect/App.axaml new file mode 100644 index 0000000..c802d73 --- /dev/null +++ b/se5/TypewriterEffect/App.axaml @@ -0,0 +1,8 @@ + + + + + diff --git a/se5/TypewriterEffect/App.axaml.cs b/se5/TypewriterEffect/App.axaml.cs new file mode 100644 index 0000000..6e1699b --- /dev/null +++ b/se5/TypewriterEffect/App.axaml.cs @@ -0,0 +1,34 @@ +using Avalonia; +using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Markup.Xaml; +using Avalonia.Styling; + +namespace SubtitleEdit.Plugins.TypewriterEffect; + +public partial class App : Application +{ + /// Set by Program.Main before Avalonia starts. + public static PluginRequest? PendingRequest; + + /// Filled in by MainWindow when the user clicks OK or Cancel. + public static PluginResponse? Response; + + public override void Initialize() => AvaloniaXamlLoader.Load(this); + + public override void OnFrameworkInitializationCompleted() + { + if (PendingRequest is not null) + { + RequestedThemeVariant = string.Equals(PendingRequest.Theme, "Dark", System.StringComparison.OrdinalIgnoreCase) + ? ThemeVariant.Dark + : ThemeVariant.Light; + + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + { + desktop.MainWindow = new MainWindow(PendingRequest); + } + } + + base.OnFrameworkInitializationCompleted(); + } +} diff --git a/se5/TypewriterEffect/MainWindow.axaml b/se5/TypewriterEffect/MainWindow.axaml new file mode 100644 index 0000000..bfc130c --- /dev/null +++ b/se5/TypewriterEffect/MainWindow.axaml @@ -0,0 +1,54 @@ + + + +