diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt b/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt index d1faa9d2..da39314c 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt @@ -45,13 +45,14 @@ import pl.szczodrzynski.edziennik.network.ServerRequest import pl.szczodrzynski.edziennik.sync.AppManagerDetectedEvent import pl.szczodrzynski.edziennik.sync.SyncWorker import pl.szczodrzynski.edziennik.ui.dialogs.changelog.ChangelogDialog -import pl.szczodrzynski.edziennik.ui.dialogs.error.ErrorSnackbar import pl.szczodrzynski.edziennik.ui.dialogs.settings.ProfileRemoveDialog +import pl.szczodrzynski.edziennik.ui.dialogs.sync.SyncViewListDialog import pl.szczodrzynski.edziennik.ui.modules.agenda.AgendaFragment import pl.szczodrzynski.edziennik.ui.modules.announcements.AnnouncementsFragment import pl.szczodrzynski.edziennik.ui.modules.attendance.AttendanceFragment import pl.szczodrzynski.edziennik.ui.modules.base.DebugFragment import pl.szczodrzynski.edziennik.ui.modules.behaviour.BehaviourFragment +import pl.szczodrzynski.edziennik.ui.modules.error.ErrorSnackbar import pl.szczodrzynski.edziennik.ui.modules.feedback.FeedbackFragment import pl.szczodrzynski.edziennik.ui.modules.feedback.HelpFragment import pl.szczodrzynski.edziennik.ui.modules.grades.GradesFragment @@ -469,7 +470,7 @@ class MainActivity : AppCompatActivity() { .withIcon(CommunityMaterial.Icon2.cmd_sync) .withOnClickListener(View.OnClickListener { bottomSheet.close() - app.apiEdziennik.guiSyncFeature(app, this, App.profileId, R.string.sync_dialog_title, R.string.sync_dialog_text, R.string.sync_done, fragmentToFeature(navTargetId)) + SyncViewListDialog(this, navTargetId) }), BottomSheetSeparatorItem(false), BottomSheetPrimaryItem(false) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Features.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Features.kt index 4d0c94c8..78b77f07 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Features.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Features.kt @@ -7,39 +7,36 @@ package pl.szczodrzynski.edziennik.api.v2 import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_AGENDA import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_ANNOUNCEMENTS import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_ATTENDANCE +import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_BEHAVIOUR import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_GRADES import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_HOME import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_HOMEWORK import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_MESSAGES -import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_BEHAVIOUR import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_TIMETABLE import pl.szczodrzynski.edziennik.data.db.modules.messages.Message.TYPE_RECEIVED import pl.szczodrzynski.edziennik.data.db.modules.messages.Message.TYPE_SENT -const val FEATURE_ALL = 0 -const val FEATURE_TIMETABLE = 1 -const val FEATURE_AGENDA = 2 -const val FEATURE_GRADES = 3 -const val FEATURE_HOMEWORK = 4 -const val FEATURE_BEHAVIOUR = 5 -const val FEATURE_ATTENDANCE = 6 -const val FEATURE_MESSAGES_INBOX = 7 -const val FEATURE_MESSAGES_SENT = 8 -const val FEATURE_ANNOUNCEMENTS = 9 +internal const val FEATURE_TIMETABLE = 1 +internal const val FEATURE_AGENDA = 2 +internal const val FEATURE_GRADES = 3 +internal const val FEATURE_HOMEWORK = 4 +internal const val FEATURE_BEHAVIOUR = 5 +internal const val FEATURE_ATTENDANCE = 6 +internal const val FEATURE_MESSAGES_INBOX = 7 +internal const val FEATURE_MESSAGES_SENT = 8 +internal const val FEATURE_ANNOUNCEMENTS = 9 -const val FEATURE_ALWAYS_NEEDED = 100 -const val FEATURE_STUDENT_INFO = 101 -const val FEATURE_STUDENT_NUMBER = 109 -const val FEATURE_SCHOOL_INFO = 102 -const val FEATURE_CLASS_INFO = 103 -const val FEATURE_TEAM_INFO = 104 -const val FEATURE_LUCKY_NUMBER = 105 -const val FEATURE_TEACHERS = 106 -const val FEATURE_SUBJECTS = 107 -const val FEATURE_CLASSROOMS = 108 -const val FEATURE_PUSH_CONFIG = 120 - -const val FEATURE_MESSAGE_GET = 201 +internal const val FEATURE_ALWAYS_NEEDED = 100 +internal const val FEATURE_STUDENT_INFO = 101 +internal const val FEATURE_STUDENT_NUMBER = 109 +internal const val FEATURE_SCHOOL_INFO = 102 +internal const val FEATURE_CLASS_INFO = 103 +internal const val FEATURE_TEAM_INFO = 104 +internal const val FEATURE_LUCKY_NUMBER = 105 +internal const val FEATURE_TEACHERS = 106 +internal const val FEATURE_SUBJECTS = 107 +internal const val FEATURE_CLASSROOMS = 108 +internal const val FEATURE_PUSH_CONFIG = 120 object Features { private fun getAllNecessary(): List = listOf( diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/sync/SyncViewListDialog.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/sync/SyncViewListDialog.kt new file mode 100644 index 00000000..e8942c1e --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/sync/SyncViewListDialog.kt @@ -0,0 +1,108 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2019-11-13. + */ + +package pl.szczodrzynski.edziennik.ui.dialogs.sync + +import androidx.appcompat.app.AlertDialog +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import pl.szczodrzynski.edziennik.App +import pl.szczodrzynski.edziennik.MainActivity +import pl.szczodrzynski.edziennik.R +import pl.szczodrzynski.edziennik.api.v2.events.task.EdziennikTask +import pl.szczodrzynski.edziennik.databinding.DialogLessonDetailsBinding +import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesFragment +import kotlin.coroutines.CoroutineContext + +class SyncViewListDialog( + val activity: MainActivity, + val currentViewId: Int? = null +) : CoroutineScope { + companion object { + private const val TAG = "SyncViewListDialog" + } + + private lateinit var job: Job + override val coroutineContext: CoroutineContext + get() = job + Dispatchers.Main + + private val app by lazy { activity.application as App } + private lateinit var b: DialogLessonDetailsBinding + private lateinit var dialog: AlertDialog + + init { run { + job = Job() + + val viewIds = arrayOf( + MainActivity.DRAWER_ITEM_TIMETABLE, + MainActivity.DRAWER_ITEM_AGENDA, + MainActivity.DRAWER_ITEM_GRADES, + MainActivity.DRAWER_ITEM_HOMEWORK, + MainActivity.DRAWER_ITEM_BEHAVIOUR, + MainActivity.DRAWER_ITEM_ATTENDANCE, + MainActivity.DRAWER_ITEM_MESSAGES, + MainActivity.DRAWER_ITEM_MESSAGES, + MainActivity.DRAWER_ITEM_ANNOUNCEMENTS + ) + + val items = arrayOf( + app.getString(R.string.menu_timetable), + app.getString(R.string.menu_agenda), + app.getString(R.string.menu_grades), + app.getString(R.string.menu_homework), + app.getString(R.string.menu_notices), + app.getString(R.string.menu_attendance), + app.getString(R.string.title_messages_inbox_single), + app.getString(R.string.title_messages_sent_single), + app.getString(R.string.menu_announcements) + ) + + val everything = currentViewId == MainActivity.DRAWER_ITEM_HOME + val checkedItems = booleanArrayOf( + everything || currentViewId == MainActivity.DRAWER_ITEM_TIMETABLE, + everything || currentViewId == MainActivity.DRAWER_ITEM_AGENDA, + everything || currentViewId == MainActivity.DRAWER_ITEM_GRADES, + everything || currentViewId == MainActivity.DRAWER_ITEM_HOMEWORK, + everything || currentViewId == MainActivity.DRAWER_ITEM_BEHAVIOUR, + everything || currentViewId == MainActivity.DRAWER_ITEM_ATTENDANCE, + everything || currentViewId == MainActivity.DRAWER_ITEM_MESSAGES && MessagesFragment.pageSelection != 1, + everything || currentViewId == MainActivity.DRAWER_ITEM_MESSAGES && MessagesFragment.pageSelection == 1, + everything || currentViewId == MainActivity.DRAWER_ITEM_ANNOUNCEMENTS + ) + val userChooses = checkedItems.toMutableList() + + dialog = MaterialAlertDialogBuilder(activity) + .setTitle(R.string.dialog_sync_view_list_title) + .setMultiChoiceItems(items, checkedItems) { _, which, isChecked -> + userChooses[which] = isChecked + } + .setPositiveButton(R.string.ok) { _, _ -> + dialog.dismiss() + + val selectedViewIds = userChooses.mapIndexed { index, it -> + if (it) + viewIds[index] to when (index) { + 7 -> 1 + else -> 0 + } + else + null + }.let { + listOfNotNull(*it.toTypedArray()) + } + + activity.swipeRefreshLayout.isRefreshing = true + EdziennikTask.syncProfile( + App.profileId, + selectedViewIds + ).enqueue(activity) + } + .setNegativeButton(R.string.cancel) { _, _ -> + dialog.dismiss() + } + .show() + }} +} \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/error/ErrorDialog.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/error/ErrorDialog.kt new file mode 100644 index 00000000..bf0ff712 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/error/ErrorDialog.kt @@ -0,0 +1,46 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2019-11-13. + */ + +package pl.szczodrzynski.edziennik.ui.modules.error + +import android.util.Log +import androidx.appcompat.app.AlertDialog +import androidx.appcompat.app.AppCompatActivity +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import pl.szczodrzynski.edziennik.App +import pl.szczodrzynski.edziennik.R +import pl.szczodrzynski.edziennik.databinding.DialogLessonDetailsBinding +import kotlin.coroutines.CoroutineContext + +class ErrorDialog( + val activity: AppCompatActivity, + val exception: Exception +) : CoroutineScope { + companion object { + private const val TAG = "ErrorDialog" + } + + private lateinit var job: Job + override val coroutineContext: CoroutineContext + get() = job + Dispatchers.Main + + private val app by lazy { activity.application as App } + private lateinit var b: DialogLessonDetailsBinding + private lateinit var dialog: AlertDialog + + init { run { + job = Job() + + dialog = MaterialAlertDialogBuilder(activity) + .setTitle(R.string.error_occured) + .setMessage(exception.message + "\n" + Log.getStackTraceString(exception)) + .setPositiveButton(R.string.ok) { _, _ -> + dialog.dismiss() + } + .show() + }} +} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/error/ErrorSnackbar.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/error/ErrorSnackbar.kt similarity index 96% rename from app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/error/ErrorSnackbar.kt rename to app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/error/ErrorSnackbar.kt index 21899e9f..17b69c8b 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/error/ErrorSnackbar.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/error/ErrorSnackbar.kt @@ -2,7 +2,7 @@ * Copyright (c) Kuba Szczodrzyński 2019-11-13. */ -package pl.szczodrzynski.edziennik.ui.dialogs.error +package pl.szczodrzynski.edziennik.ui.modules.error import android.view.View import androidx.appcompat.app.AppCompatActivity diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginActivity.java b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginActivity.java index f8ec0a4d..41c24680 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginActivity.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginActivity.java @@ -17,7 +17,7 @@ import pl.szczodrzynski.edziennik.App; import pl.szczodrzynski.edziennik.R; import pl.szczodrzynski.edziennik.api.v2.models.ApiError; import pl.szczodrzynski.edziennik.databinding.ActivityLoginBinding; -import pl.szczodrzynski.edziennik.ui.dialogs.error.ErrorSnackbar; +import pl.szczodrzynski.edziennik.ui.modules.error.ErrorSnackbar; public class LoginActivity extends AppCompatActivity { diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginIuczniowieFragment.java b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginIuczniowieFragment.java index 4f65ff42..2191e63a 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginIuczniowieFragment.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginIuczniowieFragment.java @@ -17,7 +17,7 @@ import pl.szczodrzynski.edziennik.App; import pl.szczodrzynski.edziennik.R; import pl.szczodrzynski.edziennik.api.v2.models.ApiError; import pl.szczodrzynski.edziennik.databinding.FragmentLoginIuczniowieBinding; -import pl.szczodrzynski.edziennik.ui.dialogs.error.ErrorSnackbar; +import pl.szczodrzynski.edziennik.ui.modules.error.ErrorSnackbar; import static pl.szczodrzynski.edziennik.data.api.AppError.CODE_INVALID_LOGIN; import static pl.szczodrzynski.edziennik.data.api.AppError.CODE_INVALID_SCHOOL_NAME; diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginLibrusFragment.java b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginLibrusFragment.java index f865483c..d7abdc57 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginLibrusFragment.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginLibrusFragment.java @@ -17,7 +17,7 @@ import pl.szczodrzynski.edziennik.App; import pl.szczodrzynski.edziennik.R; import pl.szczodrzynski.edziennik.api.v2.models.ApiError; import pl.szczodrzynski.edziennik.databinding.FragmentLoginLibrusBinding; -import pl.szczodrzynski.edziennik.ui.dialogs.error.ErrorSnackbar; +import pl.szczodrzynski.edziennik.ui.modules.error.ErrorSnackbar; import static pl.szczodrzynski.edziennik.api.v2.ErrorsKt.ERROR_LOGIN_DATA_INVALID; import static pl.szczodrzynski.edziennik.api.v2.ErrorsKt.ERROR_LOGIN_LIBRUS_PORTAL_NOT_ACTIVATED; diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginMobidziennikFragment.java b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginMobidziennikFragment.java index fbaf952a..8725fa92 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginMobidziennikFragment.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginMobidziennikFragment.java @@ -17,7 +17,7 @@ import pl.szczodrzynski.edziennik.App; import pl.szczodrzynski.edziennik.R; import pl.szczodrzynski.edziennik.api.v2.models.ApiError; import pl.szczodrzynski.edziennik.databinding.FragmentLoginMobidziennikBinding; -import pl.szczodrzynski.edziennik.ui.dialogs.error.ErrorSnackbar; +import pl.szczodrzynski.edziennik.ui.modules.error.ErrorSnackbar; import static pl.szczodrzynski.edziennik.data.api.AppError.CODE_ARCHIVED; import static pl.szczodrzynski.edziennik.data.api.AppError.CODE_INVALID_LOGIN; diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginVulcanFragment.java b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginVulcanFragment.java index 9c81cdc2..253636d6 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginVulcanFragment.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginVulcanFragment.java @@ -35,7 +35,7 @@ import pl.szczodrzynski.edziennik.App; import pl.szczodrzynski.edziennik.R; import pl.szczodrzynski.edziennik.api.v2.models.ApiError; import pl.szczodrzynski.edziennik.databinding.FragmentLoginVulcanBinding; -import pl.szczodrzynski.edziennik.ui.dialogs.error.ErrorSnackbar; +import pl.szczodrzynski.edziennik.ui.modules.error.ErrorSnackbar; import pl.szczodrzynski.edziennik.ui.modules.webpush.QrScannerActivity; import pl.szczodrzynski.edziennik.utils.Utils; diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/messages/MessagesDetailsFragment.java b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/messages/MessagesDetailsFragment.java index 2bf92359..d00c35f3 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/messages/MessagesDetailsFragment.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/messages/MessagesDetailsFragment.java @@ -45,6 +45,7 @@ import pl.szczodrzynski.edziennik.MainActivity; import pl.szczodrzynski.edziennik.R; import pl.szczodrzynski.edziennik.data.db.modules.messages.MessageFull; import pl.szczodrzynski.edziennik.databinding.MessagesDetailsBinding; +import pl.szczodrzynski.edziennik.ui.modules.error.ErrorDialog; import pl.szczodrzynski.edziennik.utils.Themes; import pl.szczodrzynski.edziennik.utils.Utils; @@ -320,7 +321,7 @@ public class MessagesDetailsFragment extends Fragment { } } catch (Exception e) { e.printStackTrace(); - app.apiEdziennik.guiReportException(activity, 355, e); + new ErrorDialog(activity, e); } } } @@ -458,7 +459,7 @@ public class MessagesDetailsFragment extends Fragment { .positiveText(R.string.ok) .neutralColor(R.string.report) .onNeutral((dialog, which) -> { - app.apiEdziennik.guiReportException(activity, 433, event.exception); + new ErrorDialog(activity, event.exception); }) .show(); } @@ -466,7 +467,7 @@ public class MessagesDetailsFragment extends Fragment { } } catch (Exception e) { - app.apiEdziennik.guiReportException(activity, 425, e); + new ErrorDialog(activity, e); } } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/messages/MessagesWebFragment.java b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/messages/MessagesWebFragment.java deleted file mode 100644 index 343f4076..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/messages/MessagesWebFragment.java +++ /dev/null @@ -1,474 +0,0 @@ -package pl.szczodrzynski.edziennik.ui.modules.messages; - -import android.Manifest; -import android.annotation.SuppressLint; -import android.app.Activity; -import android.app.DownloadManager; -import android.content.ActivityNotFoundException; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.PackageManager; -import android.graphics.Bitmap; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.os.Environment; -import android.os.Handler; -import android.provider.MediaStore; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.webkit.CookieManager; -import android.webkit.MimeTypeMap; -import android.webkit.ValueCallback; -import android.webkit.WebChromeClient; -import android.webkit.WebResourceError; -import android.webkit.WebResourceRequest; -import android.webkit.WebView; -import android.webkit.WebViewClient; -import android.widget.ProgressBar; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.app.ActivityCompat; -import androidx.core.content.FileProvider; -import androidx.databinding.DataBindingUtil; -import androidx.fragment.app.Fragment; - -import com.afollestad.materialdialogs.MaterialDialog; -import com.afollestad.materialdialogs.StackingBehavior; - -import java.io.File; -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.text.SimpleDateFormat; -import java.util.Date; - -import pl.szczodrzynski.edziennik.App; -import pl.szczodrzynski.edziennik.R; -import pl.szczodrzynski.edziennik.databinding.FragmentMessagesWebBinding; -import pl.szczodrzynski.edziennik.utils.Anim; -import pl.szczodrzynski.edziennik.utils.Themes; - -import static android.app.Activity.RESULT_OK; -import static android.content.Context.DOWNLOAD_SERVICE; -import static pl.szczodrzynski.edziennik.utils.Utils.readableFileSize; - -public class MessagesWebFragment extends Fragment { - - private static final String TAG = "RegisterMessagesWeb"; - private App app = null; - private Activity activity = null; - private FragmentMessagesWebBinding b = null; - - private WebView webView; - private ProgressBar progressBar; - private TextView error; - - @Override - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - activity = getActivity(); - if (getActivity() == null || getContext() == null) - return null; - app = (App) activity.getApplication(); - getContext().getTheme().applyStyle(Themes.INSTANCE.getAppTheme(), true); - if (app.profile == null) - return inflater.inflate(R.layout.fragment_loading, container, false); - // activity, context and profile is valid - b = DataBindingUtil.inflate(inflater, R.layout.fragment_messages_web, container, false); - return b.getRoot(); - } - - private boolean isStoragePermissionGranted(Activity a) { - if (Build.VERSION.SDK_INT >= 23) { - if (a.checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) - == PackageManager.PERMISSION_GRANTED) { - Log.v(TAG,"Permission is granted"); - return true; - } else { - - Log.v(TAG,"Permission is revoked"); - ActivityCompat.requestPermissions(a, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); - return false; - } - } - else { //permission is automatically granted on sdk<23 upon installation - Log.v(TAG,"Permission is granted"); - return true; - } - } - - private String getFileNameFromDisposition(String header) - { - return header.substring(header.indexOf("\"") + 1, header.lastIndexOf("\"")); - } - - private File downloadingFile; - - private void enqueueFile(String url, String filename, File downloadingFile, String cookieString) { - - this.downloadingFile = downloadingFile; - - long downloadReference; - - DownloadManager downloadManager; - downloadManager = (DownloadManager)app.getSystemService(DOWNLOAD_SERVICE); - DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); - request.setTitle(filename); - request.setDescription(getString(R.string.downloading)); - request.addRequestHeader("Cookie", cookieString); - try { - request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename); - } - catch (IllegalStateException e) - { - e.printStackTrace(); - Toast.makeText(app, "Failed to get external storage files directory", Toast.LENGTH_SHORT).show(); - } - downloadReference = downloadManager.enqueue(request); - } - - private static String getMimeType(String url) { - String type = null; - String extension = MimeTypeMap.getFileExtensionFromUrl(url); - if (extension != null) { - type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); - } - return type; - } - - private void openFile(File url) { - Toast.makeText(app, getString(R.string.opening_file, url.getName()), Toast.LENGTH_SHORT).show(); - try { - Uri uri = FileProvider.getUriForFile(app, app.getApplicationContext().getPackageName() + ".provider", url); - //Uri uri = Uri.fromFile(url); - Intent intent = new Intent(Intent.ACTION_VIEW); - if (url.toString().contains(".doc") || url.toString().contains(".docx")) { - // Word document - intent.setDataAndType(uri, "application/msword"); - } else if (url.toString().contains(".pdf")) { - // PDF file - intent.setDataAndType(uri, "application/pdf"); - } else if (url.toString().contains(".ppt") || url.toString().contains(".pptx")) { - // Powerpoint file - intent.setDataAndType(uri, "application/vnd.ms-powerpoint"); - } else if (url.toString().contains(".xls") || url.toString().contains(".xlsx")) { - // Excel file - intent.setDataAndType(uri, "application/vnd.ms-excel"); - } else if (url.toString().contains(".zip") || url.toString().contains(".rar")) { - // WAV audio file - intent.setDataAndType(uri, "application/x-wav"); - } else if (url.toString().contains(".rtf")) { - // RTF file - intent.setDataAndType(uri, "application/rtf"); - } else if (url.toString().contains(".wav") || url.toString().contains(".mp3")) { - // WAV audio file - intent.setDataAndType(uri, "audio/x-wav"); - } else if (url.toString().contains(".gif")) { - // GIF file - intent.setDataAndType(uri, "image/gif"); - } else if (url.toString().contains(".jpg") || url.toString().contains(".jpeg") || url.toString().contains(".png")) { - // JPG file - intent.setDataAndType(uri, "image/jpeg"); - } else if (url.toString().contains(".txt")) { - // Text file - intent.setDataAndType(uri, "text/plain"); - } else if (url.toString().contains(".3gp") || url.toString().contains(".mpg") || - url.toString().contains(".mpeg") || url.toString().contains(".mpe") || url.toString().contains(".mp4") || url.toString().contains(".avi")) { - // Video files - intent.setDataAndType(uri, "video/*"); - } else { - intent.setDataAndType(uri, "*/*"); - } - - intent.setDataAndType(uri, getMimeType(uri.toString())); - - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - - app.startActivity(intent); - } catch (ActivityNotFoundException e) { - Toast.makeText(app, R.string.opening_file_no_app, Toast.LENGTH_SHORT).show(); - } - } - - private void downloadFile(Activity a, String url, String filename, long contentLength, String cookieString) { - if (!isStoragePermissionGranted(a)) - return; - new MaterialDialog.Builder(a) - .title(R.string.downloading_file) - .content(getString((R.string.download_file_question), filename, readableFileSize(contentLength))) - .positiveText(R.string.yes) - .negativeText(R.string.no) - .onPositive((dialog, which) -> { - File downloadsDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); - File existingFile = new File(downloadsDir, filename); - if (existingFile.exists()) { - new MaterialDialog.Builder(a) - .title(R.string.downloading_file) - .content(getString(R.string.downloading_file_exists_choose, filename)) - .stackingBehavior(StackingBehavior.ADAPTIVE) - .positiveText(R.string.downloading_file_exists_overwrite) - .negativeText(R.string.downloading_file_exists_open) - .neutralText(R.string.downloading_file_exists_create_new) - .onPositive(((dialog1, which1) -> { - if (!existingFile.delete()) - { - new MaterialDialog.Builder(a) - .title(R.string.downloading_file) - .content(R.string.downloading_file_cannot_remove) - .positiveText(R.string.ok) - .negativeText(R.string.cancel) - .onPositive(((dialog2, which2) -> enqueueFile(url, filename, existingFile, cookieString))) - .show(); - return; - } - enqueueFile(url, filename, existingFile, cookieString); - })) - .onNegative(((dialog1, which1) -> openFile(existingFile))) - .onNeutral((dialog1, which1) -> enqueueFile(url, filename, existingFile, cookieString)) - .show(); - - return; - } - enqueueFile(url, filename, existingFile, cookieString); - }) - .show(); - } - - private String photoPath; - private ValueCallback mUM; - private ValueCallback fileCallback; - private final static int REQUEST_FILE_CHOOSER = 1; - private boolean justLoaded = false; - - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if(Build.VERSION.SDK_INT >= 21){ - Uri[] results = null; - //Check if response is positive - if(resultCode == RESULT_OK){ - if(requestCode == REQUEST_FILE_CHOOSER){ - if(null == fileCallback){ - return; - } - if(data == null){ - //Capture Photo if no image available - if (photoPath != null) { - results = new Uri[]{Uri.parse(photoPath)}; - } - }else{ - String dataString = data.getDataString(); - if(dataString != null){ - results = new Uri[]{Uri.parse(dataString)}; - } - } - } - } - fileCallback.onReceiveValue(results); - fileCallback = null; - } else { - if (requestCode == REQUEST_FILE_CHOOSER) { - if(null == mUM) return; - Uri result = data == null || resultCode != RESULT_OK ? null : data.getData(); - mUM.onReceiveValue(result); - mUM = null; - } - } - } - - private File createImageFile() throws IOException{ - @SuppressLint("SimpleDateFormat") String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); - String imageFileName = "img_"+timeStamp+"_"; - File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); - return File.createTempFile(imageFileName,".jpg",storageDir); - } - - @SuppressLint("SetJavaScriptEnabled") - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - if (app == null || app.profile == null || activity == null || b == null || !isAdded()) - return; - - webView = b.messagesWebView; - progressBar = b.messagesWebProgressBar; - error = b.messagesWebError; - - justLoaded = true; - - new Handler().postDelayed(() -> activity.runOnUiThread(() -> { - if (app == null || app.profile == null || activity == null || b == null || !isAdded()) - return; - - BroadcastReceiver onComplete = new BroadcastReceiver() { - public void onReceive(Context context, Intent intent) { - if (downloadingFile != null) { - openFile(downloadingFile); - downloadingFile = null; - } - } - }; - activity.registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); - - app.apiEdziennik.initMessagesWebView(webView, app, /*app.profile.messagesWebFullVersion*/false, false); - webView.getSettings().setJavaScriptEnabled(true); - webView.getSettings().setAllowFileAccess(true); - webView.setDownloadListener((url, userAgent, contentDisposition, mimetype, contentLength) -> { - String filename = getFileNameFromDisposition(contentDisposition); - try { - URL urlObj = new URL(url); - Log.d(TAG, "Host "+urlObj.getProtocol()+"://"+urlObj.getHost()); - Log.d(TAG, "Cookies "+CookieManager.getInstance().getCookie(urlObj.getProtocol()+"://"+urlObj.getHost())); - - downloadFile(getActivity(), url, filename, contentLength, CookieManager.getInstance().getCookie(urlObj.getProtocol()+"://"+urlObj.getHost())); - } catch (MalformedURLException e) { - e.printStackTrace(); - } - Anim.fadeOut(progressBar, 400, null); - }); - - webView.setWebViewClient(new WebViewClient() { - boolean loadingFinished = true; - boolean redirect = false; - @Override - public boolean shouldOverrideUrlLoading(WebView view, String request) { - if (!loadingFinished) { - redirect = true; - } - - loadingFinished = false; - webView.loadUrl(request); - return true; - } - - @Override - public void onPageStarted(WebView view, String url, Bitmap favicon) { - super.onPageStarted(view, url, favicon); - MessagesWebFragment.this.error.setVisibility(View.GONE); - loadingFinished = false; - //SHOW LOADING IF IT ISNT ALREADY VISIBLE - if (progressBar.getVisibility() != View.VISIBLE) - Anim.fadeIn(progressBar, 400, null); - } - - @Override - public void onPageFinished(WebView view, String url) { - if (!redirect) { - loadingFinished = true; - } - - if (loadingFinished && !redirect) { - //HIDE LOADING IT HAS FINISHED - //String cookies = CookieManager.getInstance().getCookie(url); - //Log.d(TAG, "All the cookies in a string:" + cookies); - Anim.fadeOut(progressBar, 400, null); - /*if (app.profile.messagesWebFullVersion && justLoaded && app.profile.loginType == Register.LOGIN_TYPE_MOBIDZIENNIK) { - if (!webView.getUrl().contains("wiadomosci")) { - // redirect to messages view - webView.loadUrl("https://" + app.getLoginData("serverName", "") + ".mobidziennik.pl/mobile/wiadomosci"); - } - justLoaded = false; - }*/ - } else { - redirect = false; - } - } - - @Override - public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { - if (app == null || app.profile == null || activity == null || b == null || !isAdded()) - return; - - MessagesWebFragment.this.error.setVisibility(View.VISIBLE); - MessagesWebFragment.this.error.setText(getString(R.string.error_occured_format, error.toString())); - super.onReceivedError(view, request, error); - } - }); - - if(Build.VERSION.SDK_INT >= 21) { - webView.getSettings().setMixedContentMode(0); - webView.setLayerType(View.LAYER_TYPE_HARDWARE, null); - } else if(Build.VERSION.SDK_INT >= 19) { - webView.setLayerType(View.LAYER_TYPE_HARDWARE, null); - } else { - webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); - } - - webView.setWebChromeClient(new WebChromeClient(){ - //For Android 5.0+ - public boolean onShowFileChooser( - WebView webView, ValueCallback filePathCallback, - WebChromeClient.FileChooserParams fileChooserParams){ - if(fileCallback != null){ - fileCallback.onReceiveValue(null); - } - fileCallback = filePathCallback; - Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); - if(takePictureIntent.resolveActivity(app.getPackageManager()) != null){ - File photoFile = null; - try{ - photoFile = createImageFile(); - takePictureIntent.putExtra("PhotoPath", photoPath); - }catch(IOException ex){ - Log.e(TAG, "Image file creation failed", ex); - } - if(photoFile != null){ - photoPath = "file:" + photoFile.getAbsolutePath(); - takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile)); - }else{ - takePictureIntent = null; - } - } - Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT); - contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE); - contentSelectionIntent.setType("*/*"); - Intent[] intentArray; - if(takePictureIntent != null){ - intentArray = new Intent[]{takePictureIntent}; - }else{ - intentArray = new Intent[0]; - } - - Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER); - chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent); - chooserIntent.putExtra(Intent.EXTRA_TITLE, R.string.choose_file); - chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray); - startActivityForResult(chooserIntent, REQUEST_FILE_CHOOSER); - return true; - } - }); - - - }), 200); - } - - /*public void loadVersion(boolean fullVersion) { - if (app.profile.messagesWebFullVersion != fullVersion) { - app.profile.messagesWebFullVersion = fullVersion; - app.profile.savePending = true; - justLoaded = true; - app.apiEdziennik.initMessagesWebView(webView, app, fullVersion, true); - } - }*/ - - public void performReload() { - webView.reload(); - } - - public boolean processBackKey() - { - if (webView.canGoBack()) - { - webView.goBack(); - return true; - } - return false; - } -} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/timetable/TimetableFragment.java b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/timetable/TimetableFragment.java index 09eda619..1bce90fc 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/timetable/TimetableFragment.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/timetable/TimetableFragment.java @@ -51,6 +51,7 @@ import pl.szczodrzynski.edziennik.R; import pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonFull; import pl.szczodrzynski.edziennik.databinding.FragmentTimetableBinding; import pl.szczodrzynski.edziennik.ui.dialogs.event.EventManualDialog; +import pl.szczodrzynski.edziennik.ui.modules.error.ErrorDialog; import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragment; import pl.szczodrzynski.edziennik.utils.SpannableHtmlTagHandler; import pl.szczodrzynski.edziennik.utils.Themes; @@ -422,7 +423,7 @@ public class TimetableFragment extends Fragment { linearLayout = (LinearLayout) getLayoutInflater().inflate(R.layout.row_timetable_block_item, null); } catch (Exception e) { - app.apiEdziennik.guiReportException(activity, 385, e); + new ErrorDialog(activity, e); return; } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 462eaece..936cf55e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1024,4 +1024,5 @@ Nie ma lekcji tego dnia Profil został usunięty. Wystąpił błąd + Synchronizacja ręczna