[Error] Add user friendly error strings. Add error snackbar to activity & login.

This commit is contained in:
Kuba Szczodrzyński 2019-11-13 19:44:08 +01:00
parent 831b7876b4
commit 058345b9c9
18 changed files with 450 additions and 178 deletions

View File

@ -45,6 +45,7 @@ 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.modules.agenda.AgendaFragment
import pl.szczodrzynski.edziennik.ui.modules.announcements.AnnouncementsFragment
@ -215,6 +216,7 @@ class MainActivity : AppCompatActivity() {
val navView: NavView by lazy { b.navView }
val drawer: NavDrawer by lazy { navView.drawer }
val bottomSheet: NavBottomSheet by lazy { navView.bottomSheet }
val errorSnackbar: ErrorSnackbar by lazy { ErrorSnackbar(this) }
val swipeRefreshLayout: SwipeRefreshLayoutNoTouch by lazy { b.swipeRefreshLayout }
@ -247,6 +249,8 @@ class MainActivity : AppCompatActivity() {
setContentView(b.root)
errorSnackbar.setCoordinator(b.navView.coordinator, b.navView.bottomBar)
navLoading = true
b.navView.apply {
@ -574,7 +578,12 @@ class MainActivity : AppCompatActivity() {
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onSyncErrorEvent(event: ApiTaskErrorEvent) {
navView.toolbar.apply {
subtitleFormat = R.string.toolbar_subtitle
subtitleFormatWithUnread = R.plurals.toolbar_subtitle_with_unread
subtitle = "Gotowe"
}
errorSnackbar.addError(event.error).show()
}
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
fun onAppManagerDetectedEvent(event: AppManagerDetectedEvent) {

View File

@ -163,3 +163,5 @@ const val EXCEPTION_LIBRUS_MESSAGES_REQUEST = 911
const val EXCEPTION_IDZIENNIK_WEB_REQUEST = 912
const val EXCEPTION_IDZIENNIK_WEB_API_REQUEST = 913
const val EXCEPTION_IDZIENNIK_API_REQUEST = 914
const val LOGIN_NO_ARGUMENTS = 1201

View File

@ -4,6 +4,7 @@
package pl.szczodrzynski.edziennik.api.v2.models
import android.content.Context
import com.google.gson.JsonObject
import im.wangchao.mhttp.Request
import im.wangchao.mhttp.Response
@ -52,6 +53,15 @@ class ApiError(val tag: String, val errorCode: Int) {
)
}
fun getStringReason(context: Context): String {
return context.resources.getIdentifier("error_${errorCode}_reason", "string", context.packageName).let {
if (it != 0)
context.getString(it)
else
"?"
}
}
override fun toString(): String {
return "ApiError(tag='$tag', errorCode=$errorCode, profileId=$profileId, throwable=$throwable, apiResponse=$apiResponse, request=$request, response=$response, isCritical=$isCritical)"
}

View File

@ -0,0 +1,51 @@
/*
* Copyright (c) Kuba Szczodrzyński 2019-11-13.
*/
package pl.szczodrzynski.edziennik.ui.dialogs.error
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.graphics.ColorUtils
import com.google.android.material.snackbar.Snackbar
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.api.v2.models.ApiError
import pl.szczodrzynski.edziennik.data.api.AppError
import pl.szczodrzynski.navlib.getColorFromAttr
class ErrorSnackbar(val activity: AppCompatActivity) {
companion object {
private const val TAG = "ErrorSnackbar"
}
private var snackbar: Snackbar? = null
private lateinit var coordinator: CoordinatorLayout
private val errors = mutableListOf<ApiError>()
fun setCoordinator(coordinatorLayout: CoordinatorLayout, showAbove: View? = null) {
this.coordinator = coordinatorLayout
snackbar = Snackbar.make(coordinator, R.string.snackbar_error_text, Snackbar.LENGTH_INDEFINITE)
snackbar?.setAction(R.string.more) {
}
val bgColor = ColorUtils.compositeColors(
getColorFromAttr(activity, R.attr.colorOnSurface) and 0xcfffffff.toInt(),
getColorFromAttr(activity, R.attr.colorSurface)
)
snackbar?.setBackgroundTint(bgColor)
showAbove?.let { snackbar?.anchorView = it }
}
fun addError(appError: AppError) {
}
fun addError(apiError: ApiError): ErrorSnackbar {
errors += apiError
snackbar?.setText(apiError.getStringReason(activity))
return this
}
fun show() = snackbar?.show()
fun dismiss() = snackbar?.dismiss()
}

View File

@ -36,7 +36,6 @@ import java.util.List;
import pl.szczodrzynski.edziennik.App;
import pl.szczodrzynski.edziennik.MainActivity;
import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.data.api.AppError;
import pl.szczodrzynski.edziennik.data.db.modules.events.Event;
import pl.szczodrzynski.edziennik.data.db.modules.events.EventFull;
import pl.szczodrzynski.edziennik.data.db.modules.events.EventType;
@ -54,7 +53,6 @@ import pl.szczodrzynski.edziennik.utils.models.Time;
import pl.szczodrzynski.edziennik.utils.models.Week;
import static pl.szczodrzynski.edziennik.App.APP_URL;
import static pl.szczodrzynski.edziennik.data.api.AppError.CODE_OTHER;
import static pl.szczodrzynski.edziennik.data.db.modules.events.Event.COLOR_DEFAULT;
import static pl.szczodrzynski.edziennik.data.db.modules.events.Event.TYPE_HOMEWORK;
import static pl.szczodrzynski.edziennik.data.db.modules.events.Event.TYPE_UNDEFINED;
@ -374,7 +372,8 @@ public class EventManualDialog {
}
} catch (Exception e) {
activity.runOnUiThread(() -> {
app.apiEdziennik.guiShowErrorDialog(activity, new AppError(TAG, 379, CODE_OTHER, null, e), R.string.error_occured);
// TODO show error in EventManualDialog
//app.apiEdziennik.guiShowErrorDialog(activity, new AppError(TAG, 379, CODE_OTHER, null, e), R.string.error_occured);
});
}
});

View File

@ -15,8 +15,9 @@ import java.util.List;
import pl.szczodrzynski.edziennik.App;
import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.data.api.AppError;
import pl.szczodrzynski.edziennik.api.v2.models.ApiError;
import pl.szczodrzynski.edziennik.databinding.ActivityLoginBinding;
import pl.szczodrzynski.edziennik.ui.dialogs.error.ErrorSnackbar;
public class LoginActivity extends AppCompatActivity {
@ -26,7 +27,8 @@ public class LoginActivity extends AppCompatActivity {
public static final int RESULT_OK = 1;
public static NavOptions navOptions;
static AppError error = null;
static ApiError error = null;
ErrorSnackbar errorSnackbar = new ErrorSnackbar(this);
static List<LoginProfileObject> profileObjects;
public static boolean firstCompleted = false; // if a profile is already added during *this* login. This means that LoginChooser has to navigateUp onBackPressed. Else, finish the activity.
@ -69,6 +71,8 @@ public class LoginActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTheme(R.style.AppTheme_Light);
firstCompleted = false;
profileObjects = new ArrayList<>();
error = null;
@ -83,6 +87,8 @@ public class LoginActivity extends AppCompatActivity {
b = DataBindingUtil.inflate(getLayoutInflater(), R.layout.activity_login, null, false);
setContentView(b.getRoot());
errorSnackbar.setCoordinator(b.coordinator, null);
app = (App) getApplication();
if (!app.appConfig.loginFinished) {

View File

@ -1,25 +1,23 @@
package pl.szczodrzynski.edziennik.ui.modules.login;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.Fragment;
import android.text.Editable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.danimahardhika.cafebar.CafeBar;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.Fragment;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import pl.szczodrzynski.edziennik.App;
import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.data.api.AppError;
import pl.szczodrzynski.edziennik.api.v2.models.ApiError;
import pl.szczodrzynski.edziennik.databinding.FragmentLoginIuczniowieBinding;
import pl.szczodrzynski.edziennik.ui.dialogs.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;
@ -31,6 +29,7 @@ public class LoginIuczniowieFragment extends Fragment {
private NavController nav;
private FragmentLoginIuczniowieBinding b;
private static final String TAG = "LoginIuczniowie";
private ErrorSnackbar errorSnackbar;
public LoginIuczniowieFragment() { }
@ -40,6 +39,7 @@ public class LoginIuczniowieFragment extends Fragment {
if (getActivity() != null) {
app = (App) getActivity().getApplicationContext();
nav = Navigation.findNavController(getActivity(), R.id.nav_host_fragment);
errorSnackbar = ((LoginActivity) getActivity()).errorSnackbar;
}
else {
return null;
@ -54,31 +54,17 @@ public class LoginIuczniowieFragment extends Fragment {
assert getActivity() != null;
view.postDelayed(() -> {
AppError error = LoginActivity.error;
ApiError error = LoginActivity.error;
if (error != null) {
switch (error.errorCode) {
switch (error.getErrorCode()) {
case CODE_INVALID_SCHOOL_NAME:
b.loginSchoolNameLayout.setError(getString(R.string.login_error_incorrect_school_name));
break;
case CODE_INVALID_LOGIN:
b.loginPasswordLayout.setError(getString(R.string.login_error_incorrect_login_or_password));
break;
default:
CafeBar.builder(getActivity())
.to(b.root)
.content(getString(R.string.login_error, error.asReadableString(getActivity())))
.autoDismiss(false)
.positiveText(R.string.ok)
.onPositive(CafeBar::dismiss)
.floating(true)
.swipeToDismiss(true)
.neutralText(R.string.more)
.onNeutral(cafeBar -> app.apiEdziennik.guiShowErrorDialog(getActivity(), error, R.string.error_details))
.negativeText(R.string.report)
.onNegative((cafeBar -> app.apiEdziennik.guiReportError(getActivity(), error, null)))
.show();
break;
}
errorSnackbar.addError(error).show();
LoginActivity.error = null;
}
}, 100);

View File

@ -1,28 +1,26 @@
package pl.szczodrzynski.edziennik.ui.modules.login;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.Fragment;
import android.text.Editable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.danimahardhika.cafebar.CafeBar;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.Fragment;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import pl.szczodrzynski.edziennik.App;
import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.data.api.AppError;
import pl.szczodrzynski.edziennik.api.v2.models.ApiError;
import pl.szczodrzynski.edziennik.databinding.FragmentLoginLibrusBinding;
import pl.szczodrzynski.edziennik.ui.dialogs.error.ErrorSnackbar;
import static pl.szczodrzynski.edziennik.data.api.AppError.CODE_INVALID_LOGIN;
import static pl.szczodrzynski.edziennik.data.api.AppError.CODE_LIBRUS_NOT_ACTIVATED;
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;
import static pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore.LOGIN_TYPE_LIBRUS;
public class LoginLibrusFragment extends Fragment {
@ -31,6 +29,7 @@ public class LoginLibrusFragment extends Fragment {
private NavController nav;
private FragmentLoginLibrusBinding b;
private static final String TAG = "LoginLibrus";
private ErrorSnackbar errorSnackbar;
public LoginLibrusFragment() { }
@ -40,6 +39,7 @@ public class LoginLibrusFragment extends Fragment {
if (getActivity() != null) {
app = (App) getActivity().getApplicationContext();
nav = Navigation.findNavController(getActivity(), R.id.nav_host_fragment);
errorSnackbar = ((LoginActivity) getActivity()).errorSnackbar;
}
else {
return null;
@ -54,32 +54,17 @@ public class LoginLibrusFragment extends Fragment {
assert getActivity() != null;
view.postDelayed(() -> {
AppError error = LoginActivity.error;
ApiError error = LoginActivity.error;
if (error != null) {
switch (error.errorCode) {
case CODE_INVALID_LOGIN:
switch (error.getErrorCode()) {
case ERROR_LOGIN_DATA_INVALID:
b.loginPasswordLayout.setError(getString(R.string.login_error_incorrect_login_or_password));
break;
case CODE_LIBRUS_NOT_ACTIVATED:
case ERROR_LOGIN_LIBRUS_PORTAL_NOT_ACTIVATED:
b.loginEmailLayout.setError(getString(R.string.login_error_account_not_activated));
break;
default:
CafeBar.builder(getActivity())
.to(b.root)
.content(getString(R.string.login_error, error.asReadableString(getActivity())))
.duration(10000)
.autoDismiss(false)
.positiveText(R.string.ok)
.onPositive(CafeBar::dismiss)
.floating(true)
.swipeToDismiss(true)
.neutralText(R.string.more)
.onNeutral(cafeBar -> app.apiEdziennik.guiShowErrorDialog(getActivity(), error, R.string.error_details))
.negativeText(R.string.report)
.onNegative((cafeBar -> app.apiEdziennik.guiReportError(getActivity(), error, null)))
.show();
break;
}
errorSnackbar.addError(error).show();
LoginActivity.error = null;
}
}, 100);

View File

@ -1,23 +1,23 @@
package pl.szczodrzynski.edziennik.ui.modules.login;
import androidx.databinding.DataBindingUtil;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import android.text.Editable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.danimahardhika.cafebar.CafeBar;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.Fragment;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import pl.szczodrzynski.edziennik.App;
import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.data.api.AppError;
import pl.szczodrzynski.edziennik.api.v2.models.ApiError;
import pl.szczodrzynski.edziennik.databinding.FragmentLoginMobidziennikBinding;
import pl.szczodrzynski.edziennik.ui.dialogs.error.ErrorSnackbar;
import static pl.szczodrzynski.edziennik.data.api.AppError.CODE_ARCHIVED;
import static pl.szczodrzynski.edziennik.data.api.AppError.CODE_INVALID_LOGIN;
@ -31,6 +31,7 @@ public class LoginMobidziennikFragment extends Fragment {
private NavController nav;
private FragmentLoginMobidziennikBinding b;
private static final String TAG = "LoginMobidziennik";
private ErrorSnackbar errorSnackbar;
public LoginMobidziennikFragment() { }
@ -40,6 +41,7 @@ public class LoginMobidziennikFragment extends Fragment {
if (getActivity() != null) {
app = (App) getActivity().getApplicationContext();
nav = Navigation.findNavController(getActivity(), R.id.nav_host_fragment);
errorSnackbar = ((LoginActivity) getActivity()).errorSnackbar;
}
else {
return null;
@ -54,9 +56,9 @@ public class LoginMobidziennikFragment extends Fragment {
assert getActivity() != null;
view.postDelayed(() -> {
AppError error = LoginActivity.error;
ApiError error = LoginActivity.error;
if (error != null) {
switch (error.errorCode) {
switch (error.getErrorCode()) {
case CODE_INVALID_LOGIN:
b.loginPasswordLayout.setError(getString(R.string.login_error_incorrect_login_or_password));
break;
@ -69,22 +71,8 @@ public class LoginMobidziennikFragment extends Fragment {
case CODE_INVALID_SERVER_ADDRESS:
b.loginServerAddressLayout.setError(getString(R.string.login_error_incorrect_address));
break;
default:
CafeBar.builder(getActivity())
.to(b.root)
.content(getString(R.string.login_error, error.asReadableString(getActivity())))
.autoDismiss(false)
.positiveText(R.string.ok)
.onPositive(CafeBar::dismiss)
.floating(true)
.swipeToDismiss(true)
.neutralText(R.string.more)
.onNeutral(cafeBar -> app.apiEdziennik.guiShowErrorDialog(getActivity(), error, R.string.error_details))
.negativeText(R.string.report)
.onNegative((cafeBar -> app.apiEdziennik.guiReportError(getActivity(), error, null)))
.show();
break;
}
errorSnackbar.addError(error).show();
LoginActivity.error = null;
}
}, 100);

View File

@ -23,11 +23,11 @@ import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.api.v2.events.ApiTaskErrorEvent;
import pl.szczodrzynski.edziennik.api.v2.events.FirstLoginFinishedEvent;
import pl.szczodrzynski.edziennik.api.v2.events.task.EdziennikTask;
import pl.szczodrzynski.edziennik.data.api.AppError;
import pl.szczodrzynski.edziennik.api.v2.models.ApiError;
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore;
import pl.szczodrzynski.edziennik.databinding.FragmentLoginProgressBinding;
import static pl.szczodrzynski.edziennik.data.api.AppError.CODE_OTHER;
import static pl.szczodrzynski.edziennik.api.v2.ErrorsKt.LOGIN_NO_ARGUMENTS;
public class LoginProgressFragment extends Fragment {
@ -62,7 +62,7 @@ public class LoginProgressFragment extends Fragment {
@Subscribe(threadMode = ThreadMode.MAIN)
public void onSyncErrorEvent(ApiTaskErrorEvent event) {
LoginActivity.error = event.getError().toAppError();
LoginActivity.error = event.getError();
if (getActivity() == null)
return;
nav.navigateUp();
@ -79,7 +79,7 @@ public class LoginProgressFragment extends Fragment {
LoginActivity.error = null;
if (args == null) {
LoginActivity.error = new AppError(TAG, 72, CODE_OTHER, getString(R.string.login_error_no_arguments));
LoginActivity.error = new ApiError(TAG, LOGIN_NO_ARGUMENTS);
nav.navigateUp();
return;
}

View File

@ -1,6 +1,9 @@
package pl.szczodrzynski.edziennik.ui.modules.login;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@ -8,14 +11,11 @@ import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.Fragment;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import pl.szczodrzynski.edziennik.App;
import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.databinding.FragmentLoginSyncErrorBinding;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class LoginSyncErrorFragment extends Fragment {
private App app;
@ -44,10 +44,10 @@ public class LoginSyncErrorFragment extends Fragment {
assert getContext() != null;
assert getActivity() != null;
b.errorDetails.setText(LoginActivity.error == null ? "" : LoginActivity.error.asReadableString(getActivity()));
b.errorDetails.setText(LoginActivity.error == null ? "" : LoginActivity.error.getStringReason(getActivity()));
b.reportButton.setOnClickListener((v -> {
app.apiEdziennik.guiReportError(getActivity(), LoginActivity.error, null);
// TODO error report activity open here app.apiEdziennik.guiReportError(getActivity(), LoginActivity.error, null);
}));
b.nextButton.setOnClickListener((v -> {

View File

@ -65,7 +65,7 @@ class LoginSyncFragment : Fragment() {
@Subscribe(threadMode = ThreadMode.MAIN)
fun onSyncErrorEvent(event: ApiTaskErrorEvent) {
LoginActivity.error = event.error.toAppError()
LoginActivity.error = event.error
nav.navigate(R.id.loginSyncErrorFragment, null, LoginActivity.navOptions)
}

View File

@ -3,27 +3,24 @@ package pl.szczodrzynski.edziennik.ui.modules.login;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.Fragment;
import android.text.Editable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import com.danimahardhika.cafebar.CafeBar;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.Fragment;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
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 androidx.navigation.NavController;
import androidx.navigation.Navigation;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.regex.Matcher;
@ -36,9 +33,10 @@ import javax.crypto.ShortBufferException;
import pl.szczodrzynski.edziennik.App;
import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.ui.modules.webpush.QrScannerActivity;
import pl.szczodrzynski.edziennik.data.api.AppError;
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.webpush.QrScannerActivity;
import pl.szczodrzynski.edziennik.utils.Utils;
import static pl.szczodrzynski.edziennik.data.api.AppError.CODE_EXPIRED_TOKEN;
@ -53,6 +51,7 @@ public class LoginVulcanFragment extends Fragment {
private NavController nav;
private FragmentLoginVulcanBinding b;
private static final String TAG = "LoginVulcan";
private ErrorSnackbar errorSnackbar;
public LoginVulcanFragment() { }
@ -62,6 +61,7 @@ public class LoginVulcanFragment extends Fragment {
if (getActivity() != null) {
app = (App) getActivity().getApplicationContext();
nav = Navigation.findNavController(getActivity(), R.id.nav_host_fragment);
errorSnackbar = ((LoginActivity) getActivity()).errorSnackbar;
}
else {
return null;
@ -76,9 +76,9 @@ public class LoginVulcanFragment extends Fragment {
assert getActivity() != null;
view.postDelayed(() -> {
AppError error = LoginActivity.error;
ApiError error = LoginActivity.error;
if (error != null) {
switch (error.errorCode) {
switch (error.getErrorCode()) {
case CODE_INVALID_TOKEN:
b.loginTokenLayout.setError(getString(R.string.login_error_incorrect_token));
break;
@ -89,28 +89,14 @@ public class LoginVulcanFragment extends Fragment {
b.loginSymbolLayout.setError(getString(R.string.login_error_incorrect_symbol));
break;
case CODE_INVALID_PIN:
if (!"?".equals(error.errorText)) {
/*if (!"?".equals(error.errorText)) {
b.loginPinLayout.setError(getString(R.string.login_error_incorrect_pin_format, error.errorText));
break;
}
}*/
b.loginPinLayout.setError(getString(R.string.login_error_incorrect_pin));
break;
default:
CafeBar.builder(getActivity())
.to(b.root)
.content(getString(R.string.login_error, error.asReadableString(getActivity())))
.autoDismiss(false)
.positiveText(R.string.ok)
.onPositive(CafeBar::dismiss)
.floating(true)
.swipeToDismiss(true)
.neutralText(R.string.more)
.onNeutral(cafeBar -> app.apiEdziennik.guiShowErrorDialog(getActivity(), error, R.string.error_details))
.negativeText(R.string.report)
.onNegative((cafeBar -> app.apiEdziennik.guiReportError(getActivity(), error, null)))
.show();
break;
}
errorSnackbar.addError(error).show();
LoginActivity.error = null;
}
}, 100);

View File

@ -4,7 +4,6 @@ import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Menu;
import android.view.MotionEvent;
@ -13,7 +12,6 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.databinding.DataBindingUtil;
import com.afollestad.materialdialogs.MaterialDialog;
@ -35,12 +33,6 @@ import java.util.List;
import pl.szczodrzynski.edziennik.App;
import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.data.api.AppError;
import pl.szczodrzynski.edziennik.data.api.Edziennik;
import pl.szczodrzynski.edziennik.data.api.interfaces.SyncCallback;
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore;
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile;
import pl.szczodrzynski.edziennik.data.db.modules.profiles.ProfileFull;
import pl.szczodrzynski.edziennik.data.db.modules.teachers.Teacher;
import pl.szczodrzynski.edziennik.databinding.ActivityComposeMessageBinding;
import pl.szczodrzynski.edziennik.utils.Colors;
@ -63,7 +55,7 @@ public class MessagesComposeActivity extends AppCompatActivity {
b = DataBindingUtil.inflate(getLayoutInflater(), R.layout.activity_compose_message, null, false);
setContentView(b.getRoot());
composeInfo = Edziennik.getApi(app, app.profile.getLoginStoreType()).getComposeInfo(app.profile);
/*composeInfo = Edziennik.getApi(app, app.profile.getLoginStoreType()).getComposeInfo(app.profile);
Toolbar toolbar = b.toolbar;
setSupportActionBar(toolbar);
@ -99,7 +91,7 @@ public class MessagesComposeActivity extends AppCompatActivity {
MessagesComposeSuggestionAdapter adapter = new MessagesComposeSuggestionAdapter(this, teachers);
//ArrayAdapter<Teacher> adapter = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, teachers);
b.nachoTextView.setAdapter(adapter);
});
});*/
/*app.db.teacherDao().getAllTeachers(App.profileId).observe(this, teachers -> {
});*/

View File

@ -1,17 +1,12 @@
package pl.szczodrzynski.edziennik.ui.modules.messages;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.text.Html;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -19,12 +14,18 @@ import android.widget.FrameLayout;
import android.widget.ProgressBar;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.graphics.drawable.RoundedBitmapDrawable;
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.Fragment;
import com.afollestad.materialdialogs.MaterialDialog;
import com.google.android.material.chip.Chip;
import com.mikepenz.iconics.IconicsColor;
import com.mikepenz.iconics.IconicsDrawable;
import com.mikepenz.iconics.IconicsSize;
import com.mikepenz.iconics.typeface.IIcon;
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial;
import com.theartofdev.edmodo.cropper.CropImage;
@ -39,36 +40,15 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.graphics.drawable.RoundedBitmapDrawable;
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.Fragment;
import im.wangchao.mhttp.Response;
import im.wangchao.mhttp.callback.FileCallbackHandler;
import pl.szczodrzynski.edziennik.App;
import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.MainActivity;
import pl.szczodrzynski.edziennik.data.api.Edziennik;
import pl.szczodrzynski.edziennik.data.api.AppError;
import pl.szczodrzynski.edziennik.data.api.interfaces.SyncCallback;
import pl.szczodrzynski.edziennik.databinding.MessagesDetailsBinding;
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore;
import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.data.db.modules.messages.MessageFull;
import pl.szczodrzynski.edziennik.data.db.modules.messages.MessageRecipientFull;
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile;
import pl.szczodrzynski.edziennik.data.db.modules.profiles.ProfileFull;
import pl.szczodrzynski.edziennik.utils.models.Date;
import pl.szczodrzynski.edziennik.utils.models.Time;
import pl.szczodrzynski.edziennik.utils.Anim;
import pl.szczodrzynski.edziennik.databinding.MessagesDetailsBinding;
import pl.szczodrzynski.edziennik.utils.Themes;
import pl.szczodrzynski.edziennik.utils.Utils;
import static android.app.Activity.RESULT_OK;
import static android.view.Gravity.CENTER_VERTICAL;
import static android.view.Gravity.END;
import static pl.szczodrzynski.edziennik.utils.Utils.getResizedBitmap;
import static pl.szczodrzynski.edziennik.utils.Utils.getStringFromFile;
import static pl.szczodrzynski.edziennik.utils.Utils.readableFileSize;
@ -108,7 +88,7 @@ public class MessagesDetailsFragment extends Fragment {
b.messageContent.setVisibility(View.GONE);
if (messageId != -1) {
/*if (messageId != -1) {
AsyncTask.execute(() -> {
if (app == null || app.profile == null || activity == null || b == null || !isAdded())
return;
@ -286,7 +266,7 @@ public class MessagesDetailsFragment extends Fragment {
});
});
}
}*/
// click to expand subject and sender
b.messageSubject.setOnClickListener(v -> {
@ -359,7 +339,7 @@ public class MessagesDetailsFragment extends Fragment {
File storageDir = Utils.getStorageDir();
Edziennik.getApi(app, app.profile.getLoginStoreType()).getAttachment(activity, new SyncCallback() {
/*Edziennik.getApi(app, app.profile.getLoginStoreType()).getAttachment(activity, new SyncCallback() {
@Override
public void onLoginFirst(List<Profile> profileList, LoginStore loginStore) {
@ -437,7 +417,7 @@ public class MessagesDetailsFragment extends Fragment {
}
})
.build()
.enqueue());
.enqueue());*/
}
@Subscribe(threadMode = ThreadMode.POSTING)

View File

@ -8,16 +8,17 @@
android:orientation="vertical"
android:visibility="visible">
<LinearLayout
<Space
android:layout_width="0dp"
android:layout_height="32dp" />
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:visibility="visible">
<Space
android:layout_width="0dp"
android:layout_height="32dp" />
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
@ -30,7 +31,7 @@
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/nav_login" />
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<!--<io.codetail.widget.RevealFrameLayout
android:layout_width="match_parent"

View File

@ -0,0 +1,276 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) Kuba Szczodrzyński 2019-11-13.
-->
<resources>
<string name="error_50" translatable="false">ERROR_REQUEST_FAILURE</string>
<string name="error_51" translatable="false">ERROR_REQUEST_HTTP_400</string>
<string name="error_52" translatable="false">ERROR_REQUEST_HTTP_401</string>
<string name="error_53" translatable="false">ERROR_REQUEST_HTTP_403</string>
<string name="error_54" translatable="false">ERROR_REQUEST_HTTP_404</string>
<string name="error_55" translatable="false">ERROR_REQUEST_HTTP_405</string>
<string name="error_56" translatable="false">ERROR_REQUEST_HTTP_410</string>
<string name="error_57" translatable="false">ERROR_REQUEST_HTTP_500</string>
<string name="error_100" translatable="false">ERROR_RESPONSE_EMPTY</string>
<string name="error_101" translatable="false">ERROR_LOGIN_DATA_MISSING</string>
<string name="error_102" translatable="false">ERROR_LOGIN_DATA_INVALID</string>
<string name="error_105" translatable="false">ERROR_PROFILE_MISSING</string>
<string name="error_110" translatable="false">ERROR_INVALID_LOGIN_MODE</string>
<string name="error_111" translatable="false">ERROR_LOGIN_METHOD_NOT_SATISFIED</string>
<string name="error_112" translatable="false">ERROR_NOT_IMPLEMENTED</string>
<string name="error_115" translatable="false">ERROR_NO_STUDENTS_IN_ACCOUNT</string>
<string name="error_120" translatable="false">CODE_INTERNAL_LIBRUS_ACCOUNT_410</string>
<string name="error_121" translatable="false">CODE_INTERNAL_LIBRUS_SYNERGIA_EXPIRED</string>
<string name="error_124" translatable="false">ERROR_LOGIN_LIBRUS_API_CAPTCHA_NEEDED</string>
<string name="error_125" translatable="false">ERROR_LOGIN_LIBRUS_API_CONNECTION_PROBLEMS</string>
<string name="error_126" translatable="false">ERROR_LOGIN_LIBRUS_API_INVALID_CLIENT</string>
<string name="error_127" translatable="false">ERROR_LOGIN_LIBRUS_API_REG_ACCEPT_NEEDED</string>
<string name="error_128" translatable="false">ERROR_LOGIN_LIBRUS_API_CHANGE_PASSWORD_ERROR</string>
<string name="error_129" translatable="false">ERROR_LOGIN_LIBRUS_API_PASSWORD_CHANGE_REQUIRED</string>
<string name="error_130" translatable="false">ERROR_LOGIN_LIBRUS_API_INVALID_LOGIN</string>
<string name="error_131" translatable="false">ERROR_LOGIN_LIBRUS_API_OTHER</string>
<string name="error_132" translatable="false">ERROR_LOGIN_LIBRUS_PORTAL_CSRF_MISSING</string>
<string name="error_133" translatable="false">ERROR_LOGIN_LIBRUS_PORTAL_NOT_ACTIVATED</string>
<string name="error_134" translatable="false">ERROR_LOGIN_LIBRUS_PORTAL_ACTION_ERROR</string>
<string name="error_139" translatable="false">ERROR_LOGIN_LIBRUS_PORTAL_SYNERGIA_TOKEN_MISSING</string>
<string name="error_140" translatable="false">ERROR_LIBRUS_API_TOKEN_EXPIRED</string>
<string name="error_141" translatable="false">ERROR_LIBRUS_API_INSUFFICIENT_SCOPES</string>
<string name="error_142" translatable="false">ERROR_LIBRUS_API_OTHER</string>
<string name="error_143" translatable="false">ERROR_LIBRUS_API_ACCESS_DENIED</string>
<string name="error_144" translatable="false">ERROR_LIBRUS_API_RESOURCE_NOT_FOUND</string>
<string name="error_145" translatable="false">ERROR_LIBRUS_API_DATA_NOT_FOUND</string>
<string name="error_146" translatable="false">ERROR_LIBRUS_API_TIMETABLE_NOT_PUBLIC</string>
<string name="error_147" translatable="false">ERROR_LIBRUS_API_RESOURCE_ACCESS_DENIED</string>
<string name="error_148" translatable="false">ERROR_LIBRUS_API_INVALID_REQUEST_PARAMS</string>
<string name="error_149" translatable="false">ERROR_LIBRUS_API_INCORRECT_ENDPOINT</string>
<string name="error_150" translatable="false">ERROR_LIBRUS_API_LUCKY_NUMBER_NOT_ACTIVE</string>
<string name="error_151" translatable="false">ERROR_LIBRUS_API_NOTES_NOT_ACTIVE</string>
<string name="error_152" translatable="false">ERROR_LOGIN_LIBRUS_SYNERGIA_NO_TOKEN</string>
<string name="error_153" translatable="false">ERROR_LOGIN_LIBRUS_SYNERGIA_TOKEN_INVALID</string>
<string name="error_154" translatable="false">ERROR_LOGIN_LIBRUS_SYNERGIA_NO_SESSION_ID</string>
<string name="error_155" translatable="false">ERROR_LIBRUS_MESSAGES_ACCESS_DENIED</string>
<string name="error_156" translatable="false">ERROR_LIBRUS_SYNERGIA_ACCESS_DENIED</string>
<string name="error_157" translatable="false">ERROR_LOGIN_LIBRUS_MESSAGES_NO_SESSION_ID</string>
<string name="error_158" translatable="false">ERROR_LIBRUS_PORTAL_ACCESS_DENIED</string>
<string name="error_159" translatable="false">ERROR_LIBRUS_PORTAL_API_DISABLED</string>
<string name="error_160" translatable="false">ERROR_LIBRUS_PORTAL_SYNERGIA_DISCONNECTED</string>
<string name="error_161" translatable="false">ERROR_LIBRUS_PORTAL_OTHER</string>
<string name="error_162" translatable="false">ERROR_LIBRUS_PORTAL_SYNERGIA_NOT_FOUND</string>
<string name="error_163" translatable="false">ERROR_LOGIN_LIBRUS_PORTAL_OTHER</string>
<string name="error_164" translatable="false">ERROR_LOGIN_LIBRUS_PORTAL_CODE_EXPIRED</string>
<string name="error_165" translatable="false">ERROR_LOGIN_LIBRUS_PORTAL_CODE_REVOKED</string>
<string name="error_166" translatable="false">ERROR_LOGIN_LIBRUS_PORTAL_NO_CLIENT_ID</string>
<string name="error_167" translatable="false">ERROR_LOGIN_LIBRUS_PORTAL_NO_CODE</string>
<string name="error_168" translatable="false">ERROR_LOGIN_LIBRUS_PORTAL_NO_REFRESH</string>
<string name="error_169" translatable="false">ERROR_LOGIN_LIBRUS_PORTAL_NO_REDIRECT</string>
<string name="error_170" translatable="false">ERROR_LOGIN_LIBRUS_PORTAL_UNSUPPORTED_GRANT</string>
<string name="error_171" translatable="false">ERROR_LOGIN_LIBRUS_PORTAL_INVALID_CLIENT_ID</string>
<string name="error_172" translatable="false">ERROR_LOGIN_LIBRUS_PORTAL_REFRESH_INVALID</string>
<string name="error_173" translatable="false">ERROR_LOGIN_LIBRUS_PORTAL_REFRESH_REVOKED</string>
<string name="error_174" translatable="false">ERROR_LIBRUS_SYNERGIA_OTHER</string>
<string name="error_175" translatable="false">ERROR_LIBRUS_SYNERGIA_MAINTENANCE</string>
<string name="error_201" translatable="false">ERROR_LOGIN_MOBIDZIENNIK_WEB_INVALID_LOGIN</string>
<string name="error_202" translatable="false">ERROR_LOGIN_MOBIDZIENNIK_WEB_OLD_PASSWORD</string>
<string name="error_203" translatable="false">ERROR_LOGIN_MOBIDZIENNIK_WEB_INVALID_DEVICE</string>
<string name="error_204" translatable="false">ERROR_LOGIN_MOBIDZIENNIK_WEB_ARCHIVED</string>
<string name="error_205" translatable="false">ERROR_LOGIN_MOBIDZIENNIK_WEB_MAINTENANCE</string>
<string name="error_206" translatable="false">ERROR_LOGIN_MOBIDZIENNIK_WEB_INVALID_ADDRESS</string>
<string name="error_210" translatable="false">ERROR_LOGIN_MOBIDZIENNIK_WEB_OTHER</string>
<string name="error_211" translatable="false">ERROR_MOBIDZIENNIK_WEB_ACCESS_DENIED</string>
<string name="error_212" translatable="false">ERROR_MOBIDZIENNIK_WEB_NO_SESSION_KEY</string>
<string name="error_216" translatable="false">ERROR_MOBIDZIENNIK_WEB_NO_SESSION_VALUE</string>
<string name="error_213" translatable="false">ERROR_MOBIDZIENNIK_WEB_NO_SERVER_ID</string>
<string name="error_214" translatable="false">ERROR_MOBIDZIENNIK_WEB_INVALID_RESPONSE</string>
<string name="error_215" translatable="false">ERROR_LOGIN_MOBIDZIENNIK_WEB_NO_SESSION_ID</string>
<string name="error_301" translatable="false">ERROR_LOGIN_VULCAN_INVALID_SYMBOL</string>
<string name="error_302" translatable="false">ERROR_LOGIN_VULCAN_INVALID_TOKEN</string>
<string name="error_309" translatable="false">ERROR_LOGIN_VULCAN_INVALID_PIN</string>
<string name="error_310" translatable="false">ERROR_LOGIN_VULCAN_INVALID_PIN_0_REMAINING</string>
<string name="error_311" translatable="false">ERROR_LOGIN_VULCAN_INVALID_PIN_1_REMAINING</string>
<string name="error_312" translatable="false">ERROR_LOGIN_VULCAN_INVALID_PIN_2_REMAINING</string>
<string name="error_321" translatable="false">ERROR_LOGIN_VULCAN_EXPIRED_TOKEN</string>
<string name="error_322" translatable="false">ERROR_LOGIN_VULCAN_OTHER</string>
<string name="error_330" translatable="false">ERROR_LOGIN_VULCAN_ONLY_KINDERGARTEN</string>
<string name="error_331" translatable="false">ERROR_LOGIN_VULCAN_NO_PUPILS</string>
<string name="error_340" translatable="false">ERROR_VULCAN_API_MAINTENANCE</string>
<string name="error_341" translatable="false">ERROR_VULCAN_API_BAD_REQUEST</string>
<string name="error_342" translatable="false">ERROR_VULCAN_API_OTHER</string>
<string name="error_401" translatable="false">ERROR_LOGIN_IDZIENNIK_WEB_INVALID_LOGIN</string>
<string name="error_402" translatable="false">ERROR_LOGIN_IDZIENNIK_WEB_INVALID_SCHOOL_NAME</string>
<string name="error_403" translatable="false">ERROR_LOGIN_IDZIENNIK_WEB_PASSWORD_CHANGE_NEEDED</string>
<string name="error_404" translatable="false">ERROR_LOGIN_IDZIENNIK_WEB_MAINTENANCE</string>
<string name="error_405" translatable="false">ERROR_LOGIN_IDZIENNIK_WEB_SERVER_ERROR</string>
<string name="error_410" translatable="false">ERROR_LOGIN_IDZIENNIK_WEB_OTHER</string>
<string name="error_411" translatable="false">ERROR_LOGIN_IDZIENNIK_WEB_API_NO_ACCESS</string>
<string name="error_420" translatable="false">ERROR_LOGIN_IDZIENNIK_WEB_NO_SESSION</string>
<string name="error_421" translatable="false">ERROR_LOGIN_IDZIENNIK_WEB_NO_AUTH</string>
<string name="error_422" translatable="false">ERROR_LOGIN_IDZIENNIK_WEB_NO_BEARER</string>
<string name="error_430" translatable="false">ERROR_IDZIENNIK_WEB_ACCESS_DENIED</string>
<string name="error_431" translatable="false">ERROR_IDZIENNIK_WEB_OTHER</string>
<string name="error_432" translatable="false">ERROR_IDZIENNIK_WEB_MAINTENANCE</string>
<string name="error_433" translatable="false">ERROR_IDZIENNIK_WEB_SERVER_ERROR</string>
<string name="error_434" translatable="false">ERROR_IDZIENNIK_WEB_PASSWORD_CHANGE_NEEDED</string>
<string name="error_440" translatable="false">ERROR_LOGIN_IDZIENNIK_FIRST_NO_SCHOOL_YEAR</string>
<string name="error_441" translatable="false">ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA</string>
<string name="error_450" translatable="false">ERROR_IDZIENNIK_API_ACCESS_DENIED</string>
<string name="error_451" translatable="false">ERROR_IDZIENNIK_API_OTHER</string>
<string name="error_801" translatable="false">ERROR_TEMPLATE_WEB_OTHER</string>
<string name="error_900" translatable="false">EXCEPTION_API_TASK</string>
<string name="error_901" translatable="false">EXCEPTION_LOGIN_LIBRUS_API_TOKEN</string>
<string name="error_902" translatable="false">EXCEPTION_LOGIN_LIBRUS_PORTAL_TOKEN</string>
<string name="error_903" translatable="false">EXCEPTION_LIBRUS_PORTAL_SYNERGIA_TOKEN</string>
<string name="error_904" translatable="false">EXCEPTION_LIBRUS_API_REQUEST</string>
<string name="error_905" translatable="false">EXCEPTION_LIBRUS_SYNERGIA_REQUEST</string>
<string name="error_906" translatable="false">EXCEPTION_MOBIDZIENNIK_WEB_REQUEST</string>
<string name="error_907" translatable="false">EXCEPTION_VULCAN_API_REQUEST</string>
<string name="error_910" translatable="false">EXCEPTION_NOTIFY_AND_SYNC</string>
<string name="error_911" translatable="false">EXCEPTION_LIBRUS_MESSAGES_REQUEST</string>
<string name="error_912" translatable="false">EXCEPTION_IDZIENNIK_WEB_REQUEST</string>
<string name="error_913" translatable="false">EXCEPTION_IDZIENNIK_WEB_API_REQUEST</string>
<string name="error_914" translatable="false">EXCEPTION_IDZIENNIK_API_REQUEST</string>
<string name="error_1201" translatable="false">LOGIN_NO_ARGUMENTS</string>
<string name="error_50_reason">Błąd odpowiedzi serwera</string>
<string name="error_51_reason">Błąd serwera: nieprawidłowe zapytanie</string>
<string name="error_52_reason">Błąd serwera: odmowa dostępu</string>
<string name="error_53_reason">Błąd serwera: dostęp zabroniony</string>
<string name="error_54_reason">Błąd serwera: plik nie znaleziony</string>
<string name="error_55_reason">Błąd serwera: nieprawidłowa metoda zapytania</string>
<string name="error_56_reason">Błąd serwera: odpowiedź niedostępna</string>
<string name="error_57_reason">Wewnętrzny błąd serwera</string>
<string name="error_100_reason">Brak odpowiedzi serwera</string>
<string name="error_101_reason">Dane logowania niekompletne</string>
<string name="error_102_reason">Nieprawidłowe dane logowania</string>
<string name="error_105_reason">Profil nie został ustawiony</string>
<string name="error_110_reason">Nieprawidłowy sposób logowania</string>
<string name="error_111_reason">Nie można wywołać metody logowania</string>
<string name="error_112_reason">Nie zaimplementowano</string>
<string name="error_115_reason">Brak uczniów przypisanych do konta</string>
<string name="error_120_reason">CODE_INTERNAL_LIBRUS_ACCOUNT_410</string>
<string name="error_121_reason">CODE_INTERNAL_LIBRUS_SYNERGIA_EXPIRED</string>
<string name="error_124_reason">Wymagane wypełnienie CAPTCHA</string>
<string name="error_125_reason">Problem z połączeniem</string>
<string name="error_126_reason">Nieprawidłowy identyfikator klienta</string>
<string name="error_127_reason">Wymagana akceptacja regulaminu</string>
<string name="error_128_reason">Błąd zmiany hasła</string>
<string name="error_129_reason">Wymagana zmiana hasła</string>
<string name="error_130_reason">Nieprawidłowe dane logowania</string>
<string name="error_131_reason">Inny błąd logowania do API</string>
<string name="error_132_reason">Brak tokenu CSRF</string>
<string name="error_133_reason">Konto LIBRUS nie zostało aktywowane</string>
<string name="error_134_reason">Inny błąd logowania do Portalu LIBRUS</string>
<string name="error_139_reason">Nie znaleziono tokenu Synergia</string>
<string name="error_140_reason">Token API wygasł</string>
<string name="error_141_reason">Niewystarczające uprawnienia</string>
<string name="error_142_reason">Inny błąd API</string>
<string name="error_143_reason">Odmowa dostępu do API</string>
<string name="error_144_reason">Nie znaleziono zasobu API</string>
<string name="error_145_reason">Brak danych</string>
<string name="error_146_reason">Plan lekcji nie jest publiczny</string>
<string name="error_147_reason">Brak dostępu do zasobu</string>
<string name="error_148_reason">Nieprawidłowe parametry</string>
<string name="error_149_reason">Nieprawidłowy zasób</string>
<string name="error_150_reason">Szczęśliwy numerek nie jest aktywny</string>
<string name="error_151_reason">Uwagi nie są publiczne</string>
<string name="error_152_reason">Brak tokenu logowania Synergia</string>
<string name="error_153_reason">Nieprawidłowy token logowania Synergia</string>
<string name="error_154_reason">Brak ID sesji Synergia</string>
<string name="error_155_reason">Brak dostępu do Wiadomości</string>
<string name="error_156_reason">Brak dostępu do Synergii</string>
<string name="error_157_reason">Brak ID sesji Wiadomości</string>
<string name="error_158_reason">Odmowa dostępu do Portalu Librus</string>
<string name="error_159_reason">API Portalu Librus wyłączone</string>
<string name="error_160_reason">Konto Synergia zostało rozłączone</string>
<string name="error_161_reason">Inny błąd Portalu Librus</string>
<string name="error_162_reason">Nie znaleziono konta Synergia</string>
<string name="error_163_reason">Inny błąd logowania do Portalu Librus</string>
<string name="error_164_reason">ERROR_LOGIN_LIBRUS_PORTAL_CODE_EXPIRED</string>
<string name="error_165_reason">ERROR_LOGIN_LIBRUS_PORTAL_CODE_REVOKED</string>
<string name="error_166_reason">ERROR_LOGIN_LIBRUS_PORTAL_NO_CLIENT_ID</string>
<string name="error_167_reason">ERROR_LOGIN_LIBRUS_PORTAL_NO_CODE</string>
<string name="error_168_reason">ERROR_LOGIN_LIBRUS_PORTAL_NO_REFRESH</string>
<string name="error_169_reason">ERROR_LOGIN_LIBRUS_PORTAL_NO_REDIRECT</string>
<string name="error_170_reason">ERROR_LOGIN_LIBRUS_PORTAL_UNSUPPORTED_GRANT</string>
<string name="error_171_reason">ERROR_LOGIN_LIBRUS_PORTAL_INVALID_CLIENT_ID</string>
<string name="error_172_reason">ERROR_LOGIN_LIBRUS_PORTAL_REFRESH_INVALID</string>
<string name="error_173_reason">ERROR_LOGIN_LIBRUS_PORTAL_REFRESH_REVOKED</string>
<string name="error_174_reason">ERROR_LIBRUS_SYNERGIA_OTHER</string>
<string name="error_175_reason">ERROR_LIBRUS_SYNERGIA_MAINTENANCE</string>
<string name="error_201_reason">ERROR_LOGIN_MOBIDZIENNIK_WEB_INVALID_LOGIN</string>
<string name="error_202_reason">ERROR_LOGIN_MOBIDZIENNIK_WEB_OLD_PASSWORD</string>
<string name="error_203_reason">ERROR_LOGIN_MOBIDZIENNIK_WEB_INVALID_DEVICE</string>
<string name="error_204_reason">ERROR_LOGIN_MOBIDZIENNIK_WEB_ARCHIVED</string>
<string name="error_205_reason">ERROR_LOGIN_MOBIDZIENNIK_WEB_MAINTENANCE</string>
<string name="error_206_reason">ERROR_LOGIN_MOBIDZIENNIK_WEB_INVALID_ADDRESS</string>
<string name="error_210_reason">ERROR_LOGIN_MOBIDZIENNIK_WEB_OTHER</string>
<string name="error_211_reason">ERROR_MOBIDZIENNIK_WEB_ACCESS_DENIED</string>
<string name="error_212_reason">ERROR_MOBIDZIENNIK_WEB_NO_SESSION_KEY</string>
<string name="error_216_reason">ERROR_MOBIDZIENNIK_WEB_NO_SESSION_VALUE</string>
<string name="error_213_reason">ERROR_MOBIDZIENNIK_WEB_NO_SERVER_ID</string>
<string name="error_214_reason">ERROR_MOBIDZIENNIK_WEB_INVALID_RESPONSE</string>
<string name="error_215_reason">ERROR_LOGIN_MOBIDZIENNIK_WEB_NO_SESSION_ID</string>
<string name="error_301_reason">ERROR_LOGIN_VULCAN_INVALID_SYMBOL</string>
<string name="error_302_reason">ERROR_LOGIN_VULCAN_INVALID_TOKEN</string>
<string name="error_309_reason">ERROR_LOGIN_VULCAN_INVALID_PIN</string>
<string name="error_310_reason">ERROR_LOGIN_VULCAN_INVALID_PIN_0_REMAINING</string>
<string name="error_311_reason">ERROR_LOGIN_VULCAN_INVALID_PIN_1_REMAINING</string>
<string name="error_312_reason">ERROR_LOGIN_VULCAN_INVALID_PIN_2_REMAINING</string>
<string name="error_321_reason">ERROR_LOGIN_VULCAN_EXPIRED_TOKEN</string>
<string name="error_322_reason">ERROR_LOGIN_VULCAN_OTHER</string>
<string name="error_330_reason">ERROR_LOGIN_VULCAN_ONLY_KINDERGARTEN</string>
<string name="error_331_reason">ERROR_LOGIN_VULCAN_NO_PUPILS</string>
<string name="error_340_reason">ERROR_VULCAN_API_MAINTENANCE</string>
<string name="error_341_reason">ERROR_VULCAN_API_BAD_REQUEST</string>
<string name="error_342_reason">ERROR_VULCAN_API_OTHER</string>
<string name="error_401_reason">ERROR_LOGIN_IDZIENNIK_WEB_INVALID_LOGIN</string>
<string name="error_402_reason">ERROR_LOGIN_IDZIENNIK_WEB_INVALID_SCHOOL_NAME</string>
<string name="error_403_reason">ERROR_LOGIN_IDZIENNIK_WEB_PASSWORD_CHANGE_NEEDED</string>
<string name="error_404_reason">ERROR_LOGIN_IDZIENNIK_WEB_MAINTENANCE</string>
<string name="error_405_reason">ERROR_LOGIN_IDZIENNIK_WEB_SERVER_ERROR</string>
<string name="error_410_reason">ERROR_LOGIN_IDZIENNIK_WEB_OTHER</string>
<string name="error_411_reason">ERROR_LOGIN_IDZIENNIK_WEB_API_NO_ACCESS</string>
<string name="error_420_reason">ERROR_LOGIN_IDZIENNIK_WEB_NO_SESSION</string>
<string name="error_421_reason">ERROR_LOGIN_IDZIENNIK_WEB_NO_AUTH</string>
<string name="error_422_reason">ERROR_LOGIN_IDZIENNIK_WEB_NO_BEARER</string>
<string name="error_430_reason">ERROR_IDZIENNIK_WEB_ACCESS_DENIED</string>
<string name="error_431_reason">ERROR_IDZIENNIK_WEB_OTHER</string>
<string name="error_432_reason">ERROR_IDZIENNIK_WEB_MAINTENANCE</string>
<string name="error_433_reason">ERROR_IDZIENNIK_WEB_SERVER_ERROR</string>
<string name="error_434_reason">ERROR_IDZIENNIK_WEB_PASSWORD_CHANGE_NEEDED</string>
<string name="error_440_reason">ERROR_LOGIN_IDZIENNIK_FIRST_NO_SCHOOL_YEAR</string>
<string name="error_441_reason">ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA</string>
<string name="error_450_reason">ERROR_IDZIENNIK_API_ACCESS_DENIED</string>
<string name="error_451_reason">ERROR_IDZIENNIK_API_OTHER</string>
<string name="error_801_reason">ERROR_TEMPLATE_WEB_OTHER</string>
<string name="error_900_reason">EXCEPTION_API_TASK</string>
<string name="error_901_reason">EXCEPTION_LOGIN_LIBRUS_API_TOKEN</string>
<string name="error_902_reason">EXCEPTION_LOGIN_LIBRUS_PORTAL_TOKEN</string>
<string name="error_903_reason">EXCEPTION_LIBRUS_PORTAL_SYNERGIA_TOKEN</string>
<string name="error_904_reason">EXCEPTION_LIBRUS_API_REQUEST</string>
<string name="error_905_reason">EXCEPTION_LIBRUS_SYNERGIA_REQUEST</string>
<string name="error_906_reason">EXCEPTION_MOBIDZIENNIK_WEB_REQUEST</string>
<string name="error_907_reason">EXCEPTION_VULCAN_API_REQUEST</string>
<string name="error_910_reason">EXCEPTION_NOTIFY_AND_SYNC</string>
<string name="error_911_reason">EXCEPTION_LIBRUS_MESSAGES_REQUEST</string>
<string name="error_912_reason">EXCEPTION_IDZIENNIK_WEB_REQUEST</string>
<string name="error_913_reason">EXCEPTION_IDZIENNIK_WEB_API_REQUEST</string>
<string name="error_914_reason">EXCEPTION_IDZIENNIK_API_REQUEST</string>
<string name="error_1201_reason">Nie podano parametrów</string>
</resources>

View File

@ -1023,4 +1023,5 @@
<string name="dialog_event_manual_date_next_week">następny %s (%s)</string>
<string name="dialog_event_manual_no_lessons">Nie ma lekcji tego dnia</string>
<string name="dialog_profile_remove_success">Profil został usunięty.</string>
<string name="snackbar_error_text">Wystąpił błąd</string>
</resources>