add:clean all func

This commit is contained in:
2026-04-06 03:26:02 +09:00
parent e39ee1694d
commit 83aab9d943
7 changed files with 138 additions and 3 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
.env
dist

View File

@@ -0,0 +1,5 @@
package pages
type CleanAllPageMsg struct {
ServerName string
}

View File

@@ -77,6 +77,14 @@ func (s *StorageService) Send(localPaths []string) error {
// CleanAll removes all files from remote storage.
func (s *StorageService) CleanAll() error {
// TODO: implement
return fmt.Errorf("clean all: not yet implemented")
cmd := SSHCmd(s.server,
"rm -f "+defaultStoragePath+"/*",
)
debugLog("CleanAll | args: %v", cmd.Args)
out, err := cmd.CombinedOutput()
debugLog("CleanAll | exit_err: %v | output: %q", err, strings.TrimSpace(string(out)))
if err != nil {
return fmt.Errorf("clean all failed: %w\n%s", err, strings.TrimSpace(string(out)))
}
return nil
}

View File

@@ -86,6 +86,12 @@ var (
Foreground(lipgloss.Color("203")).
MarginTop(1)
CleanWarningStyle = lipgloss.NewStyle().
Foreground(lipgloss.Color("203")).
Bold(true).
MarginBottom(1).
Width(44)
// Footer
FooterStyle = lipgloss.NewStyle().
Foreground(lipgloss.Color("240")).

View File

@@ -3,6 +3,8 @@ package tui
import (
"filepass/internal/pages"
"filepass/internal/services"
"charm.land/bubbles/v2/textinput"
)
type page int
@@ -15,6 +17,7 @@ const (
pageServerActions
pageFileAction
pageSend
pageCleanAll
)
type TUIInterface struct {
@@ -45,6 +48,10 @@ type TUIInterface struct {
FileOpLoading bool
FileOpErr error
FileOpSuccess string
// clean all confirmation page
CleanInput textinput.Model
CleanOpLoading bool
CleanOpErr error
// send / file picker page
Picker picker
}

View File

@@ -8,6 +8,7 @@ import (
"filepass/internal/pages"
"filepass/internal/services"
"charm.land/bubbles/v2/textinput"
tea "charm.land/bubbletea/v2"
)
@@ -60,6 +61,30 @@ func deleteFileCmd(store *services.ServicesStore, serverName, filename string) t
}
}
type cleanAllMsg struct {
err error
}
func cleanAllCmd(store *services.ServicesStore, serverName string) tea.Cmd {
return func() tea.Msg {
storage, err := store.NewStorageService(serverName)
if err != nil {
return cleanAllMsg{err: err}
}
return cleanAllMsg{err: storage.CleanAll()}
}
}
func newCleanInput() textinput.Model {
ti := textinput.New()
ti.Placeholder = "yes"
ti.Prompt = ""
ti.CharLimit = 3
ti.SetWidth(10)
ti.Focus()
return ti
}
func checkStorageCmd(store *services.ServicesStore, serverName string) tea.Cmd {
return func() tea.Msg {
storage, err := store.NewStorageService(serverName)
@@ -152,6 +177,22 @@ func (m TUIInterface) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.FileOpSuccess = ""
return m, nil
case pages.CleanAllPageMsg:
m.Page = pageCleanAll
m.CleanInput = newCleanInput()
m.CleanOpLoading = false
m.CleanOpErr = nil
return m, nil
case cleanAllMsg:
m.CleanOpLoading = false
if msg.err != nil {
m.CleanOpErr = msg.err
return m, nil
}
server := m.ActiveServer
return m, func() tea.Msg { return pages.ServerActionsPageMsg{ServerName: server} }
case pages.SendPageMsg:
m.Page = pageSend
m.Picker = newPicker(m.LocalDir)
@@ -222,6 +263,9 @@ func (m TUIInterface) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if m.Page == pageSend {
return m.updateSend(msg)
}
if m.Page == pageCleanAll {
return m.updateCleanAll(msg)
}
switch msg.String() {
case "up", "k":
@@ -313,7 +357,7 @@ func (m TUIInterface) updateServerActions(msg tea.KeyPressMsg) (tea.Model, tea.C
case "send":
return m, func() tea.Msg { return pages.SendPageMsg{ServerName: server} }
case "clean":
// TODO: navigate to clean all page
return m, func() tea.Msg { return pages.CleanAllPageMsg{ServerName: server} }
}
case "ctrl+c":
@@ -429,6 +473,36 @@ func (m TUIInterface) updateSend(msg tea.KeyPressMsg) (tea.Model, tea.Cmd) {
return m, nil
}
func (m TUIInterface) updateCleanAll(msg tea.KeyPressMsg) (tea.Model, tea.Cmd) {
if m.CleanOpLoading {
if msg.String() == "ctrl+c" {
m.Quitting = true
return m, tea.Quit
}
return m, nil
}
switch msg.String() {
case "enter":
if m.CleanInput.Value() == "yes" {
m.CleanOpLoading = true
m.CleanOpErr = nil
return m, cleanAllCmd(m.Services, m.ActiveServer)
}
case "ctrl+c":
m.Quitting = true
return m, tea.Quit
case "esc":
server := m.ActiveServer
return m, func() tea.Msg { return pages.ServerActionsPageMsg{ServerName: server} }
}
// route all other keys to the text input
var cmd tea.Cmd
m.CleanInput, cmd = m.CleanInput.Update(msg)
return m, cmd
}
func (m TUIInterface) updateSelectServer(msg tea.KeyPressMsg) (tea.Model, tea.Cmd) {
last := len(m.ServerNames) - 1
switch msg.String() {

View File

@@ -1,6 +1,8 @@
package tui
import (
"fmt"
"filepass/internal/styles"
tea "charm.land/bubbletea/v2"
@@ -34,6 +36,8 @@ func (m TUIInterface) subtitle() string {
return m.ActiveFile
case pageSend:
return "Send File"
case pageCleanAll:
return "Clean All"
default:
return "Secure file transfer"
}
@@ -65,6 +69,8 @@ func (m TUIInterface) View() tea.View {
body = m.viewFileAction()
case pageSend:
body = m.viewSend()
case pageCleanAll:
body = m.viewCleanAll()
default:
body = m.viewMenu()
}
@@ -108,6 +114,10 @@ func (m TUIInterface) View() tea.View {
footerHint("enter", "confirm") +
footerSep() +
footerHint("esc", "back")
case pageCleanAll:
footerStr = footerHint("enter", "confirm") +
footerSep() +
footerHint("esc", "back")
case pageSend:
footerStr = footerHint("↑↓", "navigate") +
footerSep() +
@@ -252,6 +262,30 @@ func (m TUIInterface) viewSend() string {
return lipgloss.JoinVertical(lipgloss.Left, crumb, queryLine, list)
}
func (m TUIInterface) viewCleanAll() string {
fileCount := len(m.StorageFiles)
warning := styles.CleanWarningStyle.Render(
fmt.Sprintf("This will permanently delete all %d file(s) from remote storage.", fileCount),
)
promptLabel := styles.FieldLabelStyle(true).Render("Type \"yes\" to confirm")
input := m.CleanInput.View()
var statusLine string
switch {
case m.CleanOpLoading:
statusLine = styles.StatusWarnStyle.Render(" deleting…")
case m.CleanOpErr != nil:
statusLine = styles.StatusErrStyle.Render("✗ " + m.CleanOpErr.Error())
}
parts := []string{warning, promptLabel, input}
if statusLine != "" {
parts = append(parts, statusLine)
}
return lipgloss.JoinVertical(lipgloss.Left, parts...)
}
func (m TUIInterface) viewSelectServer() string {
if len(m.ServerNames) == 0 {
return styles.StatusWarnStyle.Render("⚠ No servers configured.")