nn-widgets 0.1.15 → 0.1.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"withAndroidWidget.d.ts","sourceRoot":"","sources":["../src/withAndroidWidget.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAuB,MAAM,sBAAsB,CAAC;AAGzE,OAAO,KAAK,EACV,oBAAoB,EAGrB,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"withAndroidWidget.d.ts","sourceRoot":"","sources":["../src/withAndroidWidget.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAuB,MAAM,sBAAsB,CAAC;AAGzE,OAAO,KAAK,EACV,oBAAoB,EAGrB,MAAM,SAAS,CAAC;AAo8BjB,eAAO,MAAM,iBAAiB,EAAE,YAAY,CAAC,oBAAoB,CAmPhE,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
|
|
@@ -286,6 +286,264 @@ class ${w.name}Provider : AppWidgetProvider() {
|
|
|
286
286
|
}
|
|
287
287
|
}
|
|
288
288
|
}
|
|
289
|
+
`;
|
|
290
|
+
}
|
|
291
|
+
// ── Flex-grid type provider ──
|
|
292
|
+
if (w.type === "flex-grid") {
|
|
293
|
+
const bgColor = w.style?.backgroundColor || "#FFFFFF";
|
|
294
|
+
const titleColor = w.style?.titleColor
|
|
295
|
+
? `android.graphics.Color.parseColor("${w.style.titleColor}")`
|
|
296
|
+
: "android.graphics.Color.BLACK";
|
|
297
|
+
const subtitleColor = w.style?.subtitleColor
|
|
298
|
+
? `android.graphics.Color.parseColor("${w.style.subtitleColor}")`
|
|
299
|
+
: "android.graphics.Color.GRAY";
|
|
300
|
+
const accentColor = w.style?.accentColor
|
|
301
|
+
? `android.graphics.Color.parseColor("${w.style.accentColor}")`
|
|
302
|
+
: 'android.graphics.Color.parseColor("#6200EE")';
|
|
303
|
+
return `package ${packageName}.widget
|
|
304
|
+
|
|
305
|
+
import android.app.PendingIntent
|
|
306
|
+
import android.appwidget.AppWidgetManager
|
|
307
|
+
import android.appwidget.AppWidgetProvider
|
|
308
|
+
import android.content.Context
|
|
309
|
+
import android.content.Intent
|
|
310
|
+
import android.view.View
|
|
311
|
+
import android.widget.RemoteViews
|
|
312
|
+
import ${packageName}.MainActivity
|
|
313
|
+
import ${packageName}.R
|
|
314
|
+
import org.json.JSONArray
|
|
315
|
+
import org.json.JSONObject
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* ${w.name} - Flex Grid Widget Provider
|
|
319
|
+
* Auto-generated by nn-widgets
|
|
320
|
+
*/
|
|
321
|
+
class ${w.name}Provider : AppWidgetProvider() {
|
|
322
|
+
|
|
323
|
+
companion object {
|
|
324
|
+
const val PREFS_NAME = "nn_widgets_data"
|
|
325
|
+
const val MAX_ROWS = 4
|
|
326
|
+
const val MAX_COLS = 4
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
override fun onUpdate(
|
|
330
|
+
context: Context,
|
|
331
|
+
appWidgetManager: AppWidgetManager,
|
|
332
|
+
appWidgetIds: IntArray
|
|
333
|
+
) {
|
|
334
|
+
for (appWidgetId in appWidgetIds) {
|
|
335
|
+
updateAppWidget(context, appWidgetManager, appWidgetId)
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
override fun onEnabled(context: Context) {}
|
|
340
|
+
override fun onDisabled(context: Context) {}
|
|
341
|
+
|
|
342
|
+
override fun onReceive(context: Context, intent: Intent) {
|
|
343
|
+
super.onReceive(context, intent)
|
|
344
|
+
if (intent.action == "\${context.packageName}.WIDGET_UPDATE_${w.name.toUpperCase()}") {
|
|
345
|
+
val appWidgetManager = AppWidgetManager.getInstance(context)
|
|
346
|
+
val thisWidget = android.content.ComponentName(context, ${w.name}Provider::class.java)
|
|
347
|
+
val appWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget)
|
|
348
|
+
onUpdate(context, appWidgetManager, appWidgetIds)
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
private fun updateAppWidget(
|
|
353
|
+
context: Context,
|
|
354
|
+
appWidgetManager: AppWidgetManager,
|
|
355
|
+
appWidgetId: Int
|
|
356
|
+
) {
|
|
357
|
+
val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
|
|
358
|
+
val views = RemoteViews(context.packageName, R.layout.${w.name.toLowerCase()}_layout)
|
|
359
|
+
|
|
360
|
+
// Read items and layout JSON (same API as iOS)
|
|
361
|
+
val itemsJson = prefs.getString("widget_${w.name}_items", null)
|
|
362
|
+
val layoutJson = prefs.getString("widget_${w.name}_layout", null)
|
|
363
|
+
val title = prefs.getString("widget_${w.name}_title", "${w.fallbackTitle}") ?: "${w.fallbackTitle}"
|
|
364
|
+
val subtitle = prefs.getString("widget_${w.name}_subtitle", "${w.fallbackSubtitle}") ?: "${w.fallbackSubtitle}"
|
|
365
|
+
|
|
366
|
+
if (itemsJson != null && layoutJson != null) {
|
|
367
|
+
try {
|
|
368
|
+
val items = JSONArray(itemsJson)
|
|
369
|
+
val layoutObj = JSONObject(layoutJson)
|
|
370
|
+
// Get layout for systemSmall (default) - same as iOS
|
|
371
|
+
val layout = layoutObj.optJSONArray("systemSmall") ?: JSONArray("[[1]]")
|
|
372
|
+
|
|
373
|
+
// Hide fallback, show grid
|
|
374
|
+
views.setViewVisibility(R.id.widget_fallback, View.GONE)
|
|
375
|
+
views.setViewVisibility(R.id.widget_grid_container, View.VISIBLE)
|
|
376
|
+
|
|
377
|
+
// Clear existing rows
|
|
378
|
+
views.removeAllViews(R.id.widget_grid_container)
|
|
379
|
+
|
|
380
|
+
var itemIndex = 0
|
|
381
|
+
val rowCount = minOf(layout.length(), MAX_ROWS)
|
|
382
|
+
|
|
383
|
+
for (rowIdx in 0 until rowCount) {
|
|
384
|
+
val rowRatios = layout.optJSONArray(rowIdx) ?: continue
|
|
385
|
+
val colCount = minOf(rowRatios.length(), MAX_COLS)
|
|
386
|
+
|
|
387
|
+
// Create row container
|
|
388
|
+
val rowView = RemoteViews(context.packageName, R.layout.${w.name.toLowerCase()}_row)
|
|
389
|
+
|
|
390
|
+
for (colIdx in 0 until colCount) {
|
|
391
|
+
val ratio = rowRatios.optDouble(colIdx, 1.0)
|
|
392
|
+
val isListStyle = ratio >= 1.0
|
|
393
|
+
|
|
394
|
+
if (itemIndex < items.length()) {
|
|
395
|
+
val item = items.getJSONObject(itemIndex)
|
|
396
|
+
val cellView = if (isListStyle) {
|
|
397
|
+
createListStyleCell(context, item, itemIndex)
|
|
398
|
+
} else {
|
|
399
|
+
createCardStyleCell(context, item, itemIndex)
|
|
400
|
+
}
|
|
401
|
+
rowView.addView(R.id.row_container, cellView)
|
|
402
|
+
}
|
|
403
|
+
itemIndex++
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
views.addView(R.id.widget_grid_container, rowView)
|
|
407
|
+
}
|
|
408
|
+
} catch (e: Exception) {
|
|
409
|
+
android.util.Log.e("${w.name}Provider", "Error parsing widget data", e)
|
|
410
|
+
showFallback(views, title, subtitle)
|
|
411
|
+
}
|
|
412
|
+
} else {
|
|
413
|
+
showFallback(views, title, subtitle)
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// Widget-level click
|
|
417
|
+
${intentCode}
|
|
418
|
+
val pendingIntent = PendingIntent.getActivity(
|
|
419
|
+
context, 100, intent,
|
|
420
|
+
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
|
421
|
+
)
|
|
422
|
+
views.setOnClickPendingIntent(R.id.widget_container, pendingIntent)
|
|
423
|
+
|
|
424
|
+
appWidgetManager.updateAppWidget(appWidgetId, views)
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
private fun createListStyleCell(context: Context, item: JSONObject, index: Int): RemoteViews {
|
|
428
|
+
val cellView = RemoteViews(context.packageName, R.layout.${w.name.toLowerCase()}_cell_list)
|
|
429
|
+
|
|
430
|
+
// Parse title
|
|
431
|
+
val itemTitle = parseTextValue(item, "title")
|
|
432
|
+
cellView.setTextViewText(R.id.cell_title, itemTitle)
|
|
433
|
+
cellView.setTextColor(R.id.cell_title, ${titleColor})
|
|
434
|
+
|
|
435
|
+
// Parse description
|
|
436
|
+
val itemDesc = parseTextValue(item, "description")
|
|
437
|
+
if (itemDesc.isNotEmpty()) {
|
|
438
|
+
cellView.setTextViewText(R.id.cell_description, itemDesc)
|
|
439
|
+
cellView.setTextColor(R.id.cell_description, ${subtitleColor})
|
|
440
|
+
cellView.setViewVisibility(R.id.cell_description, View.VISIBLE)
|
|
441
|
+
} else {
|
|
442
|
+
cellView.setViewVisibility(R.id.cell_description, View.GONE)
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// Parse icon
|
|
446
|
+
setupIcon(context, cellView, item, R.id.cell_icon)
|
|
447
|
+
|
|
448
|
+
// Deep link
|
|
449
|
+
setupDeepLink(context, cellView, item, index, R.id.cell_container)
|
|
450
|
+
|
|
451
|
+
return cellView
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
private fun createCardStyleCell(context: Context, item: JSONObject, index: Int): RemoteViews {
|
|
455
|
+
val cellView = RemoteViews(context.packageName, R.layout.${w.name.toLowerCase()}_cell_card)
|
|
456
|
+
|
|
457
|
+
// Parse title (smaller for card style)
|
|
458
|
+
val itemTitle = parseTextValue(item, "title")
|
|
459
|
+
cellView.setTextViewText(R.id.cell_title, itemTitle)
|
|
460
|
+
cellView.setTextColor(R.id.cell_title, ${titleColor})
|
|
461
|
+
|
|
462
|
+
// Parse icon (larger for card style)
|
|
463
|
+
setupIcon(context, cellView, item, R.id.cell_icon)
|
|
464
|
+
|
|
465
|
+
// Deep link
|
|
466
|
+
setupDeepLink(context, cellView, item, index, R.id.cell_container)
|
|
467
|
+
|
|
468
|
+
return cellView
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
private fun setupIcon(context: Context, views: RemoteViews, item: JSONObject, iconViewId: Int) {
|
|
472
|
+
val iconName = parseIconName(item)
|
|
473
|
+
if (iconName.isNotEmpty()) {
|
|
474
|
+
// Try to load from drawable resources
|
|
475
|
+
val resId = context.resources.getIdentifier(
|
|
476
|
+
iconName.replace("-", "_").lowercase(),
|
|
477
|
+
"drawable",
|
|
478
|
+
context.packageName
|
|
479
|
+
)
|
|
480
|
+
if (resId != 0) {
|
|
481
|
+
views.setImageViewResource(iconViewId, resId)
|
|
482
|
+
views.setViewVisibility(iconViewId, View.VISIBLE)
|
|
483
|
+
} else {
|
|
484
|
+
// Fallback to a default icon or hide
|
|
485
|
+
views.setViewVisibility(iconViewId, View.GONE)
|
|
486
|
+
}
|
|
487
|
+
} else {
|
|
488
|
+
views.setViewVisibility(iconViewId, View.GONE)
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
private fun setupDeepLink(context: Context, views: RemoteViews, item: JSONObject, index: Int, containerId: Int) {
|
|
493
|
+
val deepLink = item.optString("deepLink", "")
|
|
494
|
+
if (deepLink.isNotEmpty()) {
|
|
495
|
+
val itemIntent = Intent(Intent.ACTION_VIEW, android.net.Uri.parse(deepLink)).apply {
|
|
496
|
+
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
|
|
497
|
+
}
|
|
498
|
+
val pendingIntent = PendingIntent.getActivity(
|
|
499
|
+
context, index, itemIntent,
|
|
500
|
+
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
|
501
|
+
)
|
|
502
|
+
views.setOnClickPendingIntent(containerId, pendingIntent)
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
private fun showFallback(views: RemoteViews, title: String, subtitle: String) {
|
|
507
|
+
views.setViewVisibility(R.id.widget_fallback, View.VISIBLE)
|
|
508
|
+
views.setViewVisibility(R.id.widget_grid_container, View.GONE)
|
|
509
|
+
views.setTextViewText(R.id.fallback_title, title)
|
|
510
|
+
views.setTextColor(R.id.fallback_title, ${titleColor})
|
|
511
|
+
views.setTextViewText(R.id.fallback_subtitle, subtitle)
|
|
512
|
+
views.setTextColor(R.id.fallback_subtitle, ${subtitleColor})
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
private fun parseTextValue(item: JSONObject, key: String): String {
|
|
516
|
+
return when {
|
|
517
|
+
item.has(key) && item.get(key) is String -> item.getString(key)
|
|
518
|
+
item.has(key) && item.get(key) is JSONObject -> item.getJSONObject(key).optString("text", "")
|
|
519
|
+
else -> ""
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
private fun parseIconName(item: JSONObject): String {
|
|
524
|
+
if (!item.has("icon")) return ""
|
|
525
|
+
return when {
|
|
526
|
+
item.get("icon") is String -> {
|
|
527
|
+
val iconStr = item.getString("icon")
|
|
528
|
+
// Extract filename from URL if it's a URL
|
|
529
|
+
if (iconStr.startsWith("http")) {
|
|
530
|
+
iconStr.substringAfterLast("/").substringBeforeLast(".")
|
|
531
|
+
} else {
|
|
532
|
+
iconStr
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
item.get("icon") is JSONObject -> {
|
|
536
|
+
val iconUrl = item.getJSONObject("icon").optString("url", "")
|
|
537
|
+
if (iconUrl.startsWith("http")) {
|
|
538
|
+
iconUrl.substringAfterLast("/").substringBeforeLast(".")
|
|
539
|
+
} else {
|
|
540
|
+
iconUrl
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
else -> ""
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
}
|
|
289
547
|
`;
|
|
290
548
|
}
|
|
291
549
|
// ── Single-type provider (default) ──
|
|
@@ -436,6 +694,59 @@ function generateWidgetLayoutXml(w) {
|
|
|
436
694
|
android:orientation="vertical"
|
|
437
695
|
android:visibility="gone" />
|
|
438
696
|
|
|
697
|
+
</LinearLayout>
|
|
698
|
+
`;
|
|
699
|
+
}
|
|
700
|
+
// ── Flex-grid layout ──
|
|
701
|
+
if (w.type === "flex-grid") {
|
|
702
|
+
const bgColor = w.style?.backgroundColor || "#FFFFFF";
|
|
703
|
+
const titleColor = w.style?.titleColor || "#000000";
|
|
704
|
+
const subtitleColor = w.style?.subtitleColor || "#888888";
|
|
705
|
+
return `<?xml version="1.0" encoding="utf-8"?>
|
|
706
|
+
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
707
|
+
android:id="@+id/widget_container"
|
|
708
|
+
android:layout_width="match_parent"
|
|
709
|
+
android:layout_height="match_parent"
|
|
710
|
+
android:orientation="vertical"
|
|
711
|
+
android:padding="8dp"
|
|
712
|
+
android:background="${bgColor}">
|
|
713
|
+
|
|
714
|
+
<!-- Fallback view (shown when no data) -->
|
|
715
|
+
<LinearLayout
|
|
716
|
+
android:id="@+id/widget_fallback"
|
|
717
|
+
android:layout_width="match_parent"
|
|
718
|
+
android:layout_height="match_parent"
|
|
719
|
+
android:orientation="vertical"
|
|
720
|
+
android:gravity="center"
|
|
721
|
+
android:visibility="visible">
|
|
722
|
+
|
|
723
|
+
<TextView
|
|
724
|
+
android:id="@+id/fallback_title"
|
|
725
|
+
android:layout_width="wrap_content"
|
|
726
|
+
android:layout_height="wrap_content"
|
|
727
|
+
android:text="${w.fallbackTitle}"
|
|
728
|
+
android:textSize="16sp"
|
|
729
|
+
android:textStyle="bold"
|
|
730
|
+
android:textColor="${titleColor}" />
|
|
731
|
+
|
|
732
|
+
<TextView
|
|
733
|
+
android:id="@+id/fallback_subtitle"
|
|
734
|
+
android:layout_width="wrap_content"
|
|
735
|
+
android:layout_height="wrap_content"
|
|
736
|
+
android:layout_marginTop="4dp"
|
|
737
|
+
android:text="${w.fallbackSubtitle}"
|
|
738
|
+
android:textSize="12sp"
|
|
739
|
+
android:textColor="${subtitleColor}" />
|
|
740
|
+
</LinearLayout>
|
|
741
|
+
|
|
742
|
+
<!-- Grid container (populated dynamically with rows) -->
|
|
743
|
+
<LinearLayout
|
|
744
|
+
android:id="@+id/widget_grid_container"
|
|
745
|
+
android:layout_width="match_parent"
|
|
746
|
+
android:layout_height="match_parent"
|
|
747
|
+
android:orientation="vertical"
|
|
748
|
+
android:visibility="gone" />
|
|
749
|
+
|
|
439
750
|
</LinearLayout>
|
|
440
751
|
`;
|
|
441
752
|
}
|
|
@@ -533,6 +844,107 @@ function generateWidgetItemLayoutXml(w) {
|
|
|
533
844
|
android:visibility="gone" />
|
|
534
845
|
</LinearLayout>
|
|
535
846
|
|
|
847
|
+
</LinearLayout>
|
|
848
|
+
`;
|
|
849
|
+
}
|
|
850
|
+
/** Generate row layout XML for flex-grid widgets */
|
|
851
|
+
function generateFlexGridRowLayoutXml(w) {
|
|
852
|
+
return `<?xml version="1.0" encoding="utf-8"?>
|
|
853
|
+
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
854
|
+
android:id="@+id/row_container"
|
|
855
|
+
android:layout_width="match_parent"
|
|
856
|
+
android:layout_height="0dp"
|
|
857
|
+
android:layout_weight="1"
|
|
858
|
+
android:orientation="horizontal"
|
|
859
|
+
android:gravity="center" />
|
|
860
|
+
`;
|
|
861
|
+
}
|
|
862
|
+
/** Generate list-style cell layout XML for flex-grid widgets */
|
|
863
|
+
function generateFlexGridCellListLayoutXml(w) {
|
|
864
|
+
const titleColor = w.style?.titleColor || "#000000";
|
|
865
|
+
const subtitleColor = w.style?.subtitleColor || "#888888";
|
|
866
|
+
const accentColor = w.style?.accentColor || "#6200EE";
|
|
867
|
+
return `<?xml version="1.0" encoding="utf-8"?>
|
|
868
|
+
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
869
|
+
android:id="@+id/cell_container"
|
|
870
|
+
android:layout_width="0dp"
|
|
871
|
+
android:layout_height="match_parent"
|
|
872
|
+
android:layout_weight="1"
|
|
873
|
+
android:orientation="horizontal"
|
|
874
|
+
android:gravity="center_vertical"
|
|
875
|
+
android:paddingHorizontal="6dp"
|
|
876
|
+
android:paddingVertical="4dp">
|
|
877
|
+
|
|
878
|
+
<ImageView
|
|
879
|
+
android:id="@+id/cell_icon"
|
|
880
|
+
android:layout_width="36dp"
|
|
881
|
+
android:layout_height="36dp"
|
|
882
|
+
android:layout_marginEnd="8dp"
|
|
883
|
+
android:scaleType="centerCrop"
|
|
884
|
+
android:visibility="gone" />
|
|
885
|
+
|
|
886
|
+
<LinearLayout
|
|
887
|
+
android:layout_width="0dp"
|
|
888
|
+
android:layout_height="wrap_content"
|
|
889
|
+
android:layout_weight="1"
|
|
890
|
+
android:orientation="vertical">
|
|
891
|
+
|
|
892
|
+
<TextView
|
|
893
|
+
android:id="@+id/cell_title"
|
|
894
|
+
android:layout_width="match_parent"
|
|
895
|
+
android:layout_height="wrap_content"
|
|
896
|
+
android:textSize="13sp"
|
|
897
|
+
android:textStyle="bold"
|
|
898
|
+
android:textColor="${titleColor}"
|
|
899
|
+
android:maxLines="1"
|
|
900
|
+
android:ellipsize="end" />
|
|
901
|
+
|
|
902
|
+
<TextView
|
|
903
|
+
android:id="@+id/cell_description"
|
|
904
|
+
android:layout_width="match_parent"
|
|
905
|
+
android:layout_height="wrap_content"
|
|
906
|
+
android:textSize="11sp"
|
|
907
|
+
android:textColor="${subtitleColor}"
|
|
908
|
+
android:maxLines="1"
|
|
909
|
+
android:ellipsize="end"
|
|
910
|
+
android:visibility="gone" />
|
|
911
|
+
</LinearLayout>
|
|
912
|
+
|
|
913
|
+
</LinearLayout>
|
|
914
|
+
`;
|
|
915
|
+
}
|
|
916
|
+
/** Generate card-style cell layout XML for flex-grid widgets */
|
|
917
|
+
function generateFlexGridCellCardLayoutXml(w) {
|
|
918
|
+
const titleColor = w.style?.titleColor || "#000000";
|
|
919
|
+
const accentColor = w.style?.accentColor || "#6200EE";
|
|
920
|
+
return `<?xml version="1.0" encoding="utf-8"?>
|
|
921
|
+
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
922
|
+
android:id="@+id/cell_container"
|
|
923
|
+
android:layout_width="0dp"
|
|
924
|
+
android:layout_height="match_parent"
|
|
925
|
+
android:layout_weight="1"
|
|
926
|
+
android:orientation="vertical"
|
|
927
|
+
android:gravity="center"
|
|
928
|
+
android:padding="4dp">
|
|
929
|
+
|
|
930
|
+
<ImageView
|
|
931
|
+
android:id="@+id/cell_icon"
|
|
932
|
+
android:layout_width="40dp"
|
|
933
|
+
android:layout_height="40dp"
|
|
934
|
+
android:scaleType="centerCrop"
|
|
935
|
+
android:visibility="gone" />
|
|
936
|
+
|
|
937
|
+
<TextView
|
|
938
|
+
android:id="@+id/cell_title"
|
|
939
|
+
android:layout_width="match_parent"
|
|
940
|
+
android:layout_height="wrap_content"
|
|
941
|
+
android:layout_marginTop="4dp"
|
|
942
|
+
android:textSize="10sp"
|
|
943
|
+
android:textColor="${titleColor}"
|
|
944
|
+
android:maxLines="2"
|
|
945
|
+
android:ellipsize="end"
|
|
946
|
+
android:gravity="center" />
|
|
947
|
+
|
|
536
948
|
</LinearLayout>
|
|
537
949
|
`;
|
|
538
950
|
}
|
|
@@ -591,6 +1003,19 @@ const withAndroidWidget = (config, props = {}) => {
|
|
|
591
1003
|
const itemLayoutXml = generateWidgetItemLayoutXml(w);
|
|
592
1004
|
fs.writeFileSync(path.join(resLayoutPath, `${w.name.toLowerCase()}_item.xml`), itemLayoutXml);
|
|
593
1005
|
}
|
|
1006
|
+
// Flex-grid layouts (row, card cell, list cell)
|
|
1007
|
+
if (w.type === "flex-grid") {
|
|
1008
|
+
// Row layout
|
|
1009
|
+
const rowLayoutXml = generateFlexGridRowLayoutXml(w);
|
|
1010
|
+
fs.writeFileSync(path.join(resLayoutPath, `${w.name.toLowerCase()}_row.xml`), rowLayoutXml);
|
|
1011
|
+
// Card cell layout (icon on top, text below)
|
|
1012
|
+
const cellCardLayoutXml = generateFlexGridCellCardLayoutXml(w);
|
|
1013
|
+
fs.writeFileSync(path.join(resLayoutPath, `${w.name.toLowerCase()}_cell_card.xml`), cellCardLayoutXml);
|
|
1014
|
+
// List cell layout (icon left, text right)
|
|
1015
|
+
const cellListLayoutXml = generateFlexGridCellListLayoutXml(w);
|
|
1016
|
+
fs.writeFileSync(path.join(resLayoutPath, `${w.name.toLowerCase()}_cell_list.xml`), cellListLayoutXml);
|
|
1017
|
+
console.log(`[nn-widgets] Generated Android flex-grid layouts for ${w.name}`);
|
|
1018
|
+
}
|
|
594
1019
|
// Widget info XML
|
|
595
1020
|
const widgetInfoXml = generateWidgetInfoXml(w, resolvedProps.android.updatePeriodMillis);
|
|
596
1021
|
fs.writeFileSync(path.join(resXmlPath, `${w.name.toLowerCase()}_info.xml`), widgetInfoXml);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"withIosWidget.d.ts","sourceRoot":"","sources":["../src/withIosWidget.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EAIb,MAAM,sBAAsB,CAAC;AAG9B,OAAO,KAAK,EACV,oBAAoB,EACpB,mBAAmB,EAEpB,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"withIosWidget.d.ts","sourceRoot":"","sources":["../src/withIosWidget.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EAIb,MAAM,sBAAsB,CAAC;AAG9B,OAAO,KAAK,EACV,oBAAoB,EACpB,mBAAmB,EAEpB,MAAM,SAAS,CAAC;AA8pDjB,eAAO,MAAM,aAAa,EAAE,YAAY,CAAC,oBAAoB,CAugB5D,CAAC;AAMF,wBAAgB,eAAe,CAC7B,KAAK,EAAE,oBAAoB,EAC3B,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM,GACvB,mBAAmB,CA2GrB;AAED,eAAe,aAAa,CAAC"}
|
|
@@ -1085,7 +1085,6 @@ struct ${w.name}EntryView: View {
|
|
|
1085
1085
|
.foregroundColor(.secondary)
|
|
1086
1086
|
}
|
|
1087
1087
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
1088
|
-
.background(${bgColor})
|
|
1089
1088
|
} else {
|
|
1090
1089
|
GeometryReader { geometry in
|
|
1091
1090
|
let availableWidth = geometry.size.width
|
|
@@ -1117,7 +1116,6 @@ struct ${w.name}EntryView: View {
|
|
|
1117
1116
|
}
|
|
1118
1117
|
}
|
|
1119
1118
|
}
|
|
1120
|
-
.background(${bgColor})
|
|
1121
1119
|
}
|
|
1122
1120
|
}
|
|
1123
1121
|
}
|