1- import { Application } from '@nativescript/core' ;
2-
1+ import { Application , Http , ImageSource } from '@nativescript/core' ;
2+ import { registerWidgetListener , LinearLayout , ImageView , Image , Button , VStack , List , Text , updateWidget , Root , HStack , ButtonView , Flipper , Chronometer , Clock , Grid , ProgressBar , Stack , Spacer } from '@nativescript/widgets' ;
33// uncomment to test Flutter
44// import { init } from '@nativescript/flutter';
55// init();
@@ -17,4 +17,222 @@ import { Application } from '@nativescript/core';
1717// IonicPortalManager.register('<portal-api-key>');
1818// });
1919
20+ // 1. Countdown timer widget
21+ function countdownWidget ( provider : string , ids : number [ ] ) {
22+ const targetTime = Date . now ( ) + 3600000 ; // 1 hour from now
23+ const root = Root ( ( ) =>
24+ VStack ( ( ) => [
25+ Text ( '⏱️ Countdown' ) . setColor ( '#1a1a2e' ) . setTextSize ( 18 ) ,
26+ Spacer ( 12 ) ,
27+ Chronometer ( {
28+ targetTime : targetTime , // Use targetTime for Unix timestamps
29+ countDown : true ,
30+ started : true ,
31+ } )
32+ . setColor ( '#e74c3c' )
33+ . setTextSize ( 32 ) ,
34+ Spacer ( 8 ) ,
35+ Text ( 'until deadline' ) . setColor ( '#6c757d' ) . setTextSize ( 12 ) ,
36+ ] ) ,
37+ )
38+ . setBackgroundColor ( '#ffffff' )
39+ . setPadding ( 16 ) ;
40+ for ( const id of ids ) updateWidget ( provider , root , id ) ;
41+ }
42+
43+ // 2. Clock widget
44+ function clockWidget ( provider : string , ids : number [ ] ) {
45+ const root = Root ( ( ) => VStack ( ( ) => [ Text ( '🕐 Current Time' ) . setColor ( '#ecf0f1' ) . setTextSize ( 14 ) , Spacer ( 12 ) , Clock ( { color : '#3498db' } ) . setTextSize ( 42 ) , Spacer ( 8 ) , Text ( 'Local timezone' ) . setColor ( '#7f8c8d' ) . setTextSize ( 11 ) ] ) )
46+ . setBackgroundColor ( '#1a1a2e' )
47+ . setPadding ( 16 ) ;
48+ for ( const id of ids ) updateWidget ( provider , root , id ) ;
49+ }
50+
51+ // 3. Progress indicator
52+ function progressWidget ( provider : string , ids : number [ ] ) {
53+ const root = Root ( ( ) => VStack ( ( ) => [ HStack ( ( ) => [ Text ( '⬇️ Downloading' ) . setColor ( '#2c3e50' ) . setTextSize ( 16 ) , Spacer ( ) , Text ( '65%' ) . setColor ( '#27ae60' ) . setTextSize ( 16 ) ] ) , Spacer ( 12 ) , ProgressBar ( { progress : 65 , max : 100 } ) , Spacer ( 8 ) , Text ( 'file_backup.zip • 650 MB / 1 GB' ) . setColor ( '#7f8c8d' ) . setTextSize ( 11 ) ] ) )
54+ . setBackgroundColor ( '#ffffff' )
55+ . setPadding ( 16 ) ;
56+ for ( const id of ids ) updateWidget ( provider , root , id ) ;
57+ }
58+
59+ // 4. List with click handlers
60+ function listWidget ( provider : string , ids : number [ ] ) {
61+ const items = [
62+ { icon : '📥' , name : 'Inbox' , count : 12 } ,
63+ { icon : '⭐' , name : 'Starred' , count : 3 } ,
64+ { icon : '📤' , name : 'Sent' , count : 0 } ,
65+ { icon : '📝' , name : 'Drafts' , count : 2 } ,
66+ { icon : '🗑️' , name : 'Trash' , count : 0 } ,
67+ ] ;
68+ const root = Root ( ( ) =>
69+ VStack ( ( ) => [
70+ Text ( '📧 Mail' ) . setColor ( '#2c3e50' ) . setTextSize ( 18 ) ,
71+ Spacer ( 8 ) ,
72+ List (
73+ items . length ,
74+ ( index ) => HStack ( ( ) => [ Text ( `${ items [ index ] . icon } ${ items [ index ] . name } ` ) . setColor ( '#34495e' ) . setTextSize ( 14 ) , Spacer ( ) , items [ index ] . count > 0 ? Text ( `${ items [ index ] . count } ` ) . setColor ( '#3498db' ) . setTextSize ( 12 ) : Text ( '' ) . setTextSize ( 12 ) ] ) . setMargin ( 4 , 8 , 4 , 8 ) ,
75+ ( ) => Text ( 'No folders' ) . setColor ( '#95a5a6' ) ,
76+ ) ,
77+ ] ) ,
78+ )
79+ . setBackgroundColor ( '#ffffff' )
80+ . setPadding ( 12 ) ;
81+ for ( const id of ids ) updateWidget ( provider , root , id ) ;
82+ }
83+
84+ // 5. Image flipper/slideshow
85+ async function slideshowWidget ( provider : string , ids : number [ ] , loadImages = false ) {
86+ const imageUrls = [ 'https://picsum.photos/seed/1/400/300' , 'https://picsum.photos/seed/2/400/300' , 'https://picsum.photos/seed/3/400/300' , 'https://picsum.photos/seed/4/400/300' ] ;
87+
88+ const images = loadImages ? await Promise . all ( imageUrls . map ( ( url ) => ImageSource . fromUrl ( url ) ) ) : imageUrls ;
89+
90+ const root = Root ( ( ) => VStack ( ( ) => [ Text ( '📷 Gallery' ) . setColor ( '#ffffff' ) . setTextSize ( 16 ) , Spacer ( 8 ) , Flipper ( images as never [ ] , 3000 , ( src ) => Image ( src ) ) , Spacer ( 8 ) , Text ( 'Auto-advances every 3s' ) . setColor ( '#adb5bd' ) . setTextSize ( 11 ) ] ) )
91+ . setBackgroundColor ( '#2c3e50' )
92+ . setPadding ( 12 ) ;
93+
94+ for ( const id of ids ) updateWidget ( provider , root , id ) ;
95+ }
96+
97+ // 6. Grid layout
98+ function gridWidget ( provider : string , ids : number [ ] ) {
99+ const actions = [
100+ { icon : '📞' , label : 'Call' , color : '#3498db' , bg : '#ebf5fb' } ,
101+ { icon : '💬' , label : 'Message' , color : '#9b59b6' , bg : '#f5eef8' } ,
102+ { icon : '📧' , label : 'Email' , color : '#e74c3c' , bg : '#fdedec' } ,
103+ { icon : '📅' , label : 'Calendar' , color : '#27ae60' , bg : '#eafaf1' } ,
104+ { icon : '📷' , label : 'Camera' , color : '#f39c12' , bg : '#fef9e7' } ,
105+ { icon : '🎵' , label : 'Music' , color : '#e91e63' , bg : '#fce4ec' } ,
106+ ] ;
107+
108+ const root = Root ( ( ) =>
109+ VStack ( ( ) => [
110+ HStack ( ( ) => [ Text ( '⚡ Quick Actions' ) . setColor ( '#1a1a2e' ) . setTextSize ( 18 ) , Spacer ( ) , Text ( '6 apps' ) . setColor ( '#95a5a6' ) . setTextSize ( 12 ) ] ) ,
111+ Spacer ( 16 ) ,
112+ Grid ( 3 , 12 , ( ) =>
113+ actions . map ( ( action ) =>
114+ VStack ( ( ) => [
115+ VStack ( ( ) => [ Text ( action . icon ) . setTextSize ( 28 ) , Spacer ( 6 ) , Text ( action . label ) . setColor ( action . color ) . setTextSize ( 11 ) ] )
116+ . setBackgroundColor ( action . bg )
117+ . setPadding ( 12 ) ,
118+ Spacer ( 4 ) ,
119+ ] ) ,
120+ ) ,
121+ ) ,
122+ ] ) ,
123+ )
124+ . setBackgroundColor ( '#ffffff' )
125+ . setPadding ( 16 ) ;
126+ for ( const id of ids ) updateWidget ( provider , root , id ) ;
127+ }
128+
129+ // 7. StackView (swipeable cards)
130+ function stackWidget ( provider : string , ids : number [ ] ) {
131+ const cards = [
132+ { title : 'Meeting Notes' , subtitle : 'Project sync @ 2pm' , color : '#3498db' } ,
133+ { title : 'Shopping List' , subtitle : '5 items remaining' , color : '#e74c3c' } ,
134+ { title : 'Workout Plan' , subtitle : 'Leg day tomorrow' , color : '#27ae60' } ,
135+ ] ;
136+ const root = Root ( ( ) =>
137+ VStack ( ( ) => [
138+ Text ( '📚 Cards' ) . setColor ( '#ffffff' ) . setTextSize ( 16 ) ,
139+ Spacer ( 8 ) ,
140+ Stack ( cards . length , ( index ) =>
141+ VStack ( ( ) => [ Text ( cards [ index ] . title ) . setColor ( '#2c3e50' ) . setTextSize ( 16 ) , Spacer ( 4 ) , Text ( cards [ index ] . subtitle ) . setColor ( '#7f8c8d' ) . setTextSize ( 12 ) ] )
142+ . setBackgroundColor ( '#ffffff' )
143+ . setPadding ( 12 ) ,
144+ ) ,
145+ Spacer ( 8 ) ,
146+ Text ( 'Swipe to browse' ) . setColor ( '#adb5bd' ) . setTextSize ( 11 ) ,
147+ ] ) ,
148+ )
149+ . setBackgroundColor ( '#34495e' )
150+ . setPadding ( 12 ) ;
151+ for ( const id of ids ) updateWidget ( provider , root , id ) ;
152+ }
153+
154+ // 8. Complex combined layout
155+ function dashboardWidget ( provider : string , ids : number [ ] ) {
156+ const tasks = [
157+ { name : 'Review PR #142' , done : true } ,
158+ { name : 'Update documentation' , done : true } ,
159+ { name : 'Fix login bug' , done : false } ,
160+ { name : 'Deploy to staging' , done : false } ,
161+ { name : 'Team standup' , done : false } ,
162+ ] ;
163+ const completed = tasks . filter ( ( t ) => t . done ) . length ;
164+ const progress = Math . round ( ( completed / tasks . length ) * 100 ) ;
165+
166+ const root = Root ( ( ) =>
167+ VStack ( ( ) => [
168+ // Header row
169+ HStack ( ( ) => [ Text ( '📊 Dashboard' ) . setColor ( '#1a1a2e' ) . setTextSize ( 18 ) , Spacer ( ) , Clock ( { color : '#6c757d' } ) . setTextSize ( 14 ) ] ) ,
170+
171+ Spacer ( 12 ) ,
172+
173+ // Progress section
174+ Text ( 'Sprint Progress' ) . setColor ( '#495057' ) . setTextSize ( 12 ) ,
175+ Spacer ( 4 ) ,
176+ HStack ( ( ) => [ ProgressBar ( { progress, max : 100 , flex : true } ) , Spacer ( 8 ) , Text ( `${ progress } %` ) . setColor ( '#27ae60' ) . setTextSize ( 14 ) ] ) ,
177+
178+ Spacer ( 16 ) ,
179+
180+ // Tasks section
181+ HStack ( ( ) => [ Text ( 'Tasks' ) . setColor ( '#495057' ) . setTextSize ( 12 ) , Spacer ( ) , Text ( `${ completed } /${ tasks . length } ` ) . setColor ( '#6c757d' ) . setTextSize ( 11 ) ] ) ,
182+ Spacer ( 4 ) ,
183+ List ( tasks . length , ( i ) =>
184+ Text ( `${ tasks [ i ] . done ? '✓' : '○' } ${ tasks [ i ] . name } ` )
185+ . setColor ( tasks [ i ] . done ? '#27ae60' : '#212529' )
186+ . setTextSize ( 13 ) ,
187+ ) ,
188+ ] ) ,
189+ )
190+ . setBackgroundColor ( '#ffffff' )
191+ . setPadding ( 16 ) ;
192+ for ( const id of ids ) updateWidget ( provider , root , id ) ;
193+ }
194+
195+ registerWidgetListener ( 'org.nativescript.plugindemo.PluginDemoWidgetProvider' , {
196+ onClick ( event ) {
197+ console . log ( 'Widget clicked' , event ) ;
198+ } ,
199+ onUpdate : ( event ) => {
200+ // dashboardWidget(event.provider, event.appWidgetIds);
201+ //countdownWidget(event.provider, event.appWidgetIds);
202+ // clockWidget(event.provider, event.appWidgetIds);
203+ // progressWidget(event.provider, event.appWidgetIds);
204+ // listWidget(event.provider, event.appWidgetIds);
205+ // slideshowWidget(event.provider, event.appWidgetIds);
206+ gridWidget ( event . provider , event . appWidgetIds ) ;
207+ //stackWidget(event.provider, event.appWidgetIds);
208+ /* const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
209+ const list = List(
210+ data.length,
211+ (index) =>
212+ VStack(() =>
213+ HStack(() => {
214+ const img = Image('').setSize(20, 20) as ImageView;
215+ const ret = [img, Text(`Item ${index}`), Button('Click', () => console.log(`Clicked item ${index}`))];
216+ rows.push({ row: ret as never, src: `https://picsum.photos/seed/${data[index]}/300/300` });
217+ return ret;
218+ }),
219+ ),
220+ () => Text('No content'),
221+ ).setBackgroundColor('white');
222+
223+ const root = Root(() => list)
224+ .setBackgroundColor('lightgray')
225+ .setPadding(20);
226+
227+ rootView = root;
228+ for (const id of event.appWidgetIds) {
229+ updateWidget(event.provider, root, id);
230+ }
231+ */
232+ } ,
233+ async onUpdateAsync ( event ) {
234+ // slideshowWidget(event.provider, event.appWidgetIds, true);
235+ } ,
236+ } ) ;
237+
20238Application . run ( { moduleName : 'app-root' } ) ;
0 commit comments