diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index dd139fc5..d842cb6d 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -105,6 +105,11 @@
android:excludeFromRecents="true"
android:noHistory="true"
android:theme="@style/AppTheme.NoDisplay" />
+
.filterOutArchived() {
+fun MutableList.filterOutArchived(): MutableList {
this.removeAll { it.archived }
+ return this
}
fun Activity.isStoragePermissionGranted(): Boolean {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/WidgetTimetable.java b/app/src/main/java/pl/szczodrzynski/edziennik/WidgetTimetable.java
deleted file mode 100644
index 7dca917e..00000000
--- a/app/src/main/java/pl/szczodrzynski/edziennik/WidgetTimetable.java
+++ /dev/null
@@ -1,450 +0,0 @@
-package pl.szczodrzynski.edziennik;
-
-import android.app.PendingIntent;
-import android.appwidget.AppWidgetManager;
-import android.appwidget.AppWidgetProvider;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.PorterDuff;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Build;
-import android.util.SparseArray;
-import android.view.View;
-import android.widget.RemoteViews;
-
-import com.mikepenz.iconics.IconicsColor;
-import com.mikepenz.iconics.IconicsDrawable;
-import com.mikepenz.iconics.IconicsSize;
-import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-
-import pl.szczodrzynski.edziennik.api.v2.events.task.EdziennikTask;
-import pl.szczodrzynski.edziennik.data.db.modules.events.EventFull;
-import pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonChange;
-import pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonFull;
-import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile;
-import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragment;
-import pl.szczodrzynski.edziennik.utils.models.Date;
-import pl.szczodrzynski.edziennik.utils.models.ItemWidgetTimetableModel;
-import pl.szczodrzynski.edziennik.utils.models.Time;
-import pl.szczodrzynski.edziennik.utils.models.Week;
-import pl.szczodrzynski.edziennik.widgets.WidgetConfig;
-import pl.szczodrzynski.edziennik.widgets.timetable.LessonDetailsActivity;
-import pl.szczodrzynski.edziennik.widgets.timetable.WidgetTimetableService;
-
-import static pl.szczodrzynski.edziennik.ExtensionsKt.filterOutArchived;
-import static pl.szczodrzynski.edziennik.data.db.modules.events.Event.TYPE_HOMEWORK;
-import static pl.szczodrzynski.edziennik.utils.Utils.bs;
-
-
-public class WidgetTimetable extends AppWidgetProvider {
-
-
- public static final String ACTION_SYNC_DATA = "ACTION_SYNC_DATA";
- private static final String TAG = "WidgetTimetable";
- private static int modeInt = 0;
-
- public WidgetTimetable() {
- // Start the worker thread
- //HandlerThread sWorkerThread = new HandlerThread("WidgetTimetable-worker");
- //sWorkerThread.start();
- //Handler sWorkerQueue = new Handler(sWorkerThread.getLooper());
- }
-
- public static SparseArray> timetables = null;
-
- @Override
- public void onReceive(Context context, Intent intent) {
- if (ACTION_SYNC_DATA.equals(intent.getAction())) {
- EdziennikTask.Companion.sync().enqueue(context);
- }
- super.onReceive(context, intent);
- }
-
- public static PendingIntent getPendingSelfIntent(Context context, String action) {
- Intent intent = new Intent(context, WidgetTimetable.class);
- intent.setAction(action);
- return getPendingSelfIntent(context, intent);
- }
- public static PendingIntent getPendingSelfIntent(Context context, Intent intent) {
- return PendingIntent.getBroadcast(context, 0, intent, 0);
- }
-
- public static Bitmap drawableToBitmap (Drawable drawable) {
-
- if (drawable instanceof BitmapDrawable) {
- return ((BitmapDrawable)drawable).getBitmap();
- }
-
- Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
- Canvas canvas = new Canvas(bitmap);
- drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
- drawable.draw(canvas);
-
- return bitmap;
- }
-
- @Override
- public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
- ComponentName thisWidget = new ComponentName(context, WidgetTimetable.class);
-
- timetables = new SparseArray<>();
- //timetables.clear();
-
- App app = (App)context.getApplicationContext();
-
- int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
- // There may be multiple widgets active, so update all of them
- for (int appWidgetId : allWidgetIds) {
-
- //d(TAG, "thr "+Thread.currentThread().getName());
-
- WidgetConfig widgetConfig = app.appConfig.widgetTimetableConfigs.get(appWidgetId);
- if (widgetConfig == null) {
- widgetConfig = new WidgetConfig(app.profileFirstId());
- app.appConfig.widgetTimetableConfigs.put(appWidgetId, widgetConfig);
- app.appConfig.savePending = true;
- }
-
- RemoteViews views;
- if (widgetConfig.bigStyle) {
- views = new RemoteViews(context.getPackageName(), widgetConfig.darkTheme ? R.layout.widget_timetable_dark_big : R.layout.widget_timetable_big);
- }
- else {
- views = new RemoteViews(context.getPackageName(), widgetConfig.darkTheme ? R.layout.widget_timetable_dark : R.layout.widget_timetable);
- }
-
- PorterDuff.Mode mode = PorterDuff.Mode.DST_IN;
- /*if (widgetConfig.darkTheme) {
- switch (modeInt) {
- case 0:
- mode = PorterDuff.Mode.ADD;
- d(TAG, "ADD");
- break;
- case 1:
- mode = PorterDuff.Mode.DST_ATOP;
- d(TAG, "DST_ATOP");
- break;
- case 2:
- mode = PorterDuff.Mode.DST_IN;
- d(TAG, "DST_IN");
- break;
- case 3:
- mode = PorterDuff.Mode.DST_OUT;
- d(TAG, "DST_OUT");
- break;
- case 4:
- mode = PorterDuff.Mode.DST_OVER;
- d(TAG, "DST_OVER");
- break;
- case 5:
- mode = PorterDuff.Mode.LIGHTEN;
- d(TAG, "LIGHTEN");
- break;
- case 6:
- mode = PorterDuff.Mode.MULTIPLY;
- d(TAG, "MULTIPLY");
- break;
- case 7:
- mode = PorterDuff.Mode.OVERLAY;
- d(TAG, "OVERLAY");
- break;
- case 8:
- mode = PorterDuff.Mode.SCREEN;
- d(TAG, "SCREEN");
- break;
- case 9:
- mode = PorterDuff.Mode.SRC_ATOP;
- d(TAG, "SRC_ATOP");
- break;
- case 10:
- mode = PorterDuff.Mode.SRC_IN;
- d(TAG, "SRC_IN");
- break;
- case 11:
- mode = PorterDuff.Mode.SRC_OUT;
- d(TAG, "SRC_OUT");
- break;
- case 12:
- mode = PorterDuff.Mode.SRC_OVER;
- d(TAG, "SRC_OVER");
- break;
- case 13:
- mode = PorterDuff.Mode.XOR;
- d(TAG, "XOR");
- break;
- default:
- modeInt = 0;
- mode = PorterDuff.Mode.ADD;
- d(TAG, "ADD");
- break;
- }
- }*/
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
- // this code seems to crash the launcher on >= P
- float transparency = widgetConfig.opacity; //0...1
- long colorFilter = 0x01000000L * (long) (255f * transparency);
- try {
- final Method[] declaredMethods = Class.forName("android.widget.RemoteViews").getDeclaredMethods();
- final int len = declaredMethods.length;
- if (len > 0) {
- for (int m = 0; m < len; m++) {
- final Method method = declaredMethods[m];
- if (method.getName().equals("setDrawableParameters")) {
- method.setAccessible(true);
- method.invoke(views, R.id.widgetTimetableListView, true, -1, (int) colorFilter, mode, -1);
- method.invoke(views, R.id.widgetTimetableHeader, true, -1, (int) colorFilter, mode, -1);
- break;
- }
- }
- }
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- }
- }
-
- Intent refreshIntent = new Intent(context, WidgetTimetable.class);
- refreshIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
- refreshIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
- PendingIntent pendingRefreshIntent = PendingIntent.getBroadcast(context,
- 0, refreshIntent, PendingIntent.FLAG_UPDATE_CURRENT);
- views.setOnClickPendingIntent(R.id.widgetTimetableRefresh, pendingRefreshIntent);
-
- views.setOnClickPendingIntent(R.id.widgetTimetableSync, WidgetTimetable.getPendingSelfIntent(context, ACTION_SYNC_DATA));
-
- views.setImageViewBitmap(R.id.widgetTimetableRefresh, new IconicsDrawable(context, CommunityMaterial.Icon2.cmd_refresh)
- .color(IconicsColor.colorInt(Color.WHITE))
- .size(IconicsSize.dp(widgetConfig.bigStyle ? 24 : 16)).toBitmap());
-
- views.setImageViewBitmap(R.id.widgetTimetableSync, new IconicsDrawable(context, CommunityMaterial.Icon2.cmd_sync)
- .color(IconicsColor.colorInt(Color.WHITE))
- .size(IconicsSize.dp(widgetConfig.bigStyle ? 24 : 16)).toBitmap());
-
- boolean unified = widgetConfig.profileId == -1;
-
- List profileList = new ArrayList<>();
- if (unified) {
- profileList = app.db.profileDao().getAllNow();
- filterOutArchived(profileList);
- }
- else {
- Profile profile = app.db.profileDao().getFullByIdNow(widgetConfig.profileId);
- if (profile != null) {
- profileList.add(profile);
- }
- }
-
- //d(TAG, "Profiles: "+ Arrays.toString(profileList.toArray()));
-
- if (profileList == null || profileList.size() == 0) {
- views.setViewVisibility(R.id.widgetTimetableLoading, View.VISIBLE);
- views.setTextViewText(R.id.widgetTimetableLoading, app.getString(R.string.widget_timetable_profile_doesnt_exist));
- }
- else {
- views.setViewVisibility(R.id.widgetTimetableLoading, View.GONE);
- //Register profile;
-
- long bellSyncDiffMillis = 0;
- if (app.appConfig.bellSyncDiff != null) {
- bellSyncDiffMillis = app.appConfig.bellSyncDiff.hour * 60 * 60 * 1000 + app.appConfig.bellSyncDiff.minute * 60 * 1000 + app.appConfig.bellSyncDiff.second * 1000;
- bellSyncDiffMillis *= app.appConfig.bellSyncMultiplier;
- bellSyncDiffMillis *= -1;
- }
-
- List lessonList = new ArrayList<>();
-
- Time syncedNow = Time.fromMillis(Time.getNow().getInMillis() + bellSyncDiffMillis);
-
- Date today = Date.getToday();
-
- int openProfileId = -1;
- Date displayingDate = null;
- int displayingWeekDay = 0;
- if (unified) {
- views.setTextViewText(R.id.widgetTimetableSubtitle, app.getString(R.string.widget_timetable_title_unified));
- }
- else {
- views.setTextViewText(R.id.widgetTimetableSubtitle, profileList.get(0).getName());
- openProfileId = profileList.get(0).getId();
- }
-
- List lessons = app.db.lessonDao().getAllWeekNow(unified ? -1 : openProfileId, today.clone().stepForward(0, 0, -today.getWeekDay()), today);
-
- int scrollPos = 0;
-
- for (Profile profile: profileList) {
- Date profileDisplayingDate = HomeFragment.findDateWithLessons(profile.getId(), lessons, syncedNow, 1);
- int profileDisplayingWeekDay = profileDisplayingDate.getWeekDay();
- int dayDiff = Date.diffDays(profileDisplayingDate, Date.getToday());
-
- //d(TAG, "For profile "+profile.name+" displayingDate is "+profileDisplayingDate.getStringY_m_d());
- if (displayingDate == null || profileDisplayingDate.getValue() < displayingDate.getValue()) {
- displayingDate = profileDisplayingDate;
- displayingWeekDay = profileDisplayingWeekDay;
- //d(TAG, "Setting as global dd");
- if (dayDiff == 0) {
- views.setTextViewText(R.id.widgetTimetableTitle, app.getString(R.string.day_today_format, Week.getFullDayName(displayingWeekDay)));
- } else if (dayDiff == 1) {
- views.setTextViewText(R.id.widgetTimetableTitle, app.getString(R.string.day_tomorrow_format, Week.getFullDayName(displayingWeekDay)));
- } else {
- views.setTextViewText(R.id.widgetTimetableTitle, Week.getFullDayName(displayingWeekDay) + " " + profileDisplayingDate.getStringDm());
- }
- }
- }
-
- for (Profile profile: profileList) {
- int pos = 0;
-
- List events = app.db.eventDao().getAllByDateNow(profile.getId(), displayingDate);
- if (events == null)
- events = new ArrayList<>();
-
- if (unified) {
- ItemWidgetTimetableModel separator = new ItemWidgetTimetableModel();
- separator.profileId = profile.getId();
- separator.bigStyle = widgetConfig.bigStyle;
- separator.darkTheme = widgetConfig.darkTheme;
- separator.separatorProfileName = profile.getName();
- lessonList.add(separator);
- }
-
- for (LessonFull lesson : lessons) {
- //d(TAG, "Profile "+profile.id+" Lesson profileId "+lesson.profileId+" weekDay "+lesson.weekDay+", "+lesson);
- if (profile.getId() != lesson.profileId || displayingWeekDay != lesson.weekDay)
- continue;
- //d(TAG, "Not skipped");
- ItemWidgetTimetableModel model = new ItemWidgetTimetableModel();
-
- model.bigStyle = widgetConfig.bigStyle;
- model.darkTheme = widgetConfig.darkTheme;
-
- model.profileId = profile.getId();
-
- model.lessonDate = displayingDate;
- model.startTime = lesson.startTime;
- model.endTime = lesson.endTime;
-
- model.lessonPassed = (syncedNow.getValue() > lesson.endTime.getValue()) && displayingWeekDay == Week.getTodayWeekDay();
- model.lessonCurrent = (Time.inRange(lesson.startTime, lesson.endTime, syncedNow)) && displayingWeekDay == Week.getTodayWeekDay();
-
- if (model.lessonCurrent) {
- scrollPos = pos;
- } else if (model.lessonPassed) {
- scrollPos = pos + 1;
- }
- pos++;
-
- model.subjectName = bs(lesson.subjectLongName);
- model.classroomName = lesson.classroomName;
-
- model.bellSyncDiffMillis = bellSyncDiffMillis;
-
- if (lesson.changeId != 0) {
- if (lesson.changeType == LessonChange.TYPE_CHANGE) {
- model.lessonChange = true;
- if (lesson.changedClassroomName()) {
- model.newClassroomName = lesson.changeClassroomName;
- }
-
- if (lesson.changedSubjectLongName()) {
- model.newSubjectName = lesson.changeSubjectLongName;
- }
- }
- if (lesson.changeType == LessonChange.TYPE_CANCELLED) {
- model.lessonCancelled = true;
- }
- }
-
- for (EventFull event : events) {
- if (event.startTime == null)
- continue;
- if (event.eventDate.getValue() == displayingDate.getValue()
- && event.startTime.getValue() == lesson.startTime.getValue()) {
- model.eventColors.add(event.type == TYPE_HOMEWORK ? ItemWidgetTimetableModel.EVENT_COLOR_HOMEWORK : event.getColor());
- }
- }
-
- lessonList.add(model);
- }
- }
-
- if (lessonList.size() == 0) {
- views.setViewVisibility(R.id.widgetTimetableLoading, View.VISIBLE);
- views.setRemoteAdapter(R.id.widgetTimetableListView, new Intent());
- views.setTextViewText(R.id.widgetTimetableLoading, app.getString(R.string.widget_timetable_no_lessons));
- appWidgetManager.updateAppWidget(appWidgetId, views);
- }
- else {
- views.setViewVisibility(R.id.widgetTimetableLoading, View.GONE);
-
- timetables.put(appWidgetId, lessonList);
- //WidgetTimetableListProvider.widgetsLessons.put(appWidgetId, lessons);
- //views.setRemoteAdapter(R.id.widgetTimetableListView, new Intent());
- Intent listIntent = new Intent(context, WidgetTimetableService.class);
- listIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
- listIntent.setData(Uri.parse(listIntent.toUri(Intent.URI_INTENT_SCHEME)));
- views.setRemoteAdapter(R.id.widgetTimetableListView, listIntent);
-
- // template to handle the click listener for each item
- Intent intentTemplate = new Intent(context, LessonDetailsActivity.class);
- // Old activities shouldn't be in the history stack
- intentTemplate.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- PendingIntent pendingIntentTimetable = PendingIntent.getActivity(context,
- 0,
- intentTemplate,
- 0);
- views.setPendingIntentTemplate(R.id.widgetTimetableListView, pendingIntentTimetable);
-
- Intent openIntent = new Intent(context, MainActivity.class);
- openIntent.setAction("android.intent.action.MAIN");
- if (!unified) {
- openIntent.putExtra("profileId", openProfileId);
- openIntent.putExtra("timetableDate", displayingDate.getValue());
- }
- openIntent.putExtra("fragmentId", MainActivity.DRAWER_ITEM_TIMETABLE);
- PendingIntent pendingOpenIntent = PendingIntent.getActivity(context,
- appWidgetId, openIntent, PendingIntent.FLAG_UPDATE_CURRENT);
- views.setOnClickPendingIntent(R.id.widgetTimetableHeader, pendingOpenIntent);
-
- if (!unified)
- views.setScrollPosition(R.id.widgetTimetableListView, scrollPos);
- }
- }
-
- appWidgetManager.updateAppWidget(appWidgetId, views);
- appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widgetTimetableListView);
- }
- //modeInt++;
- }
-
- @Override
- public void onEnabled(Context context) {
- // Enter relevant functionality for when the first widget is created
- }
-
- @Override
- public void onDeleted(Context context, int[] appWidgetIds) {
- App app = (App) context.getApplicationContext();
- for (int appWidgetId: appWidgetIds) {
- app.appConfig.widgetTimetableConfigs.remove(appWidgetId);
- }
- app.saveConfig("widgetTimetableConfigs");
- }
-}
-
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/WidgetTimetable.kt b/app/src/main/java/pl/szczodrzynski/edziennik/WidgetTimetable.kt
new file mode 100644
index 00000000..088f4c60
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/WidgetTimetable.kt
@@ -0,0 +1,371 @@
+package pl.szczodrzynski.edziennik
+
+import android.app.PendingIntent
+import android.appwidget.AppWidgetManager
+import android.appwidget.AppWidgetProvider
+import android.content.ComponentName
+import android.content.Context
+import android.content.Intent
+import android.graphics.Bitmap
+import android.graphics.Canvas
+import android.graphics.Color
+import android.graphics.PorterDuff
+import android.graphics.drawable.BitmapDrawable
+import android.graphics.drawable.Drawable
+import android.net.Uri
+import android.os.Build
+import android.util.SparseArray
+import android.view.View
+import android.widget.RemoteViews
+import com.mikepenz.iconics.IconicsDrawable
+import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
+import com.mikepenz.iconics.utils.colorInt
+import com.mikepenz.iconics.utils.sizeDp
+import pl.szczodrzynski.edziennik.api.v2.events.task.EdziennikTask
+import pl.szczodrzynski.edziennik.data.db.modules.events.Event.TYPE_HOMEWORK
+import pl.szczodrzynski.edziennik.data.db.modules.timetable.Lesson
+import pl.szczodrzynski.edziennik.utils.models.Date
+import pl.szczodrzynski.edziennik.utils.models.ItemWidgetTimetableModel
+import pl.szczodrzynski.edziennik.utils.models.Time
+import pl.szczodrzynski.edziennik.utils.models.Week
+import pl.szczodrzynski.edziennik.widgets.WidgetConfig
+import pl.szczodrzynski.edziennik.widgets.timetable.LessonDialogActivity
+import pl.szczodrzynski.edziennik.widgets.timetable.WidgetTimetableService
+import java.lang.reflect.InvocationTargetException
+
+
+class WidgetTimetable : AppWidgetProvider() {
+
+ override fun onReceive(context: Context, intent: Intent) {
+ if (ACTION_SYNC_DATA == intent.action) {
+ EdziennikTask.sync().enqueue(context)
+ }
+ super.onReceive(context, intent)
+ }
+
+ override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
+ val thisWidget = ComponentName(context, WidgetTimetable::class.java)
+
+ timetables = SparseArray()
+ //timetables.clear();
+
+ val app = context.applicationContext as App
+
+ var bellSyncDiffMillis: Long = 0
+ if (app.appConfig.bellSyncDiff != null) {
+ bellSyncDiffMillis = (app.appConfig.bellSyncDiff.hour * 60 * 60 * 1000 + app.appConfig.bellSyncDiff.minute * 60 * 1000 + app.appConfig.bellSyncDiff.second * 1000).toLong()
+ bellSyncDiffMillis *= app.appConfig.bellSyncMultiplier.toLong()
+ bellSyncDiffMillis *= -1
+ }
+
+ val allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget)
+
+ allWidgetIds?.forEach { appWidgetId ->
+ var widgetConfig = app.appConfig.widgetTimetableConfigs[appWidgetId]
+ if (widgetConfig == null) {
+ widgetConfig = WidgetConfig(app.profileFirstId())
+ app.appConfig.widgetTimetableConfigs[appWidgetId] = widgetConfig
+ app.appConfig.savePending = true
+ }
+
+ val views = if (widgetConfig.bigStyle) {
+ RemoteViews(context.packageName, if (widgetConfig.darkTheme) R.layout.widget_timetable_dark_big else R.layout.widget_timetable_big)
+ } else {
+ RemoteViews(context.packageName, if (widgetConfig.darkTheme) R.layout.widget_timetable_dark else R.layout.widget_timetable)
+ }
+
+ val refreshIntent = Intent(app, WidgetTimetable::class.java)
+ refreshIntent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
+ refreshIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds)
+ val pendingRefreshIntent = PendingIntent.getBroadcast(context,
+ 0, refreshIntent, PendingIntent.FLAG_UPDATE_CURRENT)
+ views.setOnClickPendingIntent(R.id.widgetTimetableRefresh, pendingRefreshIntent)
+
+ views.setOnClickPendingIntent(R.id.widgetTimetableSync, getPendingSelfIntent(context, ACTION_SYNC_DATA))
+
+ views.setImageViewBitmap(R.id.widgetTimetableRefresh, IconicsDrawable(context, CommunityMaterial.Icon2.cmd_refresh)
+ .colorInt(Color.WHITE)
+ .sizeDp(if (widgetConfig.bigStyle) 24 else 16).toBitmap())
+
+ views.setImageViewBitmap(R.id.widgetTimetableSync, IconicsDrawable(context, CommunityMaterial.Icon2.cmd_sync)
+ .colorInt(Color.WHITE)
+ .sizeDp(if (widgetConfig.bigStyle) 24 else 16).toBitmap())
+
+ prepareAppWidget(app, appWidgetId, views, widgetConfig, bellSyncDiffMillis)
+
+ appWidgetManager.updateAppWidget(appWidgetId, views)
+ appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widgetTimetableListView)
+ }
+ }
+
+ private fun prepareAppWidget(
+ app: App,
+ appWidgetId: Int,
+ views: RemoteViews,
+ widgetConfig: WidgetConfig,
+ bellSyncDiffMillis: Long
+ ) {
+ // get the current bell-synced time
+ val now = Time.fromMillis(Time.getNow().inMillis + bellSyncDiffMillis)
+
+ // set the widget transparency
+ val mode = PorterDuff.Mode.DST_IN
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
+ // this code seems to crash the launcher on >= P
+ val transparency = widgetConfig.opacity //0...1
+ val colorFilter = 0x01000000L * (255f * transparency).toLong()
+ try {
+ val declaredMethods = Class.forName("android.widget.RemoteViews").declaredMethods
+ val len = declaredMethods.size
+ if (len > 0) {
+ for (m in 0 until len) {
+ val method = declaredMethods[m]
+ if (method.name == "setDrawableParameters") {
+ method.isAccessible = true
+ method.invoke(views, R.id.widgetTimetableListView, true, -1, colorFilter.toInt(), mode, -1)
+ method.invoke(views, R.id.widgetTimetableHeader, true, -1, colorFilter.toInt(), mode, -1)
+ break
+ }
+ }
+ }
+ } catch (e: ClassNotFoundException) {
+ e.printStackTrace()
+ } catch (e: InvocationTargetException) {
+ e.printStackTrace()
+ } catch (e: IllegalAccessException) {
+ e.printStackTrace()
+ } catch (e: IllegalArgumentException) {
+ e.printStackTrace()
+ }
+ }
+
+ val unified = widgetConfig.profileId == -1
+
+ // get all profiles or one profile with the specified id
+ val profileList = if (unified)
+ app.db.profileDao().allNow.filterOutArchived()
+ else
+ listOfNotNull(app.db.profileDao().getByIdNow(widgetConfig.profileId))
+
+ // no profile was found
+ if (profileList.isEmpty()) {
+ views.setViewVisibility(R.id.widgetTimetableLoading, View.VISIBLE)
+ views.setTextViewText(R.id.widgetTimetableLoading, app.getString(R.string.widget_timetable_profile_doesnt_exist))
+ return
+ }
+
+ views.setViewVisibility(R.id.widgetTimetableLoading, View.GONE)
+
+ // set lesson search bounds
+ val today = Date.getToday()
+ val searchEnd = today.clone().stepForward(0, 0, 7)
+
+ var scrollPos = 0
+
+ var profileId: Int? = null
+ var displayingDate: Date? = null
+
+ val models = mutableListOf()
+
+ // get all lessons within the search bounds
+ val lessonList = app.db.timetableDao().getBetweenDatesNow(today, searchEnd)
+
+ for (profile in profileList) {
+
+ // add a profile separator with its name
+ if (unified) {
+ val separator = ItemWidgetTimetableModel()
+ separator.profileId = profile.id
+ separator.bigStyle = widgetConfig.bigStyle
+ separator.darkTheme = widgetConfig.darkTheme
+ separator.separatorProfileName = profile.name
+ models.add(separator)
+ }
+
+ // search for lessons to display
+ val timetableDate = Date.getToday()
+ var checkedDays = 0
+ var lessons = lessonList.filter { it.profileId == profile.id && it.displayDate == timetableDate }
+ while ((lessons.isEmpty() || lessons.none {
+ it.displayDate != today || (it.displayDate == today && it.displayEndTime != null && it.displayEndTime!! >= now)
+ }) && checkedDays < 7) {
+ timetableDate.stepForward(0, 0, 1)
+ lessons = lessonList.filter { it.profileId == profile.id && it.displayDate == timetableDate }
+ checkedDays++
+ }
+
+ // set the displayingDate to show in the header
+ if (!unified) {
+ if (lessons.isNotEmpty())
+ displayingDate = timetableDate
+ profileId = profile.id
+ }
+
+ // get all events for the current date
+ val events = app.db.eventDao().getAllByDateNow(profile.id, timetableDate)?.filterNotNull() ?: emptyList()
+
+ lessons.forEachIndexed { pos, lesson ->
+ val model = ItemWidgetTimetableModel()
+
+ model.bigStyle = widgetConfig.bigStyle
+ model.darkTheme = widgetConfig.darkTheme
+
+ model.profileId = profile.id
+
+ model.lessonId = lesson.id
+ model.lessonDate = timetableDate
+ model.startTime = lesson.startTime
+ model.endTime = lesson.endTime
+
+ // check if the lesson has already passed or it's currently in progress
+ if (lesson.displayDate == today) {
+ lesson.displayEndTime?.let { endTime ->
+ model.lessonPassed = now > endTime
+ lesson.displayStartTime?.let { startTime ->
+ model.lessonCurrent = now in startTime..endTime
+ }
+ }
+ }
+
+ // set where should the list view scroll to
+ if (model.lessonCurrent) {
+ scrollPos = pos
+ } else if (model.lessonPassed) {
+ scrollPos = pos + 1
+ }
+
+ // set the subject and classroom name
+ model.subjectName = lesson.displaySubjectName
+ model.classroomName = lesson.displayClassroom
+
+ // set the bell sync to calculate progress in ListProvider
+ model.bellSyncDiffMillis = bellSyncDiffMillis
+
+ // make the model aware of the lesson type
+ when (lesson.type) {
+ Lesson.TYPE_CANCELLED -> {
+ model.lessonCancelled = true
+ }
+ Lesson.TYPE_CHANGE,
+ Lesson.TYPE_SHIFTED_SOURCE,
+ Lesson.TYPE_SHIFTED_TARGET -> {
+ model.lessonChange = true
+ }
+ }
+
+ // add every event on this lesson
+ for (event in events) {
+ if (event.startTime != null && event.startTime != lesson.displayStartTime)
+ continue
+ model.eventColors.add(if (event.type == TYPE_HOMEWORK) ItemWidgetTimetableModel.EVENT_COLOR_HOMEWORK else event.getColor())
+ }
+
+ models += model
+ }
+ }
+
+ if (unified) {
+ // set the title for an unified widget
+ views.setTextViewText(R.id.widgetTimetableTitle, app.getString(R.string.widget_timetable_title_unified))
+ views.setViewVisibility(R.id.widgetTimetableSubtitle, View.GONE)
+ } else {
+ // set the title to present the widget's profile
+ views.setTextViewText(R.id.widgetTimetableTitle, profileList[0].name)
+ views.setViewVisibility(R.id.widgetTimetableTitle, View.VISIBLE)
+ // make the subtitle show current date for these lessons
+ displayingDate?.let {
+ when (Date.diffDays(it, Date.getToday())) {
+ 0 -> views.setTextViewText(R.id.widgetTimetableSubtitle, app.getString(R.string.day_today_format, Week.getFullDayName(it.weekDay)))
+ 1 -> views.setTextViewText(R.id.widgetTimetableSubtitle, app.getString(R.string.day_tomorrow_format, Week.getFullDayName(it.weekDay)))
+ else -> views.setTextViewText(R.id.widgetTimetableSubtitle, Week.getFullDayName(it.weekDay) + " " + it.formattedString)
+ }
+ }
+ }
+
+ // intent running when the header is clicked
+ val openIntent = Intent(app, MainActivity::class.java)
+ openIntent.action = "android.intent.action.MAIN"
+ if (!unified) {
+ // per-profile widget should redirect to it + correct day
+ profileId?.let {
+ openIntent.putExtra("profileId", it)
+ }
+ displayingDate?.let {
+ openIntent.putExtra("timetableDate", it.value)
+ }
+ }
+ openIntent.putExtra("fragmentId", MainActivity.DRAWER_ITEM_TIMETABLE)
+ val pendingOpenIntent = PendingIntent.getActivity(app, appWidgetId, openIntent, 0)
+ views.setOnClickPendingIntent(R.id.widgetTimetableHeader, pendingOpenIntent)
+
+ if (lessonList.isEmpty()) {
+ views.setViewVisibility(R.id.widgetTimetableLoading, View.VISIBLE)
+ views.setRemoteAdapter(R.id.widgetTimetableListView, Intent())
+ views.setTextViewText(R.id.widgetTimetableLoading, app.getString(R.string.widget_timetable_no_lessons))
+ return
+ }
+
+ timetables!!.put(appWidgetId, models)
+
+ // apply the list service to the list view
+ val listIntent = Intent(app, WidgetTimetableService::class.java)
+ listIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
+ listIntent.data = Uri.parse(listIntent.toUri(Intent.URI_INTENT_SCHEME))
+ views.setRemoteAdapter(R.id.widgetTimetableListView, listIntent)
+
+ // create an intent used to display the lesson details dialog
+ val intentTemplate = Intent(app, LessonDialogActivity::class.java)
+ intentTemplate.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
+ val pendingIntentTimetable = PendingIntent.getActivity(app, appWidgetId, intentTemplate, 0)
+ views.setPendingIntentTemplate(R.id.widgetTimetableListView, pendingIntentTimetable)
+
+ if (!unified)
+ views.setScrollPosition(R.id.widgetTimetableListView, scrollPos)
+ }
+
+ override fun onEnabled(context: Context) {
+ // Enter relevant functionality for when the first widget is created
+ }
+
+ override fun onDeleted(context: Context, appWidgetIds: IntArray) {
+ val app = context.applicationContext as App
+ for (appWidgetId in appWidgetIds) {
+ app.appConfig.widgetTimetableConfigs.remove(appWidgetId)
+ }
+ app.saveConfig("widgetTimetableConfigs")
+ }
+
+ companion object {
+
+
+ val ACTION_SYNC_DATA = "ACTION_SYNC_DATA"
+ private val TAG = "WidgetTimetable"
+ private val modeInt = 0
+
+ var timetables: SparseArray>? = null
+
+ fun getPendingSelfIntent(context: Context, action: String): PendingIntent {
+ val intent = Intent(context, WidgetTimetable::class.java)
+ intent.action = action
+ return getPendingSelfIntent(context, intent)
+ }
+
+ fun getPendingSelfIntent(context: Context, intent: Intent): PendingIntent {
+ return PendingIntent.getBroadcast(context, 0, intent, 0)
+ }
+
+ fun drawableToBitmap(drawable: Drawable): Bitmap {
+
+ if (drawable is BitmapDrawable) {
+ return drawable.bitmap
+ }
+
+ val bitmap = Bitmap.createBitmap(drawable.intrinsicWidth, drawable.intrinsicHeight, Bitmap.Config.ARGB_8888)
+ val canvas = Canvas(bitmap)
+ drawable.setBounds(0, 0, canvas.width, canvas.height)
+ drawable.draw(canvas)
+
+ return bitmap
+ }
+ }
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/modules/timetable/TimetableDao.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/modules/timetable/TimetableDao.kt
index fc566ac5..14db6253 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/modules/timetable/TimetableDao.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/modules/timetable/TimetableDao.kt
@@ -10,6 +10,27 @@ import pl.szczodrzynski.edziennik.utils.models.Date
@Dao
interface TimetableDao {
+ companion object {
+ private const val QUERY = """
+ SELECT
+ timetable.*,
+ subjects.subjectLongName AS subjectName,
+ teachers.teacherName ||" "|| teachers.teacherSurname AS teacherName,
+ teams.teamName AS teamName,
+ oldS.subjectLongName AS oldSubjectName,
+ oldT.teacherName ||" "|| oldT.teacherSurname AS oldTeacherName,
+ oldG.teamName AS oldTeamName,
+ metadata.seen, metadata.notified, metadata.addedDate
+ FROM timetable
+ LEFT JOIN subjects USING(profileId, subjectId)
+ LEFT JOIN teachers USING(profileId, teacherId)
+ LEFT JOIN teams USING(profileId, teamId)
+ LEFT JOIN subjects AS oldS ON timetable.profileId = oldS.profileId AND timetable.oldSubjectId = oldS.subjectId
+ LEFT JOIN teachers AS oldT ON timetable.profileId = oldT.profileId AND timetable.oldTeacherId = oldT.teacherId
+ LEFT JOIN teams AS oldG ON timetable.profileId = oldG.profileId AND timetable.oldTeamId = oldG.teamId
+ LEFT JOIN metadata ON id = thingId AND thingType = ${Metadata.TYPE_LESSON_CHANGE} AND metadata.profileId = timetable.profileId
+ """
+ }
@Insert(onConflict = OnConflictStrategy.REPLACE)
operator fun plusAssign(lessonList: List)
@@ -25,49 +46,31 @@ interface TimetableDao {
fun clearBetweenDates(profileId: Int, dateFrom: Date, dateTo: Date)
@Query("""
- SELECT
- timetable.*,
- subjects.subjectLongName AS subjectName,
- teachers.teacherName ||" "|| teachers.teacherSurname AS teacherName,
- teams.teamName AS teamName,
- oldS.subjectLongName AS oldSubjectName,
- oldT.teacherName ||" "|| oldT.teacherSurname AS oldTeacherName,
- oldG.teamName AS oldTeamName,
- metadata.seen, metadata.notified, metadata.addedDate
- FROM timetable
- LEFT JOIN subjects USING(profileId, subjectId)
- LEFT JOIN teachers USING(profileId, teacherId)
- LEFT JOIN teams USING(profileId, teamId)
- LEFT JOIN subjects AS oldS ON timetable.profileId = oldS.profileId AND timetable.oldSubjectId = oldS.subjectId
- LEFT JOIN teachers AS oldT ON timetable.profileId = oldT.profileId AND timetable.oldTeacherId = oldT.teacherId
- LEFT JOIN teams AS oldG ON timetable.profileId = oldG.profileId AND timetable.oldTeamId = oldG.teamId
- LEFT JOIN metadata ON id = thingId AND thingType = ${Metadata.TYPE_LESSON_CHANGE} AND metadata.profileId = timetable.profileId
+ $QUERY
WHERE timetable.profileId = :profileId AND (type != 3 AND date = :date) OR ((type = 3 OR type = 1) AND oldDate = :date)
ORDER BY id, type
""")
fun getForDate(profileId: Int, date: Date) : LiveData>
@Query("""
- SELECT
- timetable.*,
- subjects.subjectLongName AS subjectName,
- teachers.teacherName ||" "|| teachers.teacherSurname AS teacherName,
- teams.teamName AS teamName,
- oldS.subjectLongName AS oldSubjectName,
- oldT.teacherName ||" "|| oldT.teacherSurname AS oldTeacherName,
- oldG.teamName AS oldTeamName,
- metadata.seen, metadata.notified, metadata.addedDate
- FROM timetable
- LEFT JOIN subjects USING(profileId, subjectId)
- LEFT JOIN teachers USING(profileId, teacherId)
- LEFT JOIN teams USING(profileId, teamId)
- LEFT JOIN subjects AS oldS ON timetable.profileId = oldS.profileId AND timetable.oldSubjectId = oldS.subjectId
- LEFT JOIN teachers AS oldT ON timetable.profileId = oldT.profileId AND timetable.oldTeacherId = oldT.teacherId
- LEFT JOIN teams AS oldG ON timetable.profileId = oldG.profileId AND timetable.oldTeamId = oldG.teamId
- LEFT JOIN metadata ON id = thingId AND thingType = ${Metadata.TYPE_LESSON_CHANGE} AND metadata.profileId = timetable.profileId
+ $QUERY
WHERE timetable.profileId = :profileId AND ((type != 3 AND date > :today) OR ((type = 3 OR type = 1) AND oldDate > :today)) AND timetable.subjectId = :subjectId
ORDER BY id, type
LIMIT 1
""")
fun getNextWithSubject(profileId: Int, today: Date, subjectId: Long) : LiveData
+
+ @Query("""
+ $QUERY
+ WHERE (type != 3 AND date >= :dateFrom AND date <= :dateTo) OR ((type = 3 OR type = 1) AND oldDate >= :dateFrom AND oldDate <= :dateTo)
+ ORDER BY profileId, id, type
+ """)
+ fun getBetweenDatesNow(dateFrom: Date, dateTo: Date) : List
+
+ @Query("""
+ $QUERY
+ WHERE timetable.profileId = :profileId AND timetable.id = :lessonId
+ ORDER BY id, type
+ """)
+ fun getByIdNow(profileId: Int, lessonId: Long) : LessonFull?
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/event/EventManualV2Dialog.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/event/EventManualV2Dialog.kt
index 64644fb7..faaab700 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/event/EventManualV2Dialog.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/event/EventManualV2Dialog.kt
@@ -30,7 +30,9 @@ class EventManualV2Dialog(
val defaultDate: Date? = null,
val defaultTime: Time? = null,
val defaultType: Int? = null,
- val editingEvent: Event? = null
+ val editingEvent: Event? = null,
+ val onShowListener: ((tag: String) -> Unit)? = null,
+ val onDismissListener: ((tag: String) -> Unit)? = null
) : CoroutineScope {
companion object {
@@ -49,13 +51,16 @@ class EventManualV2Dialog(
init { run {
job = Job()
-
+ onShowListener?.invoke(TAG)
b = DialogEventManualV2Binding.inflate(activity.layoutInflater)
dialog = MaterialAlertDialogBuilder(activity)
.setTitle(R.string.dialog_event_manual_title)
.setView(b.root)
.setNegativeButton(R.string.cancel) { dialog, _ -> dialog.dismiss() }
.setPositiveButton(R.string.save) { _, _ -> saveEvent() }
+ .setOnDismissListener {
+ onDismissListener?.invoke(TAG)
+ }
.show()
event = editingEvent?.clone() ?: Event().also { event ->
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/timetable/LessonDetailsDialog.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/timetable/LessonDetailsDialog.kt
index 325cf419..2ad4557b 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/timetable/LessonDetailsDialog.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/timetable/LessonDetailsDialog.kt
@@ -21,7 +21,9 @@ import pl.szczodrzynski.edziennik.utils.models.Week
class LessonDetailsDialog(
val activity: AppCompatActivity,
- val lesson: LessonFull
+ val lesson: LessonFull,
+ val onShowListener: ((tag: String) -> Unit)? = null,
+ val onDismissListener: ((tag: String) -> Unit)? = null
) {
companion object {
private const val TAG = "LessonDetailsDialog"
@@ -31,6 +33,7 @@ class LessonDetailsDialog(
private lateinit var dialog: AlertDialog
init { run {
+ onShowListener?.invoke(TAG)
b = DialogLessonDetailsBinding.inflate(activity.layoutInflater)
dialog = MaterialAlertDialogBuilder(activity)
.setView(b.root)
@@ -38,8 +41,13 @@ class LessonDetailsDialog(
dialog.dismiss()
}
.setNeutralButton(R.string.add) { dialog, _ ->
- dialog.dismiss()
- EventManualV2Dialog(activity, lesson.profileId, lesson)
+ EventManualV2Dialog(
+ activity,
+ lesson.profileId,
+ lesson,
+ onShowListener = onShowListener,
+ onDismissListener = onDismissListener
+ )
/*MaterialAlertDialogBuilder(activity)
.setItems(R.array.main_menu_add_options) { dialog2, which ->
dialog2.dismiss()
@@ -59,6 +67,9 @@ class LessonDetailsDialog(
.setNegativeButton(R.string.cancel) { dialog2, _ -> dialog2.dismiss() }
.show()*/
}
+ .setOnDismissListener {
+ onDismissListener?.invoke(TAG)
+ }
.show()
update()
}}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/utils/models/ItemWidgetTimetableModel.java b/app/src/main/java/pl/szczodrzynski/edziennik/utils/models/ItemWidgetTimetableModel.java
index 479845da..0ddd210a 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/utils/models/ItemWidgetTimetableModel.java
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/utils/models/ItemWidgetTimetableModel.java
@@ -9,6 +9,7 @@ public class ItemWidgetTimetableModel {
public String separatorProfileName = null;
public int profileId;
+ public long lessonId;
public Date lessonDate;
public Time startTime;
public Time endTime;
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/widgets/WidgetConfigActivity.java b/app/src/main/java/pl/szczodrzynski/edziennik/widgets/WidgetConfigActivity.java
index 4004109c..38d2814d 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/widgets/WidgetConfigActivity.java
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/widgets/WidgetConfigActivity.java
@@ -21,8 +21,8 @@ import java.util.List;
import pl.szczodrzynski.edziennik.App;
import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.WidgetTimetable;
-import pl.szczodrzynski.edziennik.databinding.DialogWidgetConfigBinding;
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile;
+import pl.szczodrzynski.edziennik.databinding.DialogWidgetConfigBinding;
import pl.szczodrzynski.edziennik.widgets.luckynumber.WidgetLuckyNumber;
import pl.szczodrzynski.edziennik.widgets.notifications.WidgetNotifications;
@@ -78,7 +78,7 @@ public class WidgetConfigActivity extends Activity {
AsyncTask.execute(() -> {
profileList = app.db.profileDao().getAllNow();
- filterOutArchived(profileList);
+ profileList = filterOutArchived(profileList);
if (widgetType == WIDGET_NOTIFICATIONS)
this.runOnUiThread(this::configure);
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/widgets/timetable/LessonDialogActivity.kt b/app/src/main/java/pl/szczodrzynski/edziennik/widgets/timetable/LessonDialogActivity.kt
new file mode 100644
index 00000000..fd118390
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/widgets/timetable/LessonDialogActivity.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2019-11-14.
+ */
+
+package pl.szczodrzynski.edziennik.widgets.timetable
+
+import android.content.Intent
+import android.content.Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
+import android.graphics.drawable.ColorDrawable
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import kotlinx.coroutines.*
+import pl.szczodrzynski.edziennik.App
+import pl.szczodrzynski.edziennik.MainActivity
+import pl.szczodrzynski.edziennik.ui.dialogs.timetable.LessonDetailsDialog
+import pl.szczodrzynski.edziennik.utils.Themes
+import kotlin.coroutines.CoroutineContext
+
+class LessonDialogActivity : AppCompatActivity(), CoroutineScope {
+ companion object {
+ private const val TAG = "LessonDialogActivity"
+ }
+
+ private lateinit var job: Job
+ override val coroutineContext: CoroutineContext
+ get() = job + Dispatchers.Main
+
+ private val shownDialogs = hashSetOf()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ window.setBackgroundDrawable(ColorDrawable(0))
+
+ job = Job()
+
+ setTheme(Themes.appThemeNoDisplay)
+
+ val app = application as App
+ launch {
+ val deferred = async(Dispatchers.Default) {
+ val extras = intent?.extras
+
+ val profileId = extras?.getInt("profileId") ?: return@async null
+
+ if (extras.getBoolean("separatorItem", false)) {
+ val i = Intent(app, MainActivity::class.java)
+ .putExtra("fragmentId", MainActivity.DRAWER_ITEM_TIMETABLE)
+ .putExtra("profileId", profileId)
+ .addFlags(FLAG_ACTIVITY_REORDER_TO_FRONT)
+ app.startActivity(i)
+ finish()
+ return@async null
+ }
+
+ val lessonId = extras.getLong("lessonId")
+
+ app.db.timetableDao().getByIdNow(profileId, lessonId)
+ }
+ val lesson = deferred.await()
+ lesson?.let {
+ LessonDetailsDialog(
+ this@LessonDialogActivity,
+ lesson,
+ onShowListener = { tag ->
+ shownDialogs.add(tag)
+ },
+ onDismissListener = { tag ->
+ shownDialogs.remove(tag)
+ if (shownDialogs.isEmpty())
+ finish()
+ }
+ )
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/widgets/timetable/WidgetTimetableListProvider.java b/app/src/main/java/pl/szczodrzynski/edziennik/widgets/timetable/WidgetTimetableListProvider.java
index 2872c15f..83881d8d 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/widgets/timetable/WidgetTimetableListProvider.java
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/widgets/timetable/WidgetTimetableListProvider.java
@@ -12,13 +12,14 @@ import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
-import androidx.annotation.DrawableRes;
import android.text.Html;
import android.util.Log;
import android.view.View;
import android.widget.RemoteViews;
import android.widget.RemoteViewsService;
+import androidx.annotation.DrawableRes;
+
import com.mikepenz.iconics.IconicsColor;
import com.mikepenz.iconics.IconicsDrawable;
import com.mikepenz.iconics.IconicsSize;
@@ -62,7 +63,7 @@ public class WidgetTimetableListProvider implements RemoteViewsService.RemoteVie
public void onDataSetChanged() {
// executed EVERY TIME
Log.d(TAG, "onDataSetChanged for appWidgetId: "+appWidgetId);
- lessons = WidgetTimetable.timetables == null ? null : WidgetTimetable.timetables.get(appWidgetId);
+ lessons = WidgetTimetable.Companion.getTimetables() == null ? null : WidgetTimetable.Companion.getTimetables().get(appWidgetId);
}
@Override
@@ -163,9 +164,13 @@ public class WidgetTimetableListProvider implements RemoteViewsService.RemoteVie
Intent intent = new Intent();
intent.putExtra("profileId", lesson.profileId);
- intent.putExtra("date", lesson.lessonDate.getStringValue());
- intent.putExtra("startTime", lesson.startTime.getStringValue());
- intent.putExtra("endTime", lesson.endTime.getStringValue());
+ intent.putExtra("lessonId", lesson.lessonId);
+ if (lesson.lessonDate != null)
+ intent.putExtra("date", lesson.lessonDate.getStringValue());
+ if (lesson.startTime != null)
+ intent.putExtra("startTime", lesson.startTime.getStringValue());
+ if (lesson.endTime != null)
+ intent.putExtra("endTime", lesson.endTime.getStringValue());
views.setOnClickFillInIntent(R.id.widgetTimetableRoot, intent);
views.setTextViewText(R.id.widgetTimetableTime, lesson.startTime.getStringHM() + " - " + lesson.endTime.getStringHM());
@@ -239,30 +244,18 @@ public class WidgetTimetableListProvider implements RemoteViewsService.RemoteVie
}
}
}
- //views.setViewVisibility(R.id.widgetTimetableEvent1, View.VISIBLE);
- //views.setBitmap(R.id.widgetTimetableEvent1, "setImageBitmap", getColoredBitmap(context, R.drawable.event_color_circle, 0xff4caf50, eventIndicatorSize, eventIndicatorSize));
+
+ if (lesson.subjectName == null) {
+ lesson.subjectName = context.getString(R.string.timetable_no_subject_name);
+ }
+ if (lesson.classroomName == null) {
+ lesson.classroomName = context.getString(R.string.timetable_no_classroom);
+ }
views.setViewVisibility(R.id.widgetTimetableOldSubjectName, View.GONE);
if (lesson.lessonChange) {
- if (lesson.newSubjectName == null) {
- views.setTextViewText(R.id.widgetTimetableSubjectName, Html.fromHtml(""+lesson.subjectName+""));
- }
- else {
- views.setViewVisibility(R.id.widgetTimetableOldSubjectName, View.VISIBLE);
- views.setTextViewText(R.id.widgetTimetableOldSubjectName, Html.fromHtml(""+lesson.subjectName+""));
- views.setTextViewText(R.id.widgetTimetableSubjectName, lesson.newSubjectName);
- }
-
- if (lesson.newClassroomName == null) {
- if (lesson.classroomName == null || lesson.classroomName.equals("")) {
- lesson.classroomName = context.getString(R.string.timetable_no_classroom);
- }
- views.setTextViewText(R.id.widgetTimetableClassroomName, lesson.classroomName);
- }
- else {
- views.setTextViewText(R.id.widgetTimetableClassroomName, Html.fromHtml(""+lesson.newClassroomName+""));
- }
-
+ views.setTextViewText(R.id.widgetTimetableSubjectName, Html.fromHtml(""+lesson.subjectName+""));
+ views.setTextViewText(R.id.widgetTimetableClassroomName, Html.fromHtml(""+lesson.classroomName+""));
}
else if (lesson.lessonCancelled) {
views.setTextViewText(R.id.widgetTimetableSubjectName, Html.fromHtml(""+lesson.subjectName+""));
@@ -272,7 +265,6 @@ public class WidgetTimetableListProvider implements RemoteViewsService.RemoteVie
views.setTextViewText(R.id.widgetTimetableSubjectName, lesson.subjectName);
views.setTextViewText(R.id.widgetTimetableClassroomName, lesson.classroomName);
}
-
}
else if (!triedToReload) {
// try to reload the widget
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 936cf55e..95ff61c1 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1025,4 +1025,5 @@
Profil został usunięty.
Wystąpił błąd
Synchronizacja ręczna
+ (brak nazwy)