From fce36fd1972eea0145b0b656c44ca07bb7a47a85 Mon Sep 17 00:00:00 2001 From: Sabyasachi Patra Date: Tue, 29 Aug 2023 14:31:41 +0530 Subject: [PATCH] feat: search passwords, #22 (#25) * feat: search passwords, #22 * minor text fixes * fix:staticcheck * chore: update go version in actions * fix: security * chore: update go version in actions * fix: dfs import --- .github/workflows/build.yml | 2 +- .github/workflows/release.yml | 4 +-- .github/workflows/static-code-analysis.yml | 2 +- .github/workflows/test.yml | 2 +- go.mod | 6 ++-- go.sum | 18 ++++++++---- internal/screens/loginView.go | 9 ++++-- internal/screens/mainView.go | 2 +- internal/screens/notesView.go | 2 +- internal/screens/passwordCreate.go | 4 +-- internal/screens/passwordsView.go | 34 ++++++++++++++++++---- 11 files changed, 60 insertions(+), 25 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ca8b4be..fd721d1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,7 +17,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v2 with: - go-version: 1.18 + go-version: 1.21 - name: Install fyne-cross compiler run: go install github.com/fyne-io/fyne-cross@latest - name: Install fyne diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ab4ad4f..6f1aa34 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,7 +25,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v2 with: - go-version: 1.18 + go-version: 1.21 - name: Install fyne-cross compiler run: go install github.com/fyne-io/fyne-cross@latest - name: Install fyne @@ -59,7 +59,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v2 with: - go-version: 1.18 + go-version: 1.21 - name: Install fyne-cross compiler run: go install github.com/fyne-io/fyne-cross@latest - name: Install fyne diff --git a/.github/workflows/static-code-analysis.yml b/.github/workflows/static-code-analysis.yml index 6311003..3ded7ec 100644 --- a/.github/workflows/static-code-analysis.yml +++ b/.github/workflows/static-code-analysis.yml @@ -8,7 +8,7 @@ jobs: - name: Setup Go environment uses: actions/setup-go@v2 with: - go-version: 1.18 + go-version: 1.21 - name: Setup dependencies run: sudo apt-get update && sudo apt-get install gcc libgl1-mesa-dev libegl1-mesa-dev libgles2-mesa-dev libx11-dev xorg-dev - name: Install staticcheck diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index aa119d0..636c621 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,7 +15,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v2 with: - go-version: 1.18 + go-version: 1.21 - name: Setup dependencies run: sudo apt-get update && sudo apt-get install gcc libgl1-mesa-dev libegl1-mesa-dev libgles2-mesa-dev libx11-dev xorg-dev - name: Test diff --git a/go.mod b/go.mod index 68fa51a..6001411 100644 --- a/go.mod +++ b/go.mod @@ -5,8 +5,8 @@ go 1.20 require ( fyne.io/fyne/v2 v2.3.5 github.com/fairdatasociety/fairOS-dfs v0.9.6 - github.com/google/uuid v1.3.0 - github.com/sethvargo/go-password v0.2.0 + github.com/google/uuid v1.3.1 + github.com/sethvargo/go-password v0.2.1-0.20221026161242-a12c199499e5 github.com/sirupsen/logrus v1.9.3 ) @@ -84,7 +84,7 @@ require ( go.uber.org/atomic v1.10.0 // indirect golang.org/x/crypto v0.12.0 // indirect golang.org/x/exp v0.0.0-20230810033253-352e893a4cad // indirect - golang.org/x/image v0.3.0 // indirect + golang.org/x/image v0.11.0 // indirect golang.org/x/mobile v0.0.0-20211207041440-4e6c2922fdee // indirect golang.org/x/net v0.10.0 // indirect golang.org/x/sys v0.11.0 // indirect diff --git a/go.sum b/go.sum index 9509321..c349d9b 100644 --- a/go.sum +++ b/go.sum @@ -321,8 +321,8 @@ github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLe github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.5/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -566,8 +566,8 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sethvargo/go-password v0.2.0 h1:BTDl4CC/gjf/axHMaDQtw507ogrXLci6XRiLc7i/UHI= -github.com/sethvargo/go-password v0.2.0/go.mod h1:Ym4Mr9JXLBycr02MFuVQ/0JHidNetSgbzutTr3zsYXE= +github.com/sethvargo/go-password v0.2.1-0.20221026161242-a12c199499e5 h1:XyW9tE15i0LxhDqJgjGSfCcbk4pjNefJtk2kKb6Dqh8= +github.com/sethvargo/go-password v0.2.1-0.20221026161242-a12c199499e5/go.mod h1:Ym4Mr9JXLBycr02MFuVQ/0JHidNetSgbzutTr3zsYXE= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= @@ -711,8 +711,9 @@ golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86h golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= -golang.org/x/image v0.3.0 h1:HTDXbdK9bjfSWkPzDJIw89W8CAtfFGduujWs33NLLsg= golang.org/x/image v0.3.0/go.mod h1:fXd9211C/0VTlYuAcOhW8dY/RtEJqODXOWBDpmYBf+A= +golang.org/x/image v0.11.0 h1:ds2RoQvBvYTiJkwpSFDwCcDFNX7DqjL2WsUgTNk0Ooo= +golang.org/x/image v0.11.0/go.mod h1:bglhjqbqVuEb9e9+eNR45Jfu7D+T4Qan+NhQk8Ck2P8= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -739,6 +740,7 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -786,6 +788,7 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211118161319-6a13c67c3ce4/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -812,6 +815,7 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -880,10 +884,12 @@ golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -894,6 +900,7 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -959,6 +966,7 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.8-0.20211022200916-316ba0b74098/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/screens/loginView.go b/internal/screens/loginView.go index 7386641..2e5bdab 100644 --- a/internal/screens/loginView.go +++ b/internal/screens/loginView.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" "os" "path/filepath" @@ -41,7 +40,7 @@ type userRequest struct { func (i *index) initLoginView() fyne.CanvasObject { // load config - data, err := ioutil.ReadFile(filepath.Join(i.app.Storage().RootURI().Path(), config)) + data, err := os.ReadFile(filepath.Join(i.app.Storage().RootURI().Path(), config)) if err != nil { if os.IsNotExist(err) { return i.initConfigView(false) @@ -88,6 +87,10 @@ func (i *index) initLoginView() fyne.CanvasObject { usernameInput.SetPlaceHolder("username") passwordInput := widget.NewPasswordEntry() passwordInput.SetPlaceHolder("password") + + usernameInput.SetText("check") + passwordInput.SetText("passwordpassword") + loginBtn := widget.NewButton("Login", func() { i.progress = dialog.NewProgressInfinite("", "Login is progress", i) //lint:ignore SA1019 fyne-io/fyne/issues/2782 i.progress.Show() @@ -356,7 +359,7 @@ func (i *index) initConfigView(allowBack bool) fyne.CanvasObject { dialog.NewError(fmt.Errorf("config write failed : %s", err.Error()), i.Window).Show() return } - err = ioutil.WriteFile(filepath.Join(i.app.Storage().RootURI().Path(), config), configBytes, 0700) + err = os.WriteFile(filepath.Join(i.app.Storage().RootURI().Path(), config), configBytes, 0700) if err != nil { dialog.NewError(fmt.Errorf("config write failed : %s", err.Error()), i.Window).Show() return diff --git a/internal/screens/mainView.go b/internal/screens/mainView.go index f58de1e..0e64125 100644 --- a/internal/screens/mainView.go +++ b/internal/screens/mainView.go @@ -103,7 +103,7 @@ func (main *mainView) initMainView() { list.OnSelected = func(id widget.ListItemID) { switch id { case 0: - passwordsView := newListView(main, false) + passwordsView := newListView(main, false, "") main.setContent(passwordsView.view) case 1: notesView := newNotesListView(main, false) diff --git a/internal/screens/notesView.go b/internal/screens/notesView.go index cafc0fa..eb19895 100644 --- a/internal/screens/notesView.go +++ b/internal/screens/notesView.go @@ -25,7 +25,7 @@ func newNotesListView(mainView *mainView, forceReload bool) *notesListView { if cachedNotes == nil { forceReload = true } - if cachedNotes == nil { + if forceReload { items := []*note{} list, err := mainView.index.dfsAPI.DocFind(mainView.index.sessionID, utils.PodName, utils.NotesTable, "id>0", 100) if err == nil { diff --git a/internal/screens/passwordCreate.go b/internal/screens/passwordCreate.go index 03334fa..76c7c81 100644 --- a/internal/screens/passwordCreate.go +++ b/internal/screens/passwordCreate.go @@ -123,7 +123,7 @@ func (main *mainView) makeAddPasswordView(i *password, editable bool) fyne.Canva ) cancelBtn := widget.NewButtonWithIcon("Cancel", theme.CancelIcon(), func() { - passwordsView := newListView(main, false) + passwordsView := newListView(main, false, "") main.setContent(passwordsView.view) }) @@ -238,7 +238,7 @@ func (main *mainView) makeAddPasswordView(i *password, editable bool) fyne.Canva fmt.Println("failed to save password") return } - passwordsView := newListView(main, true) + passwordsView := newListView(main, true, "") main.setContent(passwordsView.view) }) saveBtn.Importance = widget.HighImportance diff --git a/internal/screens/passwordsView.go b/internal/screens/passwordsView.go index 927be0e..16ad453 100644 --- a/internal/screens/passwordsView.go +++ b/internal/screens/passwordsView.go @@ -4,7 +4,12 @@ import ( "encoding/json" "fmt" + "fyne.io/fyne/v2/layout" + + "fyne.io/fyne/v2/theme" + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/dialog" "fyne.io/fyne/v2/widget" "github.com/fairdatasociety/fairpass/internal/utils" @@ -13,22 +18,26 @@ import ( type listView struct { widget.BaseWidget - view *widget.Table + view fyne.CanvasObject items []*password mainView *mainView } var ( cachedPasswords []*password + searchTerm string ) -func newListView(mainView *mainView, forceUpdate bool) *listView { +func newListView(mainView *mainView, forceUpdate bool, expr string) *listView { if cachedPasswords == nil { forceUpdate = true } if forceUpdate { items := []*password{} - list, err := mainView.index.dfsAPI.DocFind(mainView.index.sessionID, utils.PodName, utils.PasswordsTable, "id>0", 100) + if expr == "" { + expr = "domain=>" + } + list, err := mainView.index.dfsAPI.DocFind(mainView.index.sessionID, utils.PodName, utils.PasswordsTable, expr, 100) if err == nil { for _, v := range list { r := &password{} @@ -132,7 +141,7 @@ func newListView(mainView *mainView, forceUpdate bool) *listView { fmt.Println("failed to delete password ", err) return } - passwordsView := newListView(mainView, true) + passwordsView := newListView(mainView, true, "") mainView.setContent(passwordsView.view) return } @@ -142,11 +151,26 @@ func newListView(mainView *mainView, forceUpdate bool) *listView { } } + searchEntry := widget.NewEntry() + searchEntry.SetPlaceHolder("Search...") + searchEntry.OnChanged = func(s string) { + searchTerm = s + } + searchEntry.SetText(searchTerm) + searchButton := widget.NewButtonWithIcon("", theme.SearchIcon(), func() { + expr = "" + if searchTerm != "" { + expr = "domain=>" + searchTerm + } + newListView(mainView, true, expr) + }) + topContent := container.NewPadded(searchEntry, container.New(layout.NewHBoxLayout(), layout.NewSpacer(), searchButton)) + return &listView{ BaseWidget: widget.BaseWidget{}, items: cachedPasswords, mainView: mainView, - view: table, + view: container.NewBorder(topContent, nil, nil, nil, table), } }