mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-06-12 21:27:43 +02:00
fix(SponsorBlock): Show create new segment error messages using a dialog
This commit is contained in:
@ -7,11 +7,13 @@ import static app.revanced.extension.music.sponsorblock.objects.CategoryBehaviou
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import app.revanced.extension.music.patches.utils.PatchStatus;
|
||||
import app.revanced.extension.music.sponsorblock.SponsorBlockSettings;
|
||||
import app.revanced.extension.shared.settings.BaseSettings;
|
||||
import app.revanced.extension.shared.settings.BooleanSetting;
|
||||
import app.revanced.extension.shared.settings.FloatSetting;
|
||||
import app.revanced.extension.shared.settings.IntegerSetting;
|
||||
import app.revanced.extension.shared.settings.LongSetting;
|
||||
import app.revanced.extension.shared.settings.Setting;
|
||||
import app.revanced.extension.shared.settings.StringSetting;
|
||||
import app.revanced.extension.shared.utils.Utils;
|
||||
|
||||
@ -218,6 +220,14 @@ public class Settings extends BaseSettings {
|
||||
// SB settings not exported
|
||||
public static final LongSetting SB_LAST_VIP_CHECK = new LongSetting("sb_last_vip_check", 0L, false, false);
|
||||
|
||||
static {
|
||||
// region SB import/export callbacks
|
||||
|
||||
Setting.addImportExportCallback(SponsorBlockSettings.SB_IMPORT_EXPORT_CALLBACK);
|
||||
|
||||
// endregion
|
||||
}
|
||||
|
||||
public static final String OPEN_DEFAULT_APP_SETTINGS = "revanced_default_app_settings";
|
||||
|
||||
/**
|
||||
|
@ -236,7 +236,7 @@ public class ReVancedPreferenceFragment extends PreferenceFragment {
|
||||
.setView(container)
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.setNeutralButton(str("revanced_extended_settings_import_copy"), (dialog, which) -> Utils.setClipboard(textView.getText().toString(), str("revanced_share_copy_settings_success")))
|
||||
.setPositiveButton(str("revanced_extended_settings_import"), (dialog, which) -> importSettings(textView.getText().toString()))
|
||||
.setPositiveButton(str("revanced_extended_settings_import"), (dialog, which) -> importSettings(activity, textView.getText().toString()))
|
||||
.show();
|
||||
} catch (Exception ex) {
|
||||
Logger.printException(() -> "importExportEditTextDialogBuilder failure", ex);
|
||||
@ -326,7 +326,7 @@ public class ReVancedPreferenceFragment extends PreferenceFragment {
|
||||
bufferedReader.close();
|
||||
fileReader.close();
|
||||
|
||||
final boolean restartNeeded = Setting.importFromJSON(sb.toString(), false);
|
||||
final boolean restartNeeded = Setting.importFromJSON(context, sb.toString());
|
||||
if (restartNeeded) {
|
||||
ReVancedPreferenceFragment.showRebootDialog();
|
||||
}
|
||||
@ -336,13 +336,13 @@ public class ReVancedPreferenceFragment extends PreferenceFragment {
|
||||
}
|
||||
}
|
||||
|
||||
private void importSettings(String replacementSettings) {
|
||||
private void importSettings(Activity mActivity, String replacementSettings) {
|
||||
try {
|
||||
existingSettings = Setting.exportToJson(null);
|
||||
if (replacementSettings.equals(existingSettings)) {
|
||||
return;
|
||||
}
|
||||
final boolean restartNeeded = Setting.importFromJSON(replacementSettings, false);
|
||||
final boolean restartNeeded = Setting.importFromJSON(mActivity, replacementSettings);
|
||||
if (restartNeeded) {
|
||||
ReVancedPreferenceFragment.showRebootDialog();
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
package app.revanced.extension.music.sponsorblock;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@ -9,6 +12,17 @@ import app.revanced.extension.music.sponsorblock.objects.SegmentCategory;
|
||||
import app.revanced.extension.shared.settings.Setting;
|
||||
|
||||
public class SponsorBlockSettings {
|
||||
|
||||
public static final Setting.ImportExportCallback SB_IMPORT_EXPORT_CALLBACK = new Setting.ImportExportCallback() {
|
||||
@Override
|
||||
public void settingsImported(@Nullable Context context) {
|
||||
SegmentCategory.loadAllCategoriesFromSettings();
|
||||
}
|
||||
@Override
|
||||
public void settingsExported(@Nullable Context context) {
|
||||
}
|
||||
};
|
||||
|
||||
private static boolean initialized;
|
||||
|
||||
/**
|
||||
@ -42,11 +56,4 @@ public class SponsorBlockSettings {
|
||||
|
||||
SegmentCategory.updateEnabledCategories();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates internal data based on {@link Setting} values.
|
||||
*/
|
||||
public static void updateFromImportedSettings() {
|
||||
SegmentCategory.loadAllCategoriesFromSettings();
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import android.content.Context;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
@ -74,6 +73,30 @@ public abstract class Setting<T> {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for importing/exporting settings.
|
||||
*/
|
||||
public interface ImportExportCallback {
|
||||
/**
|
||||
* Called after all settings have been imported.
|
||||
*/
|
||||
void settingsImported(@Nullable Context context);
|
||||
|
||||
/**
|
||||
* Called after all settings have been exported.
|
||||
*/
|
||||
void settingsExported(@Nullable Context context);
|
||||
}
|
||||
|
||||
private static final List<ImportExportCallback> importExportCallbacks = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Adds a callback for {@link #importFromJSON(Context, String)} and {@link #exportToJson(Context)}.
|
||||
*/
|
||||
public static void addImportExportCallback(@NonNull ImportExportCallback callback) {
|
||||
importExportCallbacks.add(Objects.requireNonNull(callback));
|
||||
}
|
||||
|
||||
/**
|
||||
* All settings that were instantiated.
|
||||
* When a new setting is created, it is automatically added to this list.
|
||||
@ -232,6 +255,10 @@ public abstract class Setting<T> {
|
||||
* Migrate a setting value if the path is renamed but otherwise the old and new settings are identical.
|
||||
*/
|
||||
public static <T> void migrateOldSettingToNew(@NonNull Setting<T> oldSetting, @NonNull Setting<T> newSetting) {
|
||||
if (oldSetting == newSetting) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
if (!oldSetting.isSetToDefault()) {
|
||||
Logger.printInfo(() -> "Migrating old setting value: " + oldSetting + " into replacement setting: " + newSetting);
|
||||
newSetting.save(oldSetting.value);
|
||||
@ -335,7 +362,7 @@ public abstract class Setting<T> {
|
||||
return value.equals(defaultValue);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return key + "=" + get();
|
||||
@ -393,8 +420,9 @@ public abstract class Setting<T> {
|
||||
setting.writeToJSON(json, importExportKey);
|
||||
}
|
||||
}
|
||||
if (alertDialogContext != null) {
|
||||
app.revanced.extension.youtube.sponsorblock.SponsorBlockSettings.showExportWarningIfNeeded(alertDialogContext);
|
||||
|
||||
for (ImportExportCallback callback : importExportCallbacks) {
|
||||
callback.settingsExported(alertDialogContext);
|
||||
}
|
||||
|
||||
if (json.length() == 0) {
|
||||
@ -412,14 +440,10 @@ public abstract class Setting<T> {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean importFromJSON(@NonNull String settingsJsonString) {
|
||||
return importFromJSON(settingsJsonString, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return if any settings that require a reboot were changed.
|
||||
*/
|
||||
public static boolean importFromJSON(@NonNull String settingsJsonString, boolean isYouTube) {
|
||||
public static boolean importFromJSON(@NonNull Context alertDialogContext, @NonNull String settingsJsonString) {
|
||||
try {
|
||||
if (!settingsJsonString.matches("[\\s\\S]*\\{")) {
|
||||
settingsJsonString = '{' + settingsJsonString + '}'; // Restore outer JSON braces
|
||||
@ -445,15 +469,8 @@ public abstract class Setting<T> {
|
||||
}
|
||||
}
|
||||
|
||||
// SB Enum categories are saved using StringSettings.
|
||||
// Which means they need to reload again if changed by other code (such as here).
|
||||
// This call could be removed by creating a custom Setting class that manages the
|
||||
// "String <-> Enum" logic or by adding an event hook of when settings are imported.
|
||||
// But for now this is simple and works.
|
||||
if (isYouTube) {
|
||||
app.revanced.extension.youtube.sponsorblock.SponsorBlockSettings.updateFromImportedSettings();
|
||||
} else {
|
||||
app.revanced.extension.music.sponsorblock.SponsorBlockSettings.updateFromImportedSettings();
|
||||
for (ImportExportCallback callback : importExportCallbacks) {
|
||||
callback.settingsImported(alertDialogContext);
|
||||
}
|
||||
|
||||
Utils.showToastLong(numberOfSettingsImported == 0
|
||||
|
@ -77,20 +77,20 @@ public class ImportExportPreference extends EditTextPreference implements Prefer
|
||||
Utils.setClipboard(getEditText().getText().toString())
|
||||
).setPositiveButton(
|
||||
str("revanced_extended_settings_import"), (dialog, which) ->
|
||||
importSettings(getEditText().getText().toString())
|
||||
importSettings(builder.getContext(), getEditText().getText().toString())
|
||||
);
|
||||
} catch (Exception ex) {
|
||||
Logger.printException(() -> "onPrepareDialogBuilder failure", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void importSettings(String replacementSettings) {
|
||||
private void importSettings(Context context, String replacementSettings) {
|
||||
try {
|
||||
if (replacementSettings.equals(existingSettings)) {
|
||||
return;
|
||||
}
|
||||
AbstractPreferenceFragment.settingImportInProgress = true;
|
||||
final boolean rebootNeeded = Setting.importFromJSON(replacementSettings);
|
||||
final boolean rebootNeeded = Setting.importFromJSON(context, replacementSettings);
|
||||
if (rebootNeeded) {
|
||||
AbstractPreferenceFragment.showRestartDialog(getContext());
|
||||
}
|
||||
|
@ -662,5 +662,11 @@ public class Settings extends BaseSettings {
|
||||
}
|
||||
}
|
||||
// endregion
|
||||
|
||||
// region SB import/export callbacks
|
||||
|
||||
Setting.addImportExportCallback(SponsorBlockSettings.SB_IMPORT_EXPORT_CALLBACK);
|
||||
|
||||
// endregion
|
||||
}
|
||||
}
|
||||
|
@ -76,19 +76,19 @@ public class ImportExportPreference extends EditTextPreference implements Prefer
|
||||
builder.setNeutralButton(str("revanced_extended_settings_import_copy"), (dialog, which) ->
|
||||
Utils.setClipboard(getEditText().getText().toString(), str("revanced_share_copy_settings_success")))
|
||||
.setPositiveButton(str("revanced_extended_settings_import"), (dialog, which) ->
|
||||
importSettings(getEditText().getText().toString()));
|
||||
importSettings(builder.getContext(), getEditText().getText().toString()));
|
||||
} catch (Exception ex) {
|
||||
Logger.printException(() -> "onPrepareDialogBuilder failure", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void importSettings(String replacementSettings) {
|
||||
private void importSettings(Context context, String replacementSettings) {
|
||||
try {
|
||||
if (replacementSettings.equals(existingSettings)) {
|
||||
return;
|
||||
}
|
||||
ReVancedPreferenceFragment.settingImportInProgress = true;
|
||||
final boolean rebootNeeded = Setting.importFromJSON(replacementSettings, true);
|
||||
final boolean rebootNeeded = Setting.importFromJSON(context, replacementSettings);
|
||||
if (rebootNeeded) {
|
||||
AbstractPreferenceFragment.showRestartDialog(getContext());
|
||||
}
|
||||
|
@ -675,7 +675,7 @@ public class ReVancedPreferenceFragment extends PreferenceFragment {
|
||||
bufferedReader.close();
|
||||
fileReader.close();
|
||||
|
||||
final boolean restartNeeded = Setting.importFromJSON(sb.toString(), true);
|
||||
final boolean restartNeeded = Setting.importFromJSON(context, sb.toString());
|
||||
if (restartNeeded) {
|
||||
showRestartDialog(getActivity());
|
||||
}
|
||||
|
@ -338,7 +338,7 @@ public class SponsorBlockSettingsPreference extends ReVancedPreferenceFragment {
|
||||
Utils.showToastLong(str("revanced_sb_stats_username_changed"));
|
||||
} else {
|
||||
preference.setText(userName); // revert to previous
|
||||
Utils.showToastLong(errorMessage);
|
||||
SponsorBlockUtils.showErrorDialog(errorMessage);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -28,6 +28,18 @@ public class SponsorBlockSettings {
|
||||
*/
|
||||
private static final int SB_PRIVATE_USER_ID_MINIMUM_LENGTH = 30;
|
||||
|
||||
public static final Setting.ImportExportCallback SB_IMPORT_EXPORT_CALLBACK = new Setting.ImportExportCallback() {
|
||||
@Override
|
||||
public void settingsImported(@Nullable Context context) {
|
||||
SegmentCategory.loadAllCategoriesFromSettings();
|
||||
SponsorBlockSettingsPreference.updateSegmentCategories();
|
||||
}
|
||||
@Override
|
||||
public void settingsExported(@Nullable Context context) {
|
||||
showExportWarningIfNeeded(context);
|
||||
}
|
||||
};
|
||||
|
||||
public static void importDesktopSettings(@NonNull String json) {
|
||||
Utils.verifyOnMainThread();
|
||||
try {
|
||||
@ -162,7 +174,7 @@ public class SponsorBlockSettings {
|
||||
/**
|
||||
* Export the categories using flatten json (no embedded dictionaries or arrays).
|
||||
*/
|
||||
public static void showExportWarningIfNeeded(@Nullable Context dialogContext) {
|
||||
private static void showExportWarningIfNeeded(@Nullable Context dialogContext) {
|
||||
Utils.verifyOnMainThread();
|
||||
initialize();
|
||||
|
||||
@ -193,6 +205,7 @@ public class SponsorBlockSettings {
|
||||
// Verify url is only the server address and does not contain a path such as: "https://sponsor.ajay.app/api/"
|
||||
// Could use Patterns.compile, but this is simpler
|
||||
final int lastDotIndex = serverAddress.lastIndexOf('.');
|
||||
//noinspection RedundantIfStatement
|
||||
if (lastDotIndex != -1 && serverAddress.substring(lastDotIndex).contains("/")) {
|
||||
return false;
|
||||
}
|
||||
@ -235,12 +248,4 @@ public class SponsorBlockSettings {
|
||||
|
||||
SegmentCategory.updateEnabledCategories();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates internal data based on {@link Setting} values.
|
||||
*/
|
||||
public static void updateFromImportedSettings() {
|
||||
SegmentCategory.loadAllCategoriesFromSettings();
|
||||
SponsorBlockSettingsPreference.updateSegmentCategories();
|
||||
}
|
||||
}
|
||||
|
@ -360,6 +360,16 @@ public class SponsorBlockUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static void showErrorDialog(String dialogMessage) {
|
||||
Utils.runOnMainThreadNowOrLater(() ->
|
||||
new AlertDialog.Builder(SponsorBlockViewController.getOverLaysViewGroupContext())
|
||||
.setMessage(dialogMessage)
|
||||
.setPositiveButton(android.R.string.ok, null)
|
||||
.setCancelable(false)
|
||||
.show()
|
||||
);
|
||||
}
|
||||
|
||||
public static void onEditByHandClicked() {
|
||||
try {
|
||||
Utils.verifyOnMainThread();
|
||||
|
@ -24,6 +24,7 @@ import app.revanced.extension.shared.utils.Logger;
|
||||
import app.revanced.extension.shared.utils.Utils;
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
import app.revanced.extension.youtube.sponsorblock.SponsorBlockSettings;
|
||||
import app.revanced.extension.youtube.sponsorblock.SponsorBlockUtils;
|
||||
import app.revanced.extension.youtube.sponsorblock.objects.SegmentCategory;
|
||||
import app.revanced.extension.youtube.sponsorblock.objects.SponsorSegment;
|
||||
import app.revanced.extension.youtube.sponsorblock.objects.SponsorSegment.SegmentVote;
|
||||
@ -125,25 +126,28 @@ public class SBRequester {
|
||||
HttpURLConnection connection = getConnectionFromRoute(SBRoutes.SUBMIT_SEGMENTS, privateUserId, videoId, category, start, end, duration);
|
||||
final int responseCode = connection.getResponseCode();
|
||||
|
||||
final String messageToToast = switch (responseCode) {
|
||||
String userMessage = switch (responseCode) {
|
||||
case HTTP_STATUS_CODE_SUCCESS -> str("revanced_sb_submit_succeeded");
|
||||
case 409 -> str("revanced_sb_submit_failed_duplicate");
|
||||
case 403 ->
|
||||
str("revanced_sb_submit_failed_forbidden", Requester.parseErrorStringAndDisconnect(connection));
|
||||
case 403 -> str("revanced_sb_submit_failed_forbidden",
|
||||
Requester.parseErrorStringAndDisconnect(connection));
|
||||
case 429 -> str("revanced_sb_submit_failed_rate_limit");
|
||||
case 400 ->
|
||||
str("revanced_sb_submit_failed_invalid", Requester.parseErrorStringAndDisconnect(connection));
|
||||
default ->
|
||||
str("revanced_sb_submit_failed_unknown_error", responseCode, connection.getResponseMessage());
|
||||
case 400 -> str("revanced_sb_submit_failed_invalid",
|
||||
Requester.parseErrorStringAndDisconnect(connection));
|
||||
default -> str("revanced_sb_submit_failed_unknown_error",
|
||||
responseCode, connection.getResponseMessage());
|
||||
};
|
||||
Utils.showToastLong(messageToToast);
|
||||
// Message might be about the users account or an error too large to show in a toast.
|
||||
// Use a dialog instead.
|
||||
SponsorBlockUtils.showErrorDialog(userMessage);
|
||||
} catch (SocketTimeoutException ex) {
|
||||
// Always show, even if show connection toasts is turned off
|
||||
Logger.printDebug(() -> "Timeout", ex);
|
||||
Utils.showToastLong(str("revanced_sb_submit_failed_timeout"));
|
||||
} catch (IOException ex) {
|
||||
Logger.printDebug(() -> "IOException", ex);
|
||||
Utils.showToastLong(str("revanced_sb_submit_failed_unknown_error", 0, ex.getMessage()));
|
||||
} catch (Exception ex) {
|
||||
Logger.printException(() -> "failed to submit segments", ex);
|
||||
Logger.printException(() -> "failed to submit segments", ex); // Should never happen.
|
||||
}
|
||||
}
|
||||
|
||||
@ -184,19 +188,22 @@ public class SBRequester {
|
||||
: getConnectionFromRoute(SBRoutes.VOTE_ON_SEGMENT_QUALITY, uuid, segmentUuid, String.valueOf(voteOption.apiVoteType));
|
||||
final int responseCode = connection.getResponseCode();
|
||||
|
||||
String userMessage;
|
||||
switch (responseCode) {
|
||||
case HTTP_STATUS_CODE_SUCCESS:
|
||||
Logger.printDebug(() -> "Vote success for segment: " + segment);
|
||||
break;
|
||||
return;
|
||||
case 403:
|
||||
Utils.showToastLong(
|
||||
str("revanced_sb_vote_failed_forbidden", Requester.parseErrorStringAndDisconnect(connection)));
|
||||
userMessage = str("revanced_sb_vote_failed_forbidden",
|
||||
Requester.parseErrorStringAndDisconnect(connection));
|
||||
break;
|
||||
default:
|
||||
Utils.showToastLong(
|
||||
str("revanced_sb_vote_failed_unknown_error", responseCode, connection.getResponseMessage()));
|
||||
userMessage = str("revanced_sb_vote_failed_unknown_error",
|
||||
responseCode, connection.getResponseMessage());
|
||||
break;
|
||||
}
|
||||
|
||||
SponsorBlockUtils.showErrorDialog(userMessage);
|
||||
} catch (SocketTimeoutException ex) {
|
||||
Utils.showToastShort(str("revanced_sb_vote_failed_timeout"));
|
||||
} catch (IOException ex) {
|
||||
|
Reference in New Issue
Block a user