mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-01-18 21:06:44 -06:00
[Widget] Add new Timetable widget with APIv2.
This commit is contained in:
parent
56062f5bfa
commit
dbdfc7fdd8
@ -105,6 +105,11 @@
|
|||||||
android:excludeFromRecents="true"
|
android:excludeFromRecents="true"
|
||||||
android:noHistory="true"
|
android:noHistory="true"
|
||||||
android:theme="@style/AppTheme.NoDisplay" />
|
android:theme="@style/AppTheme.NoDisplay" />
|
||||||
|
<activity android:name=".widgets.timetable.LessonDialogActivity"
|
||||||
|
android:configChanges="orientation|keyboardHidden"
|
||||||
|
android:excludeFromRecents="true"
|
||||||
|
android:noHistory="true"
|
||||||
|
android:theme="@style/AppTheme.NoDisplay" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.modules.settings.SettingsLicenseActivity"
|
android:name=".ui.modules.settings.SettingsLicenseActivity"
|
||||||
android:configChanges="orientation|keyboardHidden"
|
android:configChanges="orientation|keyboardHidden"
|
||||||
|
@ -162,8 +162,9 @@ fun colorFromName(context: Context, name: String?): Int {
|
|||||||
return context.getColorFromRes(color)
|
return context.getColorFromRes(color)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun MutableList<out Profile>.filterOutArchived() {
|
fun MutableList<Profile>.filterOutArchived(): MutableList<Profile> {
|
||||||
this.removeAll { it.archived }
|
this.removeAll { it.archived }
|
||||||
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Activity.isStoragePermissionGranted(): Boolean {
|
fun Activity.isStoragePermissionGranted(): Boolean {
|
||||||
|
@ -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<List<ItemWidgetTimetableModel>> 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<Profile> 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<ItemWidgetTimetableModel> 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<LessonFull> 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<EventFull> 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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
371
app/src/main/java/pl/szczodrzynski/edziennik/WidgetTimetable.kt
Normal file
371
app/src/main/java/pl/szczodrzynski/edziennik/WidgetTimetable.kt
Normal file
@ -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<ItemWidgetTimetableModel>()
|
||||||
|
|
||||||
|
// 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<List<ItemWidgetTimetableModel>>? = 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,27 @@ import pl.szczodrzynski.edziennik.utils.models.Date
|
|||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface TimetableDao {
|
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)
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
operator fun plusAssign(lessonList: List<Lesson>)
|
operator fun plusAssign(lessonList: List<Lesson>)
|
||||||
@ -25,49 +46,31 @@ interface TimetableDao {
|
|||||||
fun clearBetweenDates(profileId: Int, dateFrom: Date, dateTo: Date)
|
fun clearBetweenDates(profileId: Int, dateFrom: Date, dateTo: Date)
|
||||||
|
|
||||||
@Query("""
|
@Query("""
|
||||||
SELECT
|
$QUERY
|
||||||
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
|
|
||||||
WHERE timetable.profileId = :profileId AND (type != 3 AND date = :date) OR ((type = 3 OR type = 1) AND oldDate = :date)
|
WHERE timetable.profileId = :profileId AND (type != 3 AND date = :date) OR ((type = 3 OR type = 1) AND oldDate = :date)
|
||||||
ORDER BY id, type
|
ORDER BY id, type
|
||||||
""")
|
""")
|
||||||
fun getForDate(profileId: Int, date: Date) : LiveData<List<LessonFull>>
|
fun getForDate(profileId: Int, date: Date) : LiveData<List<LessonFull>>
|
||||||
|
|
||||||
@Query("""
|
@Query("""
|
||||||
SELECT
|
$QUERY
|
||||||
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
|
|
||||||
WHERE timetable.profileId = :profileId AND ((type != 3 AND date > :today) OR ((type = 3 OR type = 1) AND oldDate > :today)) AND timetable.subjectId = :subjectId
|
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
|
ORDER BY id, type
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
""")
|
""")
|
||||||
fun getNextWithSubject(profileId: Int, today: Date, subjectId: Long) : LiveData<LessonFull>
|
fun getNextWithSubject(profileId: Int, today: Date, subjectId: Long) : LiveData<LessonFull>
|
||||||
|
|
||||||
|
@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<LessonFull>
|
||||||
|
|
||||||
|
@Query("""
|
||||||
|
$QUERY
|
||||||
|
WHERE timetable.profileId = :profileId AND timetable.id = :lessonId
|
||||||
|
ORDER BY id, type
|
||||||
|
""")
|
||||||
|
fun getByIdNow(profileId: Int, lessonId: Long) : LessonFull?
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,9 @@ class EventManualV2Dialog(
|
|||||||
val defaultDate: Date? = null,
|
val defaultDate: Date? = null,
|
||||||
val defaultTime: Time? = null,
|
val defaultTime: Time? = null,
|
||||||
val defaultType: Int? = 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 {
|
) : CoroutineScope {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@ -49,13 +51,16 @@ class EventManualV2Dialog(
|
|||||||
|
|
||||||
init { run {
|
init { run {
|
||||||
job = Job()
|
job = Job()
|
||||||
|
onShowListener?.invoke(TAG)
|
||||||
b = DialogEventManualV2Binding.inflate(activity.layoutInflater)
|
b = DialogEventManualV2Binding.inflate(activity.layoutInflater)
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
dialog = MaterialAlertDialogBuilder(activity)
|
||||||
.setTitle(R.string.dialog_event_manual_title)
|
.setTitle(R.string.dialog_event_manual_title)
|
||||||
.setView(b.root)
|
.setView(b.root)
|
||||||
.setNegativeButton(R.string.cancel) { dialog, _ -> dialog.dismiss() }
|
.setNegativeButton(R.string.cancel) { dialog, _ -> dialog.dismiss() }
|
||||||
.setPositiveButton(R.string.save) { _, _ -> saveEvent() }
|
.setPositiveButton(R.string.save) { _, _ -> saveEvent() }
|
||||||
|
.setOnDismissListener {
|
||||||
|
onDismissListener?.invoke(TAG)
|
||||||
|
}
|
||||||
.show()
|
.show()
|
||||||
|
|
||||||
event = editingEvent?.clone() ?: Event().also { event ->
|
event = editingEvent?.clone() ?: Event().also { event ->
|
||||||
|
@ -21,7 +21,9 @@ import pl.szczodrzynski.edziennik.utils.models.Week
|
|||||||
|
|
||||||
class LessonDetailsDialog(
|
class LessonDetailsDialog(
|
||||||
val activity: AppCompatActivity,
|
val activity: AppCompatActivity,
|
||||||
val lesson: LessonFull
|
val lesson: LessonFull,
|
||||||
|
val onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
|
val onDismissListener: ((tag: String) -> Unit)? = null
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "LessonDetailsDialog"
|
private const val TAG = "LessonDetailsDialog"
|
||||||
@ -31,6 +33,7 @@ class LessonDetailsDialog(
|
|||||||
private lateinit var dialog: AlertDialog
|
private lateinit var dialog: AlertDialog
|
||||||
|
|
||||||
init { run {
|
init { run {
|
||||||
|
onShowListener?.invoke(TAG)
|
||||||
b = DialogLessonDetailsBinding.inflate(activity.layoutInflater)
|
b = DialogLessonDetailsBinding.inflate(activity.layoutInflater)
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
dialog = MaterialAlertDialogBuilder(activity)
|
||||||
.setView(b.root)
|
.setView(b.root)
|
||||||
@ -38,8 +41,13 @@ class LessonDetailsDialog(
|
|||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}
|
}
|
||||||
.setNeutralButton(R.string.add) { dialog, _ ->
|
.setNeutralButton(R.string.add) { dialog, _ ->
|
||||||
dialog.dismiss()
|
EventManualV2Dialog(
|
||||||
EventManualV2Dialog(activity, lesson.profileId, lesson)
|
activity,
|
||||||
|
lesson.profileId,
|
||||||
|
lesson,
|
||||||
|
onShowListener = onShowListener,
|
||||||
|
onDismissListener = onDismissListener
|
||||||
|
)
|
||||||
/*MaterialAlertDialogBuilder(activity)
|
/*MaterialAlertDialogBuilder(activity)
|
||||||
.setItems(R.array.main_menu_add_options) { dialog2, which ->
|
.setItems(R.array.main_menu_add_options) { dialog2, which ->
|
||||||
dialog2.dismiss()
|
dialog2.dismiss()
|
||||||
@ -59,6 +67,9 @@ class LessonDetailsDialog(
|
|||||||
.setNegativeButton(R.string.cancel) { dialog2, _ -> dialog2.dismiss() }
|
.setNegativeButton(R.string.cancel) { dialog2, _ -> dialog2.dismiss() }
|
||||||
.show()*/
|
.show()*/
|
||||||
}
|
}
|
||||||
|
.setOnDismissListener {
|
||||||
|
onDismissListener?.invoke(TAG)
|
||||||
|
}
|
||||||
.show()
|
.show()
|
||||||
update()
|
update()
|
||||||
}}
|
}}
|
||||||
|
@ -9,6 +9,7 @@ public class ItemWidgetTimetableModel {
|
|||||||
public String separatorProfileName = null;
|
public String separatorProfileName = null;
|
||||||
|
|
||||||
public int profileId;
|
public int profileId;
|
||||||
|
public long lessonId;
|
||||||
public Date lessonDate;
|
public Date lessonDate;
|
||||||
public Time startTime;
|
public Time startTime;
|
||||||
public Time endTime;
|
public Time endTime;
|
||||||
|
@ -21,8 +21,8 @@ import java.util.List;
|
|||||||
import pl.szczodrzynski.edziennik.App;
|
import pl.szczodrzynski.edziennik.App;
|
||||||
import pl.szczodrzynski.edziennik.R;
|
import pl.szczodrzynski.edziennik.R;
|
||||||
import pl.szczodrzynski.edziennik.WidgetTimetable;
|
import pl.szczodrzynski.edziennik.WidgetTimetable;
|
||||||
import pl.szczodrzynski.edziennik.databinding.DialogWidgetConfigBinding;
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile;
|
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.luckynumber.WidgetLuckyNumber;
|
||||||
import pl.szczodrzynski.edziennik.widgets.notifications.WidgetNotifications;
|
import pl.szczodrzynski.edziennik.widgets.notifications.WidgetNotifications;
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ public class WidgetConfigActivity extends Activity {
|
|||||||
|
|
||||||
AsyncTask.execute(() -> {
|
AsyncTask.execute(() -> {
|
||||||
profileList = app.db.profileDao().getAllNow();
|
profileList = app.db.profileDao().getAllNow();
|
||||||
filterOutArchived(profileList);
|
profileList = filterOutArchived(profileList);
|
||||||
|
|
||||||
if (widgetType == WIDGET_NOTIFICATIONS)
|
if (widgetType == WIDGET_NOTIFICATIONS)
|
||||||
this.runOnUiThread(this::configure);
|
this.runOnUiThread(this::configure);
|
||||||
|
@ -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<String>()
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -12,13 +12,14 @@ import android.graphics.Paint;
|
|||||||
import android.graphics.PorterDuff;
|
import android.graphics.PorterDuff;
|
||||||
import android.graphics.PorterDuffColorFilter;
|
import android.graphics.PorterDuffColorFilter;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import androidx.annotation.DrawableRes;
|
|
||||||
import android.text.Html;
|
import android.text.Html;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.RemoteViews;
|
import android.widget.RemoteViews;
|
||||||
import android.widget.RemoteViewsService;
|
import android.widget.RemoteViewsService;
|
||||||
|
|
||||||
|
import androidx.annotation.DrawableRes;
|
||||||
|
|
||||||
import com.mikepenz.iconics.IconicsColor;
|
import com.mikepenz.iconics.IconicsColor;
|
||||||
import com.mikepenz.iconics.IconicsDrawable;
|
import com.mikepenz.iconics.IconicsDrawable;
|
||||||
import com.mikepenz.iconics.IconicsSize;
|
import com.mikepenz.iconics.IconicsSize;
|
||||||
@ -62,7 +63,7 @@ public class WidgetTimetableListProvider implements RemoteViewsService.RemoteVie
|
|||||||
public void onDataSetChanged() {
|
public void onDataSetChanged() {
|
||||||
// executed EVERY TIME
|
// executed EVERY TIME
|
||||||
Log.d(TAG, "onDataSetChanged for appWidgetId: "+appWidgetId);
|
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
|
@Override
|
||||||
@ -163,8 +164,12 @@ public class WidgetTimetableListProvider implements RemoteViewsService.RemoteVie
|
|||||||
|
|
||||||
Intent intent = new Intent();
|
Intent intent = new Intent();
|
||||||
intent.putExtra("profileId", lesson.profileId);
|
intent.putExtra("profileId", lesson.profileId);
|
||||||
|
intent.putExtra("lessonId", lesson.lessonId);
|
||||||
|
if (lesson.lessonDate != null)
|
||||||
intent.putExtra("date", lesson.lessonDate.getStringValue());
|
intent.putExtra("date", lesson.lessonDate.getStringValue());
|
||||||
|
if (lesson.startTime != null)
|
||||||
intent.putExtra("startTime", lesson.startTime.getStringValue());
|
intent.putExtra("startTime", lesson.startTime.getStringValue());
|
||||||
|
if (lesson.endTime != null)
|
||||||
intent.putExtra("endTime", lesson.endTime.getStringValue());
|
intent.putExtra("endTime", lesson.endTime.getStringValue());
|
||||||
views.setOnClickFillInIntent(R.id.widgetTimetableRoot, intent);
|
views.setOnClickFillInIntent(R.id.widgetTimetableRoot, intent);
|
||||||
|
|
||||||
@ -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);
|
views.setViewVisibility(R.id.widgetTimetableOldSubjectName, View.GONE);
|
||||||
if (lesson.lessonChange) {
|
if (lesson.lessonChange) {
|
||||||
if (lesson.newSubjectName == null) {
|
|
||||||
views.setTextViewText(R.id.widgetTimetableSubjectName, Html.fromHtml("<i>"+lesson.subjectName+"</i>"));
|
views.setTextViewText(R.id.widgetTimetableSubjectName, Html.fromHtml("<i>"+lesson.subjectName+"</i>"));
|
||||||
}
|
views.setTextViewText(R.id.widgetTimetableClassroomName, Html.fromHtml("<i>"+lesson.classroomName+"</i>"));
|
||||||
else {
|
|
||||||
views.setViewVisibility(R.id.widgetTimetableOldSubjectName, View.VISIBLE);
|
|
||||||
views.setTextViewText(R.id.widgetTimetableOldSubjectName, Html.fromHtml("<del>"+lesson.subjectName+"</del>"));
|
|
||||||
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("<i>"+lesson.newClassroomName+"</i>"));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (lesson.lessonCancelled) {
|
else if (lesson.lessonCancelled) {
|
||||||
views.setTextViewText(R.id.widgetTimetableSubjectName, Html.fromHtml("<del>"+lesson.subjectName+"</del>"));
|
views.setTextViewText(R.id.widgetTimetableSubjectName, Html.fromHtml("<del>"+lesson.subjectName+"</del>"));
|
||||||
@ -272,7 +265,6 @@ public class WidgetTimetableListProvider implements RemoteViewsService.RemoteVie
|
|||||||
views.setTextViewText(R.id.widgetTimetableSubjectName, lesson.subjectName);
|
views.setTextViewText(R.id.widgetTimetableSubjectName, lesson.subjectName);
|
||||||
views.setTextViewText(R.id.widgetTimetableClassroomName, lesson.classroomName);
|
views.setTextViewText(R.id.widgetTimetableClassroomName, lesson.classroomName);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (!triedToReload) {
|
else if (!triedToReload) {
|
||||||
// try to reload the widget
|
// try to reload the widget
|
||||||
|
@ -1025,4 +1025,5 @@
|
|||||||
<string name="dialog_profile_remove_success">Profil został usunięty.</string>
|
<string name="dialog_profile_remove_success">Profil został usunięty.</string>
|
||||||
<string name="snackbar_error_text">Wystąpił błąd</string>
|
<string name="snackbar_error_text">Wystąpił błąd</string>
|
||||||
<string name="dialog_sync_view_list_title">Synchronizacja ręczna</string>
|
<string name="dialog_sync_view_list_title">Synchronizacja ręczna</string>
|
||||||
|
<string name="timetable_no_subject_name">(brak nazwy)</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user