Skip to content

Commit fdcb83f

Browse files
committed
updated with update notification banner
1 parent f867716 commit fdcb83f

File tree

6 files changed

+127
-1
lines changed

6 files changed

+127
-1
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file. For commit
44

55
## v0.7.9-beta
66

7+
**New Features**:
8+
- Admin users get small notification banner for available update in sidebar with link to new release.
9+
710
**Notes**:
811
- docker now defaults to ./data/databse.db as the database path allowing a simplified initial docker-compose.yaml. Existing configurations do not need updating.
912
- oidc groups header updates admin permission of existing user (either add/remove if role exists)'

backend/cmd/root.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111

1212
"github.com/gtsteffaniak/filebrowser/backend/adapters/fs/fileutils"
1313
"github.com/gtsteffaniak/filebrowser/backend/common/settings"
14+
"github.com/gtsteffaniak/filebrowser/backend/common/utils"
1415
"github.com/gtsteffaniak/filebrowser/backend/common/version"
1516
"github.com/gtsteffaniak/filebrowser/backend/database/storage"
1617
fbhttp "github.com/gtsteffaniak/filebrowser/backend/http"
@@ -52,6 +53,15 @@ func StartFilebrowser() {
5253
if !keepGoing {
5354
return
5455
}
56+
info, err := utils.CheckForUpdates()
57+
if err != nil {
58+
logger.Errorf("Error checking for updates: %v", err)
59+
} else if info.LatestVersion != "" {
60+
logger.Infof("A new version is available: %s (current: %s)", info.LatestVersion, info.CurrentVersion)
61+
logger.Infof("Release notes: %s", info.ReleaseNotes)
62+
}
63+
go utils.StartCheckForUpdates()
64+
5565
// Create context and channels for graceful shutdown
5666
ctx, cancel := context.WithCancel(context.Background())
5767
defer cancel()
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package utils
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"net/http"
7+
"strings"
8+
"time"
9+
10+
"github.com/gtsteffaniak/filebrowser/backend/common/version"
11+
"github.com/gtsteffaniak/go-logger/logger"
12+
"golang.org/x/mod/semver"
13+
)
14+
15+
var updateAvailableUrl = ""
16+
17+
type Tag struct {
18+
Name string `json:"name"`
19+
}
20+
21+
type updateInfo struct {
22+
LatestVersion string
23+
CurrentVersion string
24+
ReleaseNotes string
25+
ReleaseUrl string
26+
}
27+
28+
func CheckForUpdates() (updateInfo, error) {
29+
// --- Configuration ---
30+
repoOwner := "gtsteffaniak"
31+
repoName := "filebrowser"
32+
currentVersion := version.Version
33+
splitVersion := strings.Split(currentVersion, "-")
34+
versionCategory := "stable"
35+
if len(splitVersion) > 1 {
36+
versionCategory = splitVersion[1]
37+
}
38+
githubApiUrl := fmt.Sprintf("https://api.github.com/repos/%s/%s/tags", repoOwner, repoName)
39+
// Make the GET request
40+
resp, err := http.Get(githubApiUrl)
41+
if err != nil {
42+
return updateInfo{}, err
43+
}
44+
defer resp.Body.Close()
45+
46+
if resp.StatusCode != http.StatusOK {
47+
return updateInfo{}, fmt.Errorf("failed to fetch tags from GitHub API")
48+
}
49+
// Decode the JSON response
50+
var tags []Tag
51+
if err := json.NewDecoder(resp.Body).Decode(&tags); err != nil {
52+
return updateInfo{}, err
53+
}
54+
// Find the latest beta version greater than the current one
55+
var NewVersion string
56+
for _, tag := range tags {
57+
// Check if the version is valid, is a pre-release, and contains "beta"
58+
if semver.IsValid(tag.Name) && strings.Contains(semver.Prerelease(tag.Name), versionCategory) {
59+
// Check if this tag is greater than the current version
60+
// and also greater than any other beta version we've found so far
61+
if semver.Compare(tag.Name, currentVersion) > 0 {
62+
if NewVersion == "" || semver.Compare(tag.Name, NewVersion) > 0 {
63+
NewVersion = tag.Name
64+
}
65+
}
66+
}
67+
}
68+
if NewVersion == "" {
69+
// No newer version found, return empty updateInfo
70+
return updateInfo{}, fmt.Errorf("no newer version found for %s", currentVersion)
71+
}
72+
73+
updateAvailableUrl = fmt.Sprintf("https://github.com/%s/%s/releases/tag/%s", repoOwner, repoName, NewVersion)
74+
return updateInfo{
75+
LatestVersion: NewVersion,
76+
CurrentVersion: currentVersion,
77+
ReleaseNotes: updateAvailableUrl,
78+
ReleaseUrl: updateAvailableUrl,
79+
}, nil
80+
}
81+
82+
func GetUpdateAvailableUrl() string {
83+
return updateAvailableUrl
84+
}
85+
86+
// starts a background process to check for updates periodically.
87+
func StartCheckForUpdates() {
88+
// Create a ticker that fires every 24 hours.
89+
ticker := time.NewTicker(24 * time.Hour)
90+
defer ticker.Stop()
91+
// Start a loop that waits for the ticker to fire.
92+
for range ticker.C {
93+
_, err := CheckForUpdates()
94+
if err != nil {
95+
// In a real application, you might want more sophisticated logging.
96+
logger.Debug("update check failed:", err)
97+
continue // Don't stop the loop, just wait for the next tick.
98+
}
99+
// Update the global variable with the result of the check.
100+
// This will be an empty string if no newer version was found.
101+
}
102+
}

