mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2026-07-31 07:44:24 +02:00
Lenovo Watch X (Plus): Fix language setting
This commit is contained in:
@@ -127,7 +127,7 @@ public class GBApplication extends Application {
|
|||||||
private static SharedPreferences sharedPrefs;
|
private static SharedPreferences sharedPrefs;
|
||||||
private static final String PREFS_VERSION = "shared_preferences_version";
|
private static final String PREFS_VERSION = "shared_preferences_version";
|
||||||
//if preferences have to be migrated, increment the following and add the migration logic in migratePrefs below; see http://stackoverflow.com/questions/16397848/how-can-i-migrate-android-preferences-with-a-new-version
|
//if preferences have to be migrated, increment the following and add the migration logic in migratePrefs below; see http://stackoverflow.com/questions/16397848/how-can-i-migrate-android-preferences-with-a-new-version
|
||||||
private static final int CURRENT_PREFS_VERSION = 48;
|
private static final int CURRENT_PREFS_VERSION = 49;
|
||||||
|
|
||||||
private static final LimitedQueue<Integer, String> mIDSenderLookup = new LimitedQueue<>(16);
|
private static final LimitedQueue<Integer, String> mIDSenderLookup = new LimitedQueue<>(16);
|
||||||
private static GBPrefs prefs;
|
private static GBPrefs prefs;
|
||||||
@@ -1956,6 +1956,36 @@ public class GBApplication extends Application {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (oldVersion < 49) {
|
||||||
|
// Migrate Lenovo Watch X language preference
|
||||||
|
try (DBHandler db = acquireDB()) {
|
||||||
|
final DaoSession daoSession = db.getDaoSession();
|
||||||
|
final List<Device> activeDevices = DBHelper.getActiveDevices(daoSession);
|
||||||
|
|
||||||
|
for (Device dbDevice : activeDevices) {
|
||||||
|
final DeviceType deviceType = DeviceType.fromName(dbDevice.getTypeName());
|
||||||
|
if (deviceType == WATCHXPLUS) {
|
||||||
|
final SharedPreferences deviceSharedPrefs = GBApplication.getDeviceSpecificSharedPrefs(dbDevice.getIdentifier());
|
||||||
|
final String languageVal = deviceSharedPrefs.getString("language", "1");
|
||||||
|
final SharedPreferences.Editor deviceSharedPrefsEdit = deviceSharedPrefs.edit();
|
||||||
|
switch (languageVal) {
|
||||||
|
case "0":
|
||||||
|
deviceSharedPrefsEdit.putString("language", "zh_CN");
|
||||||
|
break;
|
||||||
|
case "1":
|
||||||
|
default:
|
||||||
|
deviceSharedPrefsEdit.putString("language", "en_US");
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
deviceSharedPrefsEdit.apply();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "Failed to migrate prefs to version 49", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
editor.putString(PREFS_VERSION, Integer.toString(CURRENT_PREFS_VERSION));
|
editor.putString(PREFS_VERSION, Integer.toString(CURRENT_PREFS_VERSION));
|
||||||
editor.apply();
|
editor.apply();
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-8
@@ -343,16 +343,18 @@ public class DeviceSpecificSettingsFragment extends AbstractPreferenceFragment i
|
|||||||
final ListPreference languageListPreference = findPreference("language");
|
final ListPreference languageListPreference = findPreference("language");
|
||||||
if (languageListPreference != null) {
|
if (languageListPreference != null) {
|
||||||
final String[] supportedLanguages = coordinator.getSupportedLanguageSettings(device);
|
final String[] supportedLanguages = coordinator.getSupportedLanguageSettings(device);
|
||||||
CharSequence[] entries = languageListPreference.getEntries();
|
if (supportedLanguages != null) {
|
||||||
CharSequence[] values = languageListPreference.getEntryValues();
|
CharSequence[] entries = languageListPreference.getEntries();
|
||||||
for (int i = entries.length - 1; i >= 0; i--) {
|
CharSequence[] values = languageListPreference.getEntryValues();
|
||||||
if (!ArrayUtils.contains(supportedLanguages, values[i])) {
|
for (int i = entries.length - 1; i >= 0; i--) {
|
||||||
entries = ArrayUtils.remove(entries, i);
|
if (!ArrayUtils.contains(supportedLanguages, values[i])) {
|
||||||
values = ArrayUtils.remove(values, i);
|
entries = ArrayUtils.remove(entries, i);
|
||||||
|
values = ArrayUtils.remove(values, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
languageListPreference.setEntries(entries);
|
||||||
|
languageListPreference.setEntryValues(values);
|
||||||
}
|
}
|
||||||
languageListPreference.setEntries(entries);
|
|
||||||
languageListPreference.setEntryValues(values);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String disconnectNotificationState = prefs.getString(PREF_DISCONNECT_NOTIFICATION, PREF_DO_NOT_DISTURB_OFF);
|
String disconnectNotificationState = prefs.getString(PREF_DISCONNECT_NOTIFICATION, PREF_DO_NOT_DISTURB_OFF);
|
||||||
|
|||||||
+10
-44
@@ -19,9 +19,7 @@ package nodomain.freeyourgadget.gadgetbridge.devices.lenovo.watchxplus;
|
|||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.bluetooth.le.ScanFilter;
|
import android.bluetooth.le.ScanFilter;
|
||||||
import android.content.Context;
|
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.ParcelUuid;
|
import android.os.ParcelUuid;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
@@ -41,7 +39,6 @@ import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
|
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractBLEDeviceCoordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractBLEDeviceCoordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.lenovo.LenovoWatchCalibrationActivity;
|
import nodomain.freeyourgadget.gadgetbridge.devices.lenovo.LenovoWatchCalibrationActivity;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.lenovo.LenovoWatchPairingActivity;
|
import nodomain.freeyourgadget.gadgetbridge.devices.lenovo.LenovoWatchPairingActivity;
|
||||||
@@ -50,23 +47,20 @@ import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.DeviceSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.DeviceSupport;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.ServiceDeviceSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.ServiceDeviceSupport;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.lenovo.watchxplus.WatchXPlusDeviceSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.lenovo.watchxplus.WatchXPlusDeviceSupport;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
|
||||||
|
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.GBApplication.getContext;
|
import static nodomain.freeyourgadget.gadgetbridge.GBApplication.getContext;
|
||||||
|
|
||||||
|
|
||||||
public class WatchXPlusDeviceCoordinator extends AbstractBLEDeviceCoordinator {
|
public class WatchXPlusDeviceCoordinator extends AbstractBLEDeviceCoordinator {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(WatchXPlusDeviceSupport.class);
|
private static final Logger LOG = LoggerFactory.getLogger(WatchXPlusDeviceCoordinator.class);
|
||||||
|
|
||||||
private static final int FindPhone_ON = -1;
|
private static final int FindPhone_ON = -1;
|
||||||
public static final int FindPhone_OFF = 0;
|
public static final int FindPhone_OFF = 0;
|
||||||
public static boolean isBPCalibrated = false;
|
public static boolean isBPCalibrated = false;
|
||||||
|
|
||||||
private static final Prefs prefs = GBApplication.getPrefs();
|
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Collection<? extends ScanFilter> createBLEScanFilters() {
|
public Collection<? extends ScanFilter> createBLEScanFilters() {
|
||||||
@@ -85,7 +79,6 @@ public class WatchXPlusDeviceCoordinator extends AbstractBLEDeviceCoordinator {
|
|||||||
return BONDING_STYLE_NONE;
|
return BONDING_STYLE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supports(GBDeviceCandidate candidate) {
|
public boolean supports(GBDeviceCandidate candidate) {
|
||||||
String macAddress = candidate.getMacAddress().toUpperCase();
|
String macAddress = candidate.getMacAddress().toUpperCase();
|
||||||
@@ -110,6 +103,14 @@ public class WatchXPlusDeviceCoordinator extends AbstractBLEDeviceCoordinator {
|
|||||||
return LenovoWatchPairingActivity.class;
|
return LenovoWatchPairingActivity.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getSupportedLanguageSettings(final GBDevice device) {
|
||||||
|
return new String[]{
|
||||||
|
"zh_CN",
|
||||||
|
"en_US",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsActivityDataFetching() {
|
public boolean supportsActivityDataFetching() {
|
||||||
return true;
|
return true;
|
||||||
@@ -125,16 +126,6 @@ public class WatchXPlusDeviceCoordinator extends AbstractBLEDeviceCoordinator {
|
|||||||
return new WatchXPlusSampleProvider(device, session);
|
return new WatchXPlusSampleProvider(device, session);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public InstallHandler findInstallHandler(Uri uri, Context context) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean supportsScreenshots(final GBDevice device) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getAlarmSlotCount(GBDevice device) {
|
public int getAlarmSlotCount(GBDevice device) {
|
||||||
return 3;
|
return 3;
|
||||||
@@ -150,31 +141,11 @@ public class WatchXPlusDeviceCoordinator extends AbstractBLEDeviceCoordinator {
|
|||||||
return "Lenovo";
|
return "Lenovo";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean supportsAppsManagement(final GBDevice device) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<? extends Activity> getAppsManagementActivity() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean supportsCalendarEvents() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean supportsRealtimeData() { return false; }
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsWeather() {
|
public boolean supportsWeather() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean supportsFindDevice() { return false; }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int[] getSupportedDeviceSpecificSettings(GBDevice device) {
|
public int[] getSupportedDeviceSpecificSettings(GBDevice device) {
|
||||||
return new int[]{
|
return new int[]{
|
||||||
@@ -208,7 +179,6 @@ public class WatchXPlusDeviceCoordinator extends AbstractBLEDeviceCoordinator {
|
|||||||
public static int getFindPhone(SharedPreferences sharedPrefs) {
|
public static int getFindPhone(SharedPreferences sharedPrefs) {
|
||||||
String findPhone = sharedPrefs.getString(DeviceSettingsPreferenceConst.PREF_FIND_PHONE, getContext().getString(R.string.p_off));
|
String findPhone = sharedPrefs.getString(DeviceSettingsPreferenceConst.PREF_FIND_PHONE, getContext().getString(R.string.p_off));
|
||||||
|
|
||||||
assert findPhone != null;
|
|
||||||
if (findPhone.equals(getContext().getString(R.string.p_off))) {
|
if (findPhone.equals(getContext().getString(R.string.p_off))) {
|
||||||
return FindPhone_OFF;
|
return FindPhone_OFF;
|
||||||
} else if (findPhone.equals(getContext().getString(R.string.p_on))) {
|
} else if (findPhone.equals(getContext().getString(R.string.p_on))) {
|
||||||
@@ -220,7 +190,6 @@ public class WatchXPlusDeviceCoordinator extends AbstractBLEDeviceCoordinator {
|
|||||||
int iDuration;
|
int iDuration;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
assert duration != null;
|
|
||||||
iDuration = Integer.valueOf(duration);
|
iDuration = Integer.valueOf(duration);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
iDuration = 60;
|
iDuration = 60;
|
||||||
@@ -243,7 +212,6 @@ public class WatchXPlusDeviceCoordinator extends AbstractBLEDeviceCoordinator {
|
|||||||
SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(deviceAddress);
|
SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(deviceAddress);
|
||||||
String doNotDisturb = prefs.getString(DeviceSettingsPreferenceConst.PREF_DO_NOT_DISTURB_NOAUTO, getContext().getString(R.string.p_off));
|
String doNotDisturb = prefs.getString(DeviceSettingsPreferenceConst.PREF_DO_NOT_DISTURB_NOAUTO, getContext().getString(R.string.p_off));
|
||||||
|
|
||||||
assert doNotDisturb != null;
|
|
||||||
if (doNotDisturb.equals(getContext().getString(R.string.p_off))) {
|
if (doNotDisturb.equals(getContext().getString(R.string.p_off))) {
|
||||||
LOG.info(" DND is disabled ");
|
LOG.info(" DND is disabled ");
|
||||||
return false;
|
return false;
|
||||||
@@ -300,13 +268,11 @@ public class WatchXPlusDeviceCoordinator extends AbstractBLEDeviceCoordinator {
|
|||||||
return LenovoWatchCalibrationActivity.class;
|
return LenovoWatchCalibrationActivity.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getDeviceNameResource() {
|
public int getDeviceNameResource() {
|
||||||
return R.string.devicetype_watchxplus;
|
return R.string.devicetype_watchxplus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getDefaultIconResource() {
|
public int getDefaultIconResource() {
|
||||||
return R.drawable.ic_device_watchxplus;
|
return R.drawable.ic_device_watchxplus;
|
||||||
|
|||||||
+11
-11
@@ -871,6 +871,7 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
|
|||||||
setPowerMode();
|
setPowerMode();
|
||||||
break;
|
break;
|
||||||
case DeviceSettingsPreferenceConst.PREF_LANGUAGE:
|
case DeviceSettingsPreferenceConst.PREF_LANGUAGE:
|
||||||
|
case DeviceSettingsPreferenceConst.PREF_TIMEFORMAT:
|
||||||
setLanguageAndTimeFormat(builder);
|
setLanguageAndTimeFormat(builder);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -893,16 +894,13 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
|
|||||||
case DeviceSettingsPreferenceConst.PREF_DISCONNECTNOTIF_NOSHED:
|
case DeviceSettingsPreferenceConst.PREF_DISCONNECTNOTIF_NOSHED:
|
||||||
setDisconnectReminder(builder);
|
setDisconnectReminder(builder);
|
||||||
break;
|
break;
|
||||||
case DeviceSettingsPreferenceConst.PREF_TIMEFORMAT:
|
|
||||||
setLanguageAndTimeFormat(builder);
|
|
||||||
break;
|
|
||||||
case DeviceSettingsPreferenceConst.PREF_DO_NOT_DISTURB_NOAUTO:
|
case DeviceSettingsPreferenceConst.PREF_DO_NOT_DISTURB_NOAUTO:
|
||||||
setDNDHours(builder);
|
setDNDHours(builder);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
builder.queue(getQueue());
|
builder.queue(getQueue());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
LOG.error("Failed to send config", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2033,21 +2031,23 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
|
|||||||
buildCommand(WatchXPlusConstants.CMD_ALTITUDE,
|
buildCommand(WatchXPlusConstants.CMD_ALTITUDE,
|
||||||
WatchXPlusConstants.WRITE_VALUE,
|
WatchXPlusConstants.WRITE_VALUE,
|
||||||
bArr));
|
bArr));
|
||||||
LOG.info(" setAltitude: " + mAltitude);
|
LOG.info(" setAltitude: {}", mAltitude);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set time format
|
// set time format
|
||||||
private void setLanguageAndTimeFormat(TransactionBuilder transactionBuilder) {
|
private void setLanguageAndTimeFormat(TransactionBuilder transactionBuilder) {
|
||||||
byte setLanguage, setTimeMode;
|
byte setLanguage, setTimeMode;
|
||||||
String languageString = GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress()).getString(DeviceSettingsPreferenceConst.PREF_LANGUAGE, "1");
|
String languageString = GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress()).getString(DeviceSettingsPreferenceConst.PREF_LANGUAGE, "en_US");
|
||||||
if (languageString == null || languageString.equals("1")) {
|
switch (languageString) {
|
||||||
setLanguage = 0x01;
|
case "zh_CN":
|
||||||
} else {
|
setLanguage = 0x00;
|
||||||
setLanguage = 0x00;
|
break;
|
||||||
|
case "en_US":
|
||||||
|
default:
|
||||||
|
setLanguage = 0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
String timeformatString = GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress()).getString(DeviceSettingsPreferenceConst.PREF_TIMEFORMAT, "1");
|
String timeformatString = GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress()).getString(DeviceSettingsPreferenceConst.PREF_TIMEFORMAT, "1");
|
||||||
assert timeformatString != null;
|
|
||||||
if (timeformatString.equals(getContext().getString(R.string.p_timeformat_24h))) {
|
if (timeformatString.equals(getContext().getString(R.string.p_timeformat_24h))) {
|
||||||
setTimeMode = WatchXPlusConstants.ARG_SET_TIMEMODE_24H;
|
setTimeMode = WatchXPlusConstants.ARG_SET_TIMEMODE_24H;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -168,14 +168,6 @@
|
|||||||
<item>never</item>
|
<item>never</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<string-array name="language_only_EN_CH">
|
|
||||||
<item name="0">@string/simplified_chinese</item>
|
|
||||||
<item name="1">@string/english</item>
|
|
||||||
</string-array>
|
|
||||||
<string-array name="language_only_EN_CH_values">
|
|
||||||
<item>0</item>
|
|
||||||
<item>1</item>
|
|
||||||
</string-array>
|
|
||||||
<string-array name="sensors_bp_cal">
|
<string-array name="sensors_bp_cal">
|
||||||
<item name="0">@string/prefs_sensors_button_bp_calibration</item>
|
<item name="0">@string/prefs_sensors_button_bp_calibration</item>
|
||||||
<item name="1">@string/Cancel</item>
|
<item name="1">@string/Cancel</item>
|
||||||
|
|||||||
@@ -55,14 +55,6 @@
|
|||||||
android:icon="@drawable/ic_settings"
|
android:icon="@drawable/ic_settings"
|
||||||
android:key="pref_category_device_spec_settings"
|
android:key="pref_category_device_spec_settings"
|
||||||
android:title="@string/pref_header_device_spec_settings">
|
android:title="@string/pref_header_device_spec_settings">
|
||||||
<ListPreference
|
|
||||||
android:icon="@drawable/ic_language"
|
|
||||||
android:defaultValue="1"
|
|
||||||
android:title="@string/pref_title_language"
|
|
||||||
android:entries="@array/language_only_EN_CH"
|
|
||||||
android:entryValues="@array/language_only_EN_CH_values"
|
|
||||||
android:key="language"
|
|
||||||
android:summary="%s" />
|
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
android:icon="@drawable/ic_access_time"
|
android:icon="@drawable/ic_access_time"
|
||||||
android:defaultValue="false"
|
android:defaultValue="false"
|
||||||
|
|||||||
Reference in New Issue
Block a user