1+ # Adhkar Counter A pp
2+
3+ load "webview.ring"
4+ load "jsonlib.ring"
5+
6+ oWebVi ew = NULL
7+ nCou nt = 0
8+ nCurrentZikrInd ex = 1
9+
10+ aAzk ar = [
11+ ["سُبْحَانَ اللَّهِ" , 33 ],
12+ ["الْحَمْدُ للّهِ" , 33 ],
13+ ["الْلَّهُ أَكْبَرُ" , 34 ],
14+ ["لَا إلَه إلّا اللهُ وَحْدَهُ لَا شَرِيكَ لَهُ، لَهُ الْمُلْكُ وَلَهُ الْحَمْدُ وَهُوَ عَلَى كُلُّ شَيْءِ قَدِيرِ" , 1 ],
15+ ]
16+
17+
18+ func main ()
19+ oWebVi ew = new WebView (1 , NULL )
20+
21+ oWebVi ew {
22+ setTitle ("السبحة" )
23+ setSize (500 , 700 , WEBVIEW_HINT_NO NE )
24+
25+ bind ("getInitialCount" , :handleGetInitialCou nt )
26+ bind ("incrementCounter" , :handleIncrementCount er )
27+ bind ("resetCounter" , :handleResetCount er )
28+
29+ loadSebhaHTML ()
30+
31+ run ()
32+ }
33+
34+ func loadSebhaHTML ()
35+ cHT ML = `
36+ < !DOCTYPE html >
37+ < html dir = "rtl" la ng = "ar" >
38+ < he ad >
39+ < meta charset = "UTF-8" >
40+ < meta name = "viewport" conte nt = "width=device-width, initial-scale=1.0" >
41+ < !-- Font Awesome for ico ns -->
42+ < link rel = "stylesheet" hr ef = "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" >
43+ < sty le >
44+ @ import url ('htt ps ://fonts .googleapis .com /css2 ?family =Tajawal :wg ht @ 400 ;700 &display =swap ');
45+ :ro ot {
46+ --bg -color : #000000 ;
47+ --card -bg : rgba (30 , 30 , 32 , 0.6 );
48+ --border -color : rgba (255 , 255 , 255 , 0.1 );
49+ --text -primary : #f8fa fc ;
50+ --text -secondary : #a1a1 aa ;
51+ --accent -green : #4ade80;
52+ --accent -red : #f87171;
53+ }
54+ bo dy {
55+ font -family : 'Tajaw al ', sans -serif ;
56+ displ ay : fl ex ;
57+ flex -direction : colu mn ;
58+ justify -content : cent er ;
59+ align -items : cent er ;
60+ heig ht : 100vh;
61+ marg in : 0 ;
62+ background -color : var (--bg -color );
63+ user -select : no ne ;
64+ positi on : relati ve ;
65+ overfl ow : hidd en ;
66+ col or : var (--text -primary );
67+ }
68+ .background -container {
69+ positi on : fix ed ; t op : 0 ; le ft : 0 ; wid th : 100 %; heig ht : 100 %;
70+ z -index : -1 ; overfl ow : hidd en ;
71+ }
72+ .auro ra {
73+ positi on : relati ve ; wid th : 100 %; heig ht : 100 %;
74+ filt er : blur (150px); opaci ty : 0.5 ;
75+ }
76+ .aurora -shape1 {
77+ positi on : absolu te ; wid th : 50vw; heig ht : 50vh;
78+ backgrou nd : radial -gradient(circ le , #22d3ee, transpare nt 60 %);
79+ t op : 5 %; le ft : 5 %;
80+ }
81+ .aurora -shape2 {
82+ positi on : absolu te ; wid th : 40vw; heig ht : 40vh;
83+ backgrou nd : radial -gradient(circ le , #c084 fc , transpare nt 60 %);
84+ bott om : 10 %; rig ht : 10 %;
85+ }
86+
87+ .sebha -container {
88+ text -align : cent er ;
89+ background -color : var (--card -bg );
90+ paddi ng : 2em;
91+ border -radius : 15px;
92+ box -shadow : 0 8px 30px rgba (0 ,0 ,0 ,0.3 );
93+ backdrop -filter : blur (12px);
94+ -webkit -backdrop -filt er : blur (12px);
95+ bord er : 1px solid var(--border -color );
96+ positi on : relati ve ; z -index : 1 ;
97+ wid th : 90 %;
98+ max -width : 400px;
99+ }
100+ h1 {
101+ font -size : 1 .8em;
102+ col or : var (--text -primary );
103+ margin -bottom : 1em;
104+ }
105+ .counter -display {
106+ background -color : rgba (255 , 255 , 255 , 0.05 );
107+ wid th : 100 %;
108+ heig ht : 120px;
109+ line -height : 120px;
110+ border -radius : 15px;
111+ box -shadow : ins et 0 2px 5px rgba (0 ,0 ,0 ,0.2 );
112+ font -size : 4em;
113+ font -weight : 700 ;
114+ col or : var (--accent -green );
115+ margin -bottom : 30px;
116+ bord er : 1px solid var(--border -color );
117+ }
118+ .tasbih -button {
119+ wid th : 180px;
120+ heig ht : 180px;
121+ border -radius : 50 %;
122+ bord er : no ne ;
123+ background -color : var (--accent -green );
124+ col or : whi te ;
125+ font -size : 2em;
126+ font -weight : 700 ;
127+ curs or : point er ;
128+ box -shadow : 0 5px 15px rgba (0 , 128 , 0 , 0.4 );
129+ transiti on : transfo rm 0 .1s, box -shadow 0 .1s, background -color 0 .2s;
130+ displ ay : fl ex ;
131+ align -items : cent er ;
132+ justify -content : cent er ;
133+ marg in : 0 au to 30px au to ;
134+ }
135+ .tasbih -button :acti ve {
136+ transfo rm : scale (0.95 );
137+ box -shadow : 0 2px 8px rgba (0 , 128 , 0 , 0.5 );
138+ }
139+ .tasbih -button :hov er {
140+ background -color : #00a884;
141+ }
142+ .reset -button {
143+ backgrou nd : no ne ;
144+ bord er : 1px solid var(--accent -red );
145+ col or : var (--accent -red );
146+ paddi ng : 0 .8em 2em;
147+ border -radius : 10px;
148+ curs or : point er ;
149+ font -size : 1 .1em;
150+ font -weight : 500 ;
151+ transiti on : a ll 0 .2s ea se ;
152+ }
153+ .reset -button :hov er {
154+ background -color : var (--accent -red );
155+ col or : whi te ;
156+ box -shadow : 0 4px 10px rgba (0 ,0 ,0 ,0.2 );
157+ }
158+ @ media (max -width : 480px) {
159+ .sebha -container {
160+ paddi ng : 1 .5em;
161+ }
162+ .counter -display {
163+ font -size : 3em;
164+ heig ht : 100px;
165+ line -height : 100px;
166+ }
167+ .tasbih -button {
168+ wid th : 150px;
169+ heig ht : 150px;
170+ font -size : 1 .8em;
171+ }
172+ .reset -button {
173+ font -size : 1em;
174+ paddi ng : 0 .7em 1 .5em;
175+ }
176+ }
177+ < /sty le >
178+ < /he ad >
179+ < bo dy >
180+ < div class = "background-container" >
181+ < div class = "aurora" >< div class = "aurora-shape1" >< /d iv >< div class = "aurora-shape2" >< /d iv >< /d iv >
182+ < /d iv >
183+ < div class = "sebha-container" >
184+ < h1>< i class = "fa-solid fa-mosque" >< /i> السبحة< /h1>
185+ < div id = "zikr-text" sty le = "font-size: 1.5em; margin-bottom: 15px; color: var(--text-primary);" >< /d iv >
186+ < div id = "counter" class = "counter-display" > 0 < /d iv >
187+ < button id = "tasbih-btn" class = "tasbih-button" > سبّح< /butt on >
188+ < button id = "reset-btn" class = "reset-button" > تصفير< /butt on >
189+ < /d iv >
190+
191+ < scri pt >
192+ function updateCounter(cou nt , zikrTe xt ) {
193+ document .getElementById('count er ').textConte nt = cou nt ;
194+ document .getElementById('zikr -text ').textConte nt = zikrTe xt ;
195+ }
196+
197+ async function increment () {
198+ // We don 't need to wait for a response if we update the UI from Ri ng
199+ window .incrementCounter();
200+ }
201+
202+ async function reset () {
203+ if (confirm ('هل أنت متأكد أنك تريد تصفير العداد؟')) {
204+ window .resetCounter();
205+ }
206+ }
207+
208+ window .onload = async () = > {
209+ try {
210+ const initialData = await window .getInitialCount ();
211+ updateCounter (initialData .count , initialData .zikr );
212+ } catch (e) { console .error('Error getting initial count :', e); }
213+
214+ document .getElementById('tasbih -btn ').addEventListener ('cli ck ', increme nt );
215+ document .getElementById('reset -btn ').addEventListener ('cli ck ', res et );
216+ };
217+ < /scri pt >
218+ < /bo dy >
219+ < /ht ml >
220+ `
221+ oWebView .setHtml(cHT ML )
222+
223+
224+ # Handles requests from JavaScript to get the initial counter value and current Zikr te xt .
225+ func handleGetInitialCount (id, r eq )
226+ see "Ring: JavaScript requests initial counter value and Zikr text." + nl
227+ aRespon se = [
228+ :cou nt = nCou nt ,
229+ :zi kr = aAzkar [nCurrentZikrIndex ][1 ]
230+ ]
231+ oWebView .wreturn(id, WEBVIEW_ERROR_ OK , list2json (aRespon se ))
232+
233+ # Handles requests from JavaScript to increment the count er .
234+ func handleIncrementCounter (id, r eq )
235+ nCou nt ++
236+ see "Ring: Counter incremented to: " + nCou nt + nl
237+
238+ if nCou nt >= aAzkar [nCurrentZikrIndex ][2 ]
239+ nCurrentZikrInd ex ++
240+ nCou nt = 0
241+ if nCurrentZikrInd ex > len (aAzk ar )
242+ nCurrentZikrInd ex = 1
243+ ok
244+ see "Ring: Switched to next Zikr: " + aAzkar [nCurrentZikrIndex ][1 ] + nl
245+ ok
246+
247+ updateUICounter ()
248+ oWebView .wreturn(id, WEBVIEW_ERROR_ OK , '{}')
249+
250+ # Handles requests from JavaScript to reset the count er .
251+ func handleResetCounter (id, r eq )
252+ nCou nt = 0
253+ see "Ring: Counter has been reset." + nl
254+ updateUICounter ()
255+ oWebView .wreturn(id, WEBVIEW_ERROR_ OK , '{}')
256+
257+ # Updates the counter and Zikr text displayed in the WebView UI.
258+ func updateUICounter ()
259+ cJsCo de = "updateCounter(" + nCou nt + ", '" + aAzkar [nCurrentZikrIndex ][1 ] + "');"
260+ oWebView .evalJS(cJsCo de )
0 commit comments