backend/http/static.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"text/template"
1010

1111
"github.com/gtsteffaniak/filebrowser/backend/common/settings"
12+
"github.com/gtsteffaniak/filebrowser/backend/common/utils"
1213
"github.com/gtsteffaniak/filebrowser/backend/common/version"
1314
)
1415

@@ -59,6 +60,7 @@ func handleWithStaticData(w http.ResponseWriter, r *http.Request, file, contentT
5960
"PasswordAvailable": config.Auth.Methods.PasswordAuth.Enabled,
6061
"MediaAvailable": config.Integrations.Media.FfmpegPath != "",
6162
"MuPdfAvailable": config.Server.MuPdfAvailable,
63+
"UpdateAvailable": utils.GetUpdateAvailableUrl(),
6264
}
6365

6466
b, err := json.Marshal(data)

frontend/src/components/sidebar/Sidebar.vue

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,15 @@
1414
<span v-if="name != ''">
1515
<h4 style="margin: 0">{{ name }}</h4>
1616
</span>
17+
<div v-if="shouldShow" class="release-banner">
18+
<a :href="releaseUrl" >A new version is available!</a>
19+
</div>
1720
</div>
1821
</nav>
1922
</template>
2023

2124
<script>
22-
import { externalLinks, name } from "@/utils/constants";
25+
import { externalLinks, name, updateAvailable } from "@/utils/constants";
2326
import { getters, mutations, state } from "@/store"; // Import your custom store
2427
import SidebarGeneral from "./General.vue";
2528
import SidebarSettings from "./Settings.vue";
@@ -37,11 +40,15 @@ export default {
3740
};
3841
},
3942
computed: {
43+
releaseUrl: () => updateAvailable,
4044
isDarkMode: () => getters.isDarkMode(),
4145
isLoggedIn: () => getters.isLoggedIn(),
4246
isSettings: () => getters.isSettings(),
4347
active: () => getters.isSidebarVisible(),
4448
behindOverlay: () => state.isSearchActive,
49+
shouldShow() {
50+
return updateAvailable != "" && state.user.permissions.admin;
51+
},
4552
},
4653
methods: {
4754
// Show the help overlay

frontend/src/utils/constants.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const oidcAvailable = window.FileBrowser.OidcAvailable;
2222
const passwordAvailable = window.FileBrowser.PasswordAvailable;
2323
const mediaAvailable = window.FileBrowser.MediaAvailable;
2424
const muPdfAvailable = window.FileBrowser.MuPdfAvailable;
25+
const updateAvailable = window.FileBrowser.UpdateAvailable;
2526
const origin = window.location.origin;
2627

2728
const settings = [
@@ -33,6 +34,7 @@ const settings = [
3334
];
3435

3536
export {
37+
updateAvailable,
3638
muPdfAvailable,
3739
mediaAvailable,
3840
oidcAvailable,

0 commit comments

Comments
 (0)