diff --git a/.github/release-footer.md b/.github/release-footer.md new file mode 100644 index 0000000..30ce250 --- /dev/null +++ b/.github/release-footer.md @@ -0,0 +1,26 @@ + +--- + +## How to install + +This release is distributed via the HellionChat custom repository, not the +Dalamud main plugin repo. To install: + +1. In XIVLauncher: **Settings → Experimental → Custom Plugin Repositories** +2. Add the URL: + `https://raw.githubusercontent.com/JonKazama-Hellion/HellionChat/main/repo.json` +3. Enable, save, then `/xlplugins` → search **Hellion Chat** → install + +## Project documents + +- [README](https://github.com/JonKazama-Hellion/HellionChat/blob/main/README.md) — features, architecture, build +- [Privacy notice](https://github.com/JonKazama-Hellion/HellionChat/blob/main/PRIVACY.md) — what the plugin stores and sends +- [Third-party notices](https://github.com/JonKazama-Hellion/HellionChat/blob/main/THIRD_PARTY_NOTICES.md) — dependencies and licences +- [Security policy](https://github.com/JonKazama-Hellion/HellionChat/blob/main/SECURITY.md) — vulnerability reporting +- [Support](https://github.com/JonKazama-Hellion/HellionChat/blob/main/SUPPORT.md) — bug reports, questions, contact paths + +## Licence + +[EUPL-1.2](https://github.com/JonKazama-Hellion/HellionChat/blob/main/LICENSE). +Based on [Chat 2](https://github.com/Infiziert90/ChatTwo) by Infi and Anna, +also EUPL-1.2. diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 581a9c9..1e1cf33 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,6 +16,16 @@ on: push: tags: - 'v*' + # Manual recovery trigger. Use when a tag was pushed but the auto-run + # was missed or failed: `gh workflow run release.yml -f tag=v0.6.1`. + # The tag input is validated against the same semver regex as the + # auto-trigger before any string interpolation happens. + workflow_dispatch: + inputs: + tag: + description: 'Existing tag to (re)release, e.g. v0.6.1' + required: true + type: string permissions: contents: write @@ -27,8 +37,14 @@ jobs: timeout-minutes: 20 steps: + # On push:tags, github.ref_name is the tag — checkout default works. + # On workflow_dispatch, ref defaults to the branch the action was + # invoked from; we need to explicitly check out the tag the user + # supplied so the build comes from the tagged commit, not main. - name: Checkout uses: actions/checkout@v6 + with: + ref: ${{ github.event.inputs.tag || github.ref }} - name: Setup .NET 10 uses: actions/setup-dotnet@v4 @@ -71,7 +87,12 @@ jobs: - name: Generate release body shell: pwsh env: - TAG_NAME: ${{ github.ref_name }} + # workflow_dispatch carries the user-supplied tag in inputs.tag; + # push:tags carries it in github.ref_name. Either way the value + # is treated as a PowerShell variable (env-var pass), not as + # inline shell text, and validated against the semver regex + # below before any string interpolation. + TAG_NAME: ${{ github.event.inputs.tag || github.ref_name }} run: | $tag = $env:TAG_NAME if ($tag -notmatch '^v\d+\.\d+\.\d+$') { @@ -112,34 +133,14 @@ jobs: $currentBlock = $rest.TrimEnd() } - $footer = @' - ---- - -## How to install - -This release is distributed via the HellionChat custom repository, not the -Dalamud main plugin repo. To install: - -1. In XIVLauncher: **Settings → Experimental → Custom Plugin Repositories** -2. Add the URL: - `https://raw.githubusercontent.com/JonKazama-Hellion/HellionChat/main/repo.json` -3. Enable, save, then `/xlplugins` → search **Hellion Chat** → install - -## Project documents - -- [README](https://github.com/JonKazama-Hellion/HellionChat/blob/main/README.md) — features, architecture, build -- [Privacy notice](https://github.com/JonKazama-Hellion/HellionChat/blob/main/PRIVACY.md) — what the plugin stores and sends -- [Third-party notices](https://github.com/JonKazama-Hellion/HellionChat/blob/main/THIRD_PARTY_NOTICES.md) — dependencies and licences -- [Security policy](https://github.com/JonKazama-Hellion/HellionChat/blob/main/SECURITY.md) — vulnerability reporting -- [Support](https://github.com/JonKazama-Hellion/HellionChat/blob/main/SUPPORT.md) — bug reports, questions, contact paths - -## Licence - -[EUPL-1.2](https://github.com/JonKazama-Hellion/HellionChat/blob/main/LICENSE). -Based on [Chat 2](https://github.com/Infiziert90/ChatTwo) by Infi and Anna, -also EUPL-1.2. -'@ + # Static install / docs / licence footer is maintained as a + # separate file so the workflow YAML stays clean (no embedded + # heredoc that would have to be indented under the run-block). + $footerPath = ".github/release-footer.md" + if (-not (Test-Path $footerPath)) { + throw "Release footer template not found: $footerPath" + } + $footer = Get-Content -Path $footerPath -Raw $body = $currentBlock + "`n" + $footer $body | Out-File -FilePath release-body.md -Encoding utf8 -NoNewline @@ -152,6 +153,11 @@ also EUPL-1.2. - name: Attach to GitHub release uses: softprops/action-gh-release@v3 with: + # Explicit tag_name so the action targets the correct release in + # both push:tags (auto) and workflow_dispatch (manual recovery) + # modes. Without this, dispatch runs would default to the branch + # ref (main) and fail to find the release. + tag_name: ${{ github.event.inputs.tag || github.ref_name }} files: ${{ steps.locate.outputs.path }} body_path: release-body.md fail_on_unmatched_files: true diff --git a/ChatTwo/AutoTellTabsService.cs b/ChatTwo/AutoTellTabsService.cs index 100f7b0..5234b0c 100644 --- a/ChatTwo/AutoTellTabsService.cs +++ b/ChatTwo/AutoTellTabsService.cs @@ -183,6 +183,22 @@ internal sealed class AutoTellTabsService : IDisposable return; } + // v0.6.1 — if the victim is currently popped out, tear down the + // matching Popout window first. Otherwise the window stays in + // PopOutWindows + WindowSystem and renders empty / re-spawns on the + // next AddPopOutsToDraw tick. Latent since pop-outs were introduced; + // becomes visible with AutoTellTabsOpenAsPopout where dropping a + // popped tab is now a routine code path. + if (victim.Tab.PopOut) + { + var popout = _plugin.ChatLogWindow.ActivePopouts + .FirstOrDefault(p => p.TabIdentifier == victim.Tab.Identifier); + if (popout != null) + { + popout.IsOpen = false; + } + } + Plugin.Config.Tabs.RemoveAt(victim.Index); // Re-anchor the active tab so the user does not silently end up on @@ -207,6 +223,17 @@ internal sealed class AutoTellTabsService : IDisposable PreloadHistory(tab, partner.Name, partner.World, currentMessage.Id); tab.AddMessage(currentMessage, unread: true); + + // Hellion Chat v0.6.1 — opt-in: open new /tell tabs directly as a + // pop-out window. Set BEFORE Tabs.Add so the next render-tick's + // AddPopOutsToDraw() sees PopOut=true and spawns the Popout window + // alongside the tab going into the list. No SaveConfig() because + // auto-tell tabs are IsTempTab (session-only, never persisted). + if (Plugin.Config.AutoTellTabsOpenAsPopout) + { + tab.PopOut = true; + } + Plugin.Config.Tabs.Add(tab); } @@ -355,6 +382,27 @@ internal sealed class AutoTellTabsService : IDisposable var lastIndexValid = lastIndex >= 0 && lastIndex < Plugin.Config.Tabs.Count; var currentWasTempTab = lastIndexValid && Plugin.Config.Tabs[lastIndex].IsTempTab; + // v0.6.1 — symmetric to DropOldestTempTab cleanup: tear down any + // popped-out temp tab windows before removing the tabs themselves, + // otherwise PopOutWindows + WindowSystem keep ghost entries until + // the next plugin reload. Especially relevant once Auto-Pop-Out is + // enabled — every logout would otherwise leak as many ghosts as + // there were active /tell pop-outs. + var poppedTempTabIds = Plugin.Config.Tabs + .Where(t => t.IsTempTab && t.PopOut) + .Select(t => t.Identifier) + .ToList(); + if (poppedTempTabIds.Count > 0) + { + var poppedSet = poppedTempTabIds.ToHashSet(); + foreach (var popout in _plugin.ChatLogWindow.ActivePopouts + .Where(p => poppedSet.Contains(p.TabIdentifier)) + .ToList()) + { + popout.IsOpen = false; + } + } + Plugin.Config.Tabs.RemoveAll(t => t.IsTempTab); // Force a switch to tab 0 if the active tab was a temp tab OR diff --git a/ChatTwo/ChatTwo.csproj b/ChatTwo/ChatTwo.csproj index 9b43ba3..69b12b1 100644 --- a/ChatTwo/ChatTwo.csproj +++ b/ChatTwo/ChatTwo.csproj @@ -4,7 +4,7 @@ 0.1.0 is our bootstrap release; the underlying Chat 2 base is called out in the yaml changelog so users can see what it derives from. --> - 0.6.0 + 0.6.1 enable