A music player that connects to your cloud/distributed storage.
1module UI.Alfred.State exposing (..)
2
3import Alfred exposing (Alfred)
4import Browser.Dom as Dom
5import Keyboard
6import Process
7import Return exposing (return)
8import Return.Ext as Return
9import Task
10import UI.Types as UI exposing (Manager)
11
12
13
14-- 📣
15
16
17assign : Alfred UI.Msg -> Manager
18assign instance model =
19 let
20 pressedKeys =
21 List.filter
22 (\k ->
23 case k of
24 Keyboard.Meta ->
25 True
26
27 Keyboard.Control ->
28 True
29
30 _ ->
31 False
32 )
33 model.pressedKeys
34 in
35 250
36 |> Process.sleep
37 |> Task.andThen (\_ -> Dom.focus "diffuse__alfred")
38 |> Task.andThen (\_ -> Dom.setViewportOf "alfred__results" 0 0)
39 |> Task.attempt (\_ -> UI.Bypass)
40 -- The "K" key seems to stick when using CMD + K,
41 -- aka. Meta key + K, to show the command palette.
42 -- https://github.com/ohanhi/keyboard/issues/14
43 |> return { model | alfred = Just instance, pressedKeys = pressedKeys }
44
45
46gotInput : String -> Manager
47gotInput searchTerm model =
48 model.alfred
49 |> Maybe.map (determineResults searchTerm)
50 |> (\a -> Return.singleton { model | alfred = a })
51
52
53runAction : Int -> Manager
54runAction index model =
55 case model.alfred of
56 Just instance ->
57 { result = Alfred.getAt index instance
58 , searchTerm = instance.searchTerm
59 }
60 |> instance.action
61 |> List.map Return.task
62 |> Cmd.batch
63 |> return { model | alfred = Nothing }
64
65 Nothing ->
66 Return.singleton { model | alfred = Nothing }
67
68
69runSelectedAction : Manager
70runSelectedAction model =
71 case model.alfred of
72 Just instance ->
73 runAction instance.focus model
74
75 Nothing ->
76 Return.singleton model
77
78
79scrollToFocus : Manager
80scrollToFocus model =
81 let
82 task =
83 Task.map3
84 (\innerE outerE outerV ->
85 outerV.viewport.y + innerE.element.y - outerE.element.y - 9
86 )
87 (Dom.getElement "alfred__results__focus")
88 (Dom.getElement "alfred__results")
89 (Dom.getViewportOf "alfred__results")
90 in
91 task
92 |> Task.andThen (\a -> Dom.setViewportOf "alfred__results" 0 a)
93 |> Task.attempt (\_ -> UI.Bypass)
94 |> return model
95
96
97selectNext : Manager
98selectNext model =
99 case model.alfred of
100 Just instance ->
101 let
102 total =
103 Alfred.length instance
104 in
105 instance
106 |> (\i -> { i | focus = min (i.focus + 1) (total - 1) })
107 |> (\i -> { model | alfred = Just i })
108 |> scrollToFocus
109
110 Nothing ->
111 Return.singleton model
112
113
114selectPrevious : Manager
115selectPrevious model =
116 case model.alfred of
117 Just instance ->
118 instance
119 |> (\i -> { i | focus = max (i.focus - 1) 0 })
120 |> (\i -> { model | alfred = Just i })
121 |> scrollToFocus
122
123 Nothing ->
124 Return.singleton model
125
126
127
128-- ⚗️
129
130
131determineResults : String -> Alfred UI.Msg -> Alfred UI.Msg
132determineResults searchTerm alfred =
133 let
134 lowerSearchTerm =
135 searchTerm
136 |> String.toLower
137 |> String.trim
138 in
139 if String.length lowerSearchTerm > 0 then
140 { alfred
141 | focus = 0
142 , searchTerm =
143 Just searchTerm
144 , results =
145 List.map
146 (\group ->
147 group.items
148 |> List.filter
149 (.title >> String.toLower >> String.contains lowerSearchTerm)
150 |> (\items ->
151 { group | items = items }
152 )
153 )
154 alfred.index
155 }
156
157 else
158 { alfred
159 | focus = 0
160 , searchTerm = Nothing
161 , results = alfred.index
162 }