Proton Drive Polybar Module - Design Document
Overview
Add a 3-state polybar module for Proton Drive sync status. The icon reflects current state, and click actions are state-aware.
States
| State | Icon | Meaning |
|---|---|---|
| Not Configured | | ProtonDrive not set up |
| Needs Sync | | Files out of sync (or never synced) |
| Synced | | Local matches remote |
CLI Flags
--proton-drive
Polybar module - outputs icon for display.
$ openriot --proton-drive
Proton Drive: Synced
Or for hidden state (not configured):
$ openriot --proton-drive
(nothing - module hidden)
--proton-drive-sync
Click action - reads state, performs appropriate action.
| State | Action |
|---|---|
| Not Configured | Notify “Proton Drive is not configured” |
| Needs Sync | Open floating terminal with sync command |
| Synced | Notify “Proton Drive is Synced” |
Sync command:
alacritty -e sh -c "rclone bisync ~/ProtonSync proton:ProtonSync --progress --work-dir ~/.cache/rclone/bisync; echo 'Press enter to close...'; read"
Logic
isProtonDriveConfigured() = false → "not-configured"
isProtonDriveConfigured() = true:
├─ Check ~/.cache/rclone/bisync/home_{username}_ProtonSync..proton_ProtonSync.path1.lst
├─ Check ~/.cache/rclone/bisync/home_{username}_ProtonSync..proton_ProtonSync.path2.lst
├─ If either missing OR files differ → "needs-sync"
└─ If both exist AND identical → "synced"
Configuration check:
func isProtonDriveConfigured() bool {
home := os.Getenv("HOME")
// Check for ~/ProtonSync folder
syncFolder := home + "/ProtonSync"
if _, err := os.Stat(syncFolder); err != nil {
return false
}
// Check for rclone config
rcloneConf := home + "/.config/rclone/rclone.conf"
if _, err := os.Stat(rcloneConf); err != nil {
return false
}
return true
}
Sync status check:
func checkProtonDriveSync() string {
home := os.Getenv("HOME")
bisyncDir := home + "/.cache/rclone/bisync"
path1 := bisyncDir + "/home_{username}_ProtonSync..proton_ProtonSync.path1.lst"
path2 := bisyncDir + "/home_{username}_ProtonSync..proton_ProtonSync.path2.lst"
// Check both files exist
if _, err := os.Stat(path1); os.IsNotExist(err) {
return "needs-sync"
}
if _, err := os.Stat(path2); os.IsNotExist(err) {
return "needs-sync"
}
// Compare files
content1, _ := os.ReadFile(path1)
content2, _ := os.ReadFile(path2)
if string(content1) == string(content2) {
return "synced"
}
return "needs-sync"
}
Implementation Checklist
Files to Modify
source/polybar/polybar.go- Update
isProtonDriveConfigured()- keep existing - Add
checkProtonDriveSync()function - Add
GetProtonDriveState()- combines config check + sync check - Update
GetProtonDriveIcon()- returns //empty based on state - Update
getProtonDriveTooltip()- returns “Synced”/”Needs Sync”/”Not configured” - Update
RunProtonDrive()- uses new state logic
- Update
source/main.go- Modify
--proton-drive-syncflag - Add state detection before running sync
- Implement state-aware click behavior
- Modify
config/polybar/config.ini- Add
proton-drivemodule entry
- Add
Polybar Config
[module/proton-drive]
type = custom/script
exec = $HOME/.local/share/openriot/install/openriot --proton-drive
interval = 60
format-padding = 1
click-left = $HOME/.local/share/openriot/install/openriot --proton-drive-sync
Notification Messages
| Trigger | Message |
|---|---|
| Not configured (click) | “Proton Drive is not configured” |
| Synced (click) | “Proton Drive is Synced” |
| Sync started | “Syncing Proton Drive…” |
| Sync complete | “Proton Drive sync complete” |
| Sync failed | “Proton Drive sync failed” |
Edge Cases
- ProtonSync directory deleted after config
- State returns to “not-configured”
- rclone not installed
- Click on “Needs Sync” shows error notification
- bisync never run
- path1.lst missing → “needs-sync”
- Network offline
- “needs-sync” (bisync fails, cache not updated)
Future Enhancements (Not This PR)
- Auto-sync every 30 minutes (background polling)
- Show file count differences in notification
- Conflict detection and resolution