Skip to content

Commit

Permalink
✨ Complete horizontal widget #9
Browse files Browse the repository at this point in the history
  • Loading branch information
iqfareez committed Dec 7, 2023
1 parent c1544fa commit 6604fce
Show file tree
Hide file tree
Showing 13 changed files with 95 additions and 59 deletions.
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
// https://github.com/flutter/flutter/issues/110658
implementation "androidx.window:window:1.0.0"
implementation "androidx.window:window:1.0.0"
implementation 'androidx.window:window-java:1.0.0'

implementation 'com.google.code.gson:gson:2.10.1'
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.os.Build
import android.util.Log
import android.widget.RemoteViews
import es.antonborri.home_widget.HomeWidgetPlugin
import org.json.JSONObject
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
Expand All @@ -19,6 +21,7 @@ import java.util.TimeZone


private const val ACTION_SCHEDULED_UPDATE = "live.iqfareez.waktusolatmalaysia.SCHEDULED_UPDATE"
private const val LOG_TAG = "MPT_Widget"

/**
* Implementation of App Widget functionality.
Expand All @@ -32,6 +35,7 @@ class SolatHorizontalWidget : AppWidgetProvider() {
val widgetData = HomeWidgetPlugin.getData(context)
// There may be multiple widgets active, so update all of them
for (appWidgetId in appWidgetIds) {
Log.i(LOG_TAG, "onUpdate: SolatHorizontalWidget called")
updateAppWidget(context, appWidgetManager, appWidgetId, widgetData)
}

Expand All @@ -50,7 +54,8 @@ class SolatHorizontalWidget : AppWidgetProvider() {
super.onReceive(context, intent);
if (intent.action.equals(ACTION_SCHEDULED_UPDATE)) {
val manager = AppWidgetManager.getInstance(context)
val ids = manager.getAppWidgetIds(ComponentName(context, SolatHorizontalWidget::class.java))
val ids =
manager.getAppWidgetIds(ComponentName(context, SolatHorizontalWidget::class.java))
onUpdate(context, manager, ids)
}
}
Expand All @@ -74,36 +79,73 @@ internal fun updateAppWidget(
// Set the click listener for the widget
views.setOnClickPendingIntent(android.R.id.background, pendingIntent)

// Parse the JSON in SharedPreferences
val prayerData = widgetData.getString("prayer_data", null);

// If data not available, display help message
if (prayerData == null) {
views.setTextViewText(R.id.widget_date, "Please open app to get prayer data")
return;
}

val parsed = JSONObject(prayerData)

Log.i(LOG_TAG, "updateAppWidget: Reading SP json ${parsed.get("zone")}, ${parsed.get("month")}-${parsed.get("year")} ")

val prayers = parsed.getJSONArray("prayers")

val calendar = Calendar.getInstance()
val todayIndex = calendar.get(Calendar.DAY_OF_WEEK) - 1;
val todayPrayer: JSONObject = prayers.get(todayIndex) as JSONObject;

val subuhTime = todayPrayer.getLong("fajr")
val zohorTime = todayPrayer.getLong("dhuhr")
val asarTime = todayPrayer.getLong("asr")
val maghribTime = todayPrayer.getLong("maghrib")
val isyakTime = todayPrayer.getLong("isha")

val gmt8TimeZone = TimeZone.getTimeZone("GMT+8")
val timeFormat = SimpleDateFormat("h:mm a")
timeFormat.timeZone = gmt8TimeZone

fun formatTime(timeInMillis: Long): String {
val date = Date(timeInMillis)
return timeFormat.format(date)
}

val formattedSubuhTime = formatTime(subuhTime)
val formattedZohorTime = formatTime(zohorTime)
val formattedAsarTime = formatTime(asarTime)
val formattedMaghribTime = formatTime(maghribTime)
val formattedIsyakTime = formatTime(isyakTime)

val dateFormat = SimpleDateFormat("dd/MM/yyyy", Locale.getDefault())
dateFormat.timeZone = TimeZone.getTimeZone("Asia/Kuala_Lumpur") // Set Malaysia timezone
val formattedDate = dateFormat.format(Date())

val widgetTitle = "${parsed.get("zone")}: ${widgetData.getString("widget_title", null)}"

// Set content
views.setTextViewText(R.id.widget_date, formattedDate)

// Set widget content
views.setTextViewText(
R.id.widget_title, widgetData.getString("widget_title", null)
R.id.widget_title, widgetTitle
?: "Please open app to set widget data"
)
views.setTextViewText(
R.id.subuh_time, widgetData.getString("widget_subuh_time", null)
?: "00:00"
R.id.subuh_time, formattedSubuhTime
)
views.setTextViewText(
R.id.zuhur_time, widgetData.getString("widget_zuhur_time", null)
?: "00:00"
R.id.zuhur_time, formattedZohorTime
)
views.setTextViewText(
R.id.asar_time, widgetData.getString("widget_asar_time", null)
?: "00:00"
R.id.asar_time, formattedAsarTime
)
views.setTextViewText(
R.id.maghrib_time, widgetData.getString("widget_maghrib_time", null)
?: "00:00"
R.id.maghrib_time, formattedMaghribTime
)
views.setTextViewText(
R.id.isyak_time, widgetData.getString("widget_isyak_time", null)
?: "00:00"
R.id.isyak_time, formattedIsyakTime
)

// Instruct the widget manager to update the widget
Expand Down
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
android:initialLayout="@layout/solat_horizontal_widget"
android:minWidth="250dp"
android:minHeight="40dp"
android:previewImage="@drawable/example_appwidget_preview"
android:previewImage="@drawable/example_widget_horizontal"
android:previewLayout="@layout/solat_horizontal_widget"
android:resizeMode="vertical"
android:targetCellWidth="4"
Expand Down
1 change: 0 additions & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ buildscript {
classpath 'com.android.tools.build:gradle:7.1.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.gms:google-services:4.3.4'

classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1'
}
}
Expand Down
2 changes: 2 additions & 0 deletions lib/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ const kTimetableShowOneThird = "tbOneThird";
const kTasbihCount = "tasbihCount";
const kTasbihGradientColour = "tasbihColours";
const kNoAdsStartTime = "noAdsStartTime";
// store current user location name to be consumed by homescreen widget
const kWidgetLocation = "widgetLocation";

// API base
const kApiBaseUrl = 'mpt-server.vercel.app';
Expand Down
16 changes: 8 additions & 8 deletions lib/models/mpt_server_solat.dart
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,14 @@ class Prayers {

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['isha'] = isha;
data['syuruk'] = syuruk;
data['day'] = day;
data['dhuhr'] = dhuhr;
data['maghrib'] = maghrib;
data['fajr'] = fajr;
data['asr'] = asr;
data['hijri'] = hijri;
data['isha'] = isha.millisecondsSinceEpoch;
data['syuruk'] = syuruk.millisecondsSinceEpoch;
data['day'] = day.millisecondsSinceEpoch;
data['dhuhr'] = dhuhr.millisecondsSinceEpoch;
data['maghrib'] = maghrib.millisecondsSinceEpoch;
data['fajr'] = fajr.millisecondsSinceEpoch;
data['asr'] = asr.millisecondsSinceEpoch;
data['hijri'] = hijri.toString();
return data;
}
}
26 changes: 8 additions & 18 deletions lib/utils/homescreen.dart
Original file line number Diff line number Diff line change
@@ -1,26 +1,16 @@
import 'dart:convert';

import 'package:home_widget/home_widget.dart';

/// Homescreen widget utility helper
class Homescreen {
/// Update the solat widget with the current prayer time data
static void updateSolatWidget(
{required String title,
required String subuhTime,
required String zohorTime,
required String asarTime,
required String maghribTime,
required String isyakTime}) async {
// set the data
await Future.wait([
HomeWidget.saveWidgetData('widget_title', title),
HomeWidget.saveWidgetData('widget_subuh_time', subuhTime),
HomeWidget.saveWidgetData('widget_zuhur_time', zohorTime),
HomeWidget.saveWidgetData('widget_asar_time', asarTime),
HomeWidget.saveWidgetData('widget_maghrib_time', maghribTime),
HomeWidget.saveWidgetData('widget_isyak_time', isyakTime),
]);
/// Save the whole month prayer time data as json
static Future<void> savePrayerDataAndUpdateWidget(
Map<String, dynamic> json, String widgetTitle) async {
await HomeWidget.saveWidgetData('prayer_data', jsonEncode(json));
await HomeWidget.saveWidgetData('widget_title', widgetTitle);

// update the widget based on the set data
// Trigger widget update to show the new data
HomeWidget.updateWidget(
name: 'SolatHorizontalWidget',
androidName: 'SolatHorizontalWidget',
Expand Down
14 changes: 14 additions & 0 deletions lib/utils/prayer_data_handler.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import 'package:get_storage/get_storage.dart';

import '../constants.dart';
import '../location_utils/location_database.dart';
import '../models/mpt_server_solat.dart';
import '../networking/mpt_fetch_api.dart';
import 'homescreen.dart';

final int _day = DateTime.now().day;

Expand All @@ -10,6 +15,15 @@ class PrayDataHandler {
/// Returns the hijri date
static Future<String> init(String zone) async {
_mptServerSolat = await MptApiFetch.fetchMpt(zone);

// Alang2 init, we save the data to widget
var widgetLocation = GetStorage().read(kWidgetLocation);
if (widgetLocation == null || widgetLocation.isEmpty) {
widgetLocation = LocationDatabase.daerah(zone);
}
Homescreen.savePrayerDataAndUpdateWidget(
_mptServerSolat!.toJson(), widgetLocation!);

return today().hijri.toString();
}

Expand Down
15 changes: 0 additions & 15 deletions lib/views/app_body.dart
Original file line number Diff line number Diff line change
Expand Up @@ -110,21 +110,6 @@ class _AppBodyState extends State<AppBody> {
onRetryPressed: () => setState(() {}));
}

// TODO: Use Flutter Workmanager
// update homscreen widget
final prayerData = PrayDataHandler.today();
// TODO: Use location data from geolocation
final widgetTitle =
'${LocationDatabase.negeri(value.currentLocationCode)}: ${LocationDatabase.daerah(value.currentLocationCode)}';
Homescreen.updateSolatWidget(
title: widgetTitle,
subuhTime: prayerData.fajr.format(true),
zohorTime: prayerData.dhuhr.format(true),
asarTime: prayerData.asr.format(true),
maghribTime: prayerData.maghrib.format(true),
isyakTime: prayerData.isha.format(true),
);

// display the list of prayer timee
return const PrayTimeList();
}),
Expand Down
4 changes: 4 additions & 0 deletions lib/views/zone_chooser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ class LocationChooser {
Provider.of<LocationProvider>(context, listen: false).currentLocationCode =
newZone.jakimCode;
onNewLocationSaved(context);
print(newZone.daerah);
GetStorage().write(kWidgetLocation, newZone.daerah);
}
}

Expand Down Expand Up @@ -241,6 +243,8 @@ class ZoneSuccessWidget extends StatelessWidget {
onPressed: () {
value.currentLocationCode = coordinateData.zone;
LocationChooser.onNewLocationSaved(context);
GetStorage().write(kWidgetLocation,
coordinateData.lokasi ?? coordinateData.negeri);

Navigator.pop(context, true);
},
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ description: App waktu solat seluruh Malaysia

publish_to: "none" # Remove this line if you wish to publish to pub.dev

version: 2.10.1+137
version: 2.11.0-pre.1+138

environment:
sdk: ">=3.0.0 <4.0.0"
Expand Down

0 comments on commit 6604fce

Please sign in to comment.