From 9f06bffbeafbe89413038336fdecec35d4290975 Mon Sep 17 00:00:00 2001 From: Harry NG <90631770+harryngne@users.noreply.github.com> Date: Mon, 11 May 2026 13:24:22 +0700 Subject: [PATCH] chore: fix remarks shadowrocket subscription (#4247) --- frontend/src/pages/sub/SubPage.vue | 11 +++- sub/subController.go | 2 +- sub/subService.go | 82 ++++++++++++++++-------------- 3 files changed, 54 insertions(+), 41 deletions(-) diff --git a/frontend/src/pages/sub/SubPage.vue b/frontend/src/pages/sub/SubPage.vue index f35554be..561a2854 100644 --- a/frontend/src/pages/sub/SubPage.vue +++ b/frontend/src/pages/sub/SubPage.vue @@ -37,6 +37,8 @@ const lastOnlineMs = Number(subData.lastOnline || 0); const subUrl = subData.subUrl || ''; const subJsonUrl = subData.subJsonUrl || ''; const subClashUrl = subData.subClashUrl || ''; +const subTitle = subData.subTitle || ''; +const subSupportUrl = subData.subSupportUrl || ''; const links = Array.isArray(subData.links) ? subData.links : []; // Panel's "Calendar Type" setting; controls whether expiry / lastOnline // render in Gregorian or Jalali on this standalone subscription page. @@ -102,7 +104,14 @@ function linkName(link, idx) { // iOS deep links — taken verbatim from the legacy subpage. Each // client expects the sub URL in a slightly different param name. -const shadowrocketUrl = computed(() => `sub://${btoa(subUrl)}`); +const shadowrocketUrl = computed(() => { + if (!subUrl) return ''; + const separator = subUrl.includes('?') ? '&' : '?'; + const rawUrl = subUrl + separator + 'flag=shadowrocket'; + const base64Url = encodeURIComponent(btoa(rawUrl)); + const remark = encodeURIComponent(subTitle || sId || 'Subscription'); + return `shadowrocket://add/sub/${base64Url}?remark=${remark}`; +}); const v2boxUrl = computed(() => `v2box://install-sub?url=${encodeURIComponent(subUrl)}&name=${encodeURIComponent(sId)}`); const streisandUrl = computed(() => `streisand://import/${encodeURIComponent(subUrl)}`); const v2raytunUrl = computed(() => subUrl); diff --git a/sub/subController.go b/sub/subController.go index 3c309810..1f2be30b 100644 --- a/sub/subController.go +++ b/sub/subController.go @@ -128,7 +128,7 @@ func (a *SUBController) subs(c *gin.Context) { basePath = "/" } basePathStr := basePath.(string) - page := a.subService.BuildPageData(subId, hostHeader, traffic, lastOnline, subs, subURL, subJsonURL, subClashURL, basePathStr) + page := a.subService.BuildPageData(subId, hostHeader, traffic, lastOnline, subs, subURL, subJsonURL, subClashURL, basePathStr, a.subTitle, a.subSupportUrl) a.serveSubPage(c, basePathStr, page) return } diff --git a/sub/subService.go b/sub/subService.go index 6bfbea2b..2ec33e5f 100644 --- a/sub/subService.go +++ b/sub/subService.go @@ -1413,25 +1413,27 @@ func searchHost(headers any) string { // PageData is a view model for subpage.html // PageData contains data for rendering the subscription information page. type PageData struct { - Host string - BasePath string - SId string - Enabled bool - Download string - Upload string - Total string - Used string - Remained string - Expire int64 - LastOnline int64 - Datepicker string - DownloadByte int64 - UploadByte int64 - TotalByte int64 - SubUrl string - SubJsonUrl string - SubClashUrl string - Result []string + Host string + BasePath string + SId string + Enabled bool + Download string + Upload string + Total string + Used string + Remained string + Expire int64 + LastOnline int64 + Datepicker string + DownloadByte int64 + UploadByte int64 + TotalByte int64 + SubUrl string + SubJsonUrl string + SubClashUrl string + SubTitle string + SubSupportUrl string + Result []string } // ResolveRequest extracts scheme and host info from request/headers consistently. @@ -1545,7 +1547,7 @@ func (s *SubService) joinPathWithID(basePath, subId string) string { // BuildPageData parses header and prepares the template view model. // BuildPageData constructs page data for rendering the subscription information page. -func (s *SubService) BuildPageData(subId string, hostHeader string, traffic xray.ClientTraffic, lastOnline int64, subs []string, subURL, subJsonURL, subClashURL string, basePath string) PageData { +func (s *SubService) BuildPageData(subId string, hostHeader string, traffic xray.ClientTraffic, lastOnline int64, subs []string, subURL, subJsonURL, subClashURL string, basePath string, subTitle string, subSupportUrl string) PageData { download := common.FormatTraffic(traffic.Down) upload := common.FormatTraffic(traffic.Up) total := "∞" @@ -1563,25 +1565,27 @@ func (s *SubService) BuildPageData(subId string, hostHeader string, traffic xray } return PageData{ - Host: hostHeader, - BasePath: basePath, - SId: subId, - Enabled: traffic.Enable, - Download: download, - Upload: upload, - Total: total, - Used: used, - Remained: remained, - Expire: traffic.ExpiryTime / 1000, - LastOnline: lastOnline, - Datepicker: datepicker, - DownloadByte: traffic.Down, - UploadByte: traffic.Up, - TotalByte: traffic.Total, - SubUrl: subURL, - SubJsonUrl: subJsonURL, - SubClashUrl: subClashURL, - Result: subs, + Host: hostHeader, + BasePath: basePath, + SId: subId, + Enabled: traffic.Enable, + Download: download, + Upload: upload, + Total: total, + Used: used, + Remained: remained, + Expire: traffic.ExpiryTime / 1000, + LastOnline: lastOnline, + Datepicker: datepicker, + DownloadByte: traffic.Down, + UploadByte: traffic.Up, + TotalByte: traffic.Total, + SubUrl: subURL, + SubJsonUrl: subJsonURL, + SubClashUrl: subClashURL, + SubTitle: subTitle, + SubSupportUrl: subSupportUrl, + Result: subs, } }