Merge branch 'whatsnew-n-stuff' into 'master'
support new WhatsNew fields in index-v1 (+ l18n fixes) Closes #910 and #941 See merge request !474
This commit is contained in:
commit
c73a65656a
@ -226,6 +226,7 @@ public final class Languages {
|
|||||||
new Locale("da"),
|
new Locale("da"),
|
||||||
new Locale("el"),
|
new Locale("el"),
|
||||||
new Locale("es"),
|
new Locale("es"),
|
||||||
|
new Locale("eo"),
|
||||||
new Locale("et"),
|
new Locale("et"),
|
||||||
new Locale("eu"),
|
new Locale("eu"),
|
||||||
new Locale("fa"),
|
new Locale("fa"),
|
||||||
@ -267,6 +268,7 @@ public final class Languages {
|
|||||||
new Locale("sk"),
|
new Locale("sk"),
|
||||||
new Locale("sl"),
|
new Locale("sl"),
|
||||||
new Locale("sn"),
|
new Locale("sn"),
|
||||||
|
new Locale("sq"),
|
||||||
new Locale("sr"),
|
new Locale("sr"),
|
||||||
new Locale("sv"),
|
new Locale("sv"),
|
||||||
new Locale("sw"),
|
new Locale("sw"),
|
||||||
|
@ -110,7 +110,10 @@ public class App extends ValueObject implements Comparable<App>, Parcelable {
|
|||||||
|
|
||||||
public String description;
|
public String description;
|
||||||
|
|
||||||
public String video;
|
/**
|
||||||
|
* A descriptive text for what has changed in this version.
|
||||||
|
*/
|
||||||
|
public String whatsNew;
|
||||||
|
|
||||||
public String featureGraphic;
|
public String featureGraphic;
|
||||||
public String promoGraphic;
|
public String promoGraphic;
|
||||||
@ -133,6 +136,8 @@ public class App extends ValueObject implements Comparable<App>, Parcelable {
|
|||||||
|
|
||||||
public String sourceCode;
|
public String sourceCode;
|
||||||
|
|
||||||
|
public String video;
|
||||||
|
|
||||||
public String changelog;
|
public String changelog;
|
||||||
|
|
||||||
public String donate;
|
public String donate;
|
||||||
@ -230,6 +235,9 @@ public class App extends ValueObject implements Comparable<App>, Parcelable {
|
|||||||
case Cols.DESCRIPTION:
|
case Cols.DESCRIPTION:
|
||||||
description = cursor.getString(i);
|
description = cursor.getString(i);
|
||||||
break;
|
break;
|
||||||
|
case Cols.WHATSNEW:
|
||||||
|
whatsNew = cursor.getString(i);
|
||||||
|
break;
|
||||||
case Cols.LICENSE:
|
case Cols.LICENSE:
|
||||||
license = cursor.getString(i);
|
license = cursor.getString(i);
|
||||||
break;
|
break;
|
||||||
@ -248,6 +256,9 @@ public class App extends ValueObject implements Comparable<App>, Parcelable {
|
|||||||
case Cols.SOURCE_CODE:
|
case Cols.SOURCE_CODE:
|
||||||
sourceCode = cursor.getString(i);
|
sourceCode = cursor.getString(i);
|
||||||
break;
|
break;
|
||||||
|
case Cols.VIDEO:
|
||||||
|
video = cursor.getString(i);
|
||||||
|
break;
|
||||||
case Cols.CHANGELOG:
|
case Cols.CHANGELOG:
|
||||||
changelog = cursor.getString(i);
|
changelog = cursor.getString(i);
|
||||||
break;
|
break;
|
||||||
@ -387,8 +398,10 @@ public class App extends ValueObject implements Comparable<App>, Parcelable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if key starts with Upper case, its set by humans
|
// if key starts with Upper case, its set by humans
|
||||||
// Name, Summary, Description existed before localization so their values can be set directly
|
|
||||||
video = getLocalizedEntry(localized, localesToUse, "Video");
|
video = getLocalizedEntry(localized, localesToUse, "Video");
|
||||||
|
whatsNew = getLocalizedEntry(localized, localesToUse, "WhatsNew");
|
||||||
|
// Name, Summary, Description existed before localization so they shouldn't replace
|
||||||
|
// non-localized old data format with a null or blank string
|
||||||
String value = getLocalizedEntry(localized, localesToUse, "Name");
|
String value = getLocalizedEntry(localized, localesToUse, "Name");
|
||||||
if (!TextUtils.isEmpty(value)) {
|
if (!TextUtils.isEmpty(value)) {
|
||||||
name = value;
|
name = value;
|
||||||
@ -397,7 +410,7 @@ public class App extends ValueObject implements Comparable<App>, Parcelable {
|
|||||||
if (!TextUtils.isEmpty(value)) {
|
if (!TextUtils.isEmpty(value)) {
|
||||||
summary = value;
|
summary = value;
|
||||||
}
|
}
|
||||||
description = getLocalizedEntry(localized, localesToUse, "Description");
|
value = getLocalizedEntry(localized, localesToUse, "Description");
|
||||||
if (!TextUtils.isEmpty(value)) {
|
if (!TextUtils.isEmpty(value)) {
|
||||||
description = value;
|
description = value;
|
||||||
}
|
}
|
||||||
@ -733,12 +746,14 @@ public class App extends ValueObject implements Comparable<App>, Parcelable {
|
|||||||
values.put(Cols.ICON_URL, iconUrl);
|
values.put(Cols.ICON_URL, iconUrl);
|
||||||
values.put(Cols.ICON_URL_LARGE, iconUrlLarge);
|
values.put(Cols.ICON_URL_LARGE, iconUrlLarge);
|
||||||
values.put(Cols.DESCRIPTION, description);
|
values.put(Cols.DESCRIPTION, description);
|
||||||
|
values.put(Cols.WHATSNEW, whatsNew);
|
||||||
values.put(Cols.LICENSE, license);
|
values.put(Cols.LICENSE, license);
|
||||||
values.put(Cols.AUTHOR_NAME, authorName);
|
values.put(Cols.AUTHOR_NAME, authorName);
|
||||||
values.put(Cols.AUTHOR_EMAIL, authorEmail);
|
values.put(Cols.AUTHOR_EMAIL, authorEmail);
|
||||||
values.put(Cols.WEBSITE, webSite);
|
values.put(Cols.WEBSITE, webSite);
|
||||||
values.put(Cols.ISSUE_TRACKER, issueTracker);
|
values.put(Cols.ISSUE_TRACKER, issueTracker);
|
||||||
values.put(Cols.SOURCE_CODE, sourceCode);
|
values.put(Cols.SOURCE_CODE, sourceCode);
|
||||||
|
values.put(Cols.VIDEO, video);
|
||||||
values.put(Cols.CHANGELOG, changelog);
|
values.put(Cols.CHANGELOG, changelog);
|
||||||
values.put(Cols.DONATE, donate);
|
values.put(Cols.DONATE, donate);
|
||||||
values.put(Cols.BITCOIN, bitcoin);
|
values.put(Cols.BITCOIN, bitcoin);
|
||||||
@ -887,12 +902,14 @@ public class App extends ValueObject implements Comparable<App>, Parcelable {
|
|||||||
dest.writeString(this.summary);
|
dest.writeString(this.summary);
|
||||||
dest.writeString(this.icon);
|
dest.writeString(this.icon);
|
||||||
dest.writeString(this.description);
|
dest.writeString(this.description);
|
||||||
|
dest.writeString(this.whatsNew);
|
||||||
dest.writeString(this.license);
|
dest.writeString(this.license);
|
||||||
dest.writeString(this.authorName);
|
dest.writeString(this.authorName);
|
||||||
dest.writeString(this.authorEmail);
|
dest.writeString(this.authorEmail);
|
||||||
dest.writeString(this.webSite);
|
dest.writeString(this.webSite);
|
||||||
dest.writeString(this.issueTracker);
|
dest.writeString(this.issueTracker);
|
||||||
dest.writeString(this.sourceCode);
|
dest.writeString(this.sourceCode);
|
||||||
|
dest.writeString(this.video);
|
||||||
dest.writeString(this.changelog);
|
dest.writeString(this.changelog);
|
||||||
dest.writeString(this.donate);
|
dest.writeString(this.donate);
|
||||||
dest.writeString(this.bitcoin);
|
dest.writeString(this.bitcoin);
|
||||||
@ -932,12 +949,14 @@ public class App extends ValueObject implements Comparable<App>, Parcelable {
|
|||||||
this.summary = in.readString();
|
this.summary = in.readString();
|
||||||
this.icon = in.readString();
|
this.icon = in.readString();
|
||||||
this.description = in.readString();
|
this.description = in.readString();
|
||||||
|
this.whatsNew = in.readString();
|
||||||
this.license = in.readString();
|
this.license = in.readString();
|
||||||
this.authorName = in.readString();
|
this.authorName = in.readString();
|
||||||
this.authorEmail = in.readString();
|
this.authorEmail = in.readString();
|
||||||
this.webSite = in.readString();
|
this.webSite = in.readString();
|
||||||
this.issueTracker = in.readString();
|
this.issueTracker = in.readString();
|
||||||
this.sourceCode = in.readString();
|
this.sourceCode = in.readString();
|
||||||
|
this.video = in.readString();
|
||||||
this.changelog = in.readString();
|
this.changelog = in.readString();
|
||||||
this.donate = in.readString();
|
this.donate = in.readString();
|
||||||
this.bitcoin = in.readString();
|
this.bitcoin = in.readString();
|
||||||
|
@ -119,12 +119,14 @@ class DBHelper extends SQLiteOpenHelper {
|
|||||||
+ AppMetadataTable.Cols.SUMMARY + " text not null, "
|
+ AppMetadataTable.Cols.SUMMARY + " text not null, "
|
||||||
+ AppMetadataTable.Cols.ICON + " text, "
|
+ AppMetadataTable.Cols.ICON + " text, "
|
||||||
+ AppMetadataTable.Cols.DESCRIPTION + " text not null, "
|
+ AppMetadataTable.Cols.DESCRIPTION + " text not null, "
|
||||||
|
+ AppMetadataTable.Cols.WHATSNEW + " text, "
|
||||||
+ AppMetadataTable.Cols.LICENSE + " text not null, "
|
+ AppMetadataTable.Cols.LICENSE + " text not null, "
|
||||||
+ AppMetadataTable.Cols.AUTHOR_NAME + " text, "
|
+ AppMetadataTable.Cols.AUTHOR_NAME + " text, "
|
||||||
+ AppMetadataTable.Cols.AUTHOR_EMAIL + " text, "
|
+ AppMetadataTable.Cols.AUTHOR_EMAIL + " text, "
|
||||||
+ AppMetadataTable.Cols.WEBSITE + " text, "
|
+ AppMetadataTable.Cols.WEBSITE + " text, "
|
||||||
+ AppMetadataTable.Cols.ISSUE_TRACKER + " text, "
|
+ AppMetadataTable.Cols.ISSUE_TRACKER + " text, "
|
||||||
+ AppMetadataTable.Cols.SOURCE_CODE + " text, "
|
+ AppMetadataTable.Cols.SOURCE_CODE + " text, "
|
||||||
|
+ AppMetadataTable.Cols.VIDEO + " string, "
|
||||||
+ AppMetadataTable.Cols.CHANGELOG + " text, "
|
+ AppMetadataTable.Cols.CHANGELOG + " text, "
|
||||||
+ AppMetadataTable.Cols.SUGGESTED_VERSION_CODE + " text,"
|
+ AppMetadataTable.Cols.SUGGESTED_VERSION_CODE + " text,"
|
||||||
+ AppMetadataTable.Cols.UPSTREAM_VERSION_NAME + " text,"
|
+ AppMetadataTable.Cols.UPSTREAM_VERSION_NAME + " text,"
|
||||||
@ -190,7 +192,7 @@ class DBHelper extends SQLiteOpenHelper {
|
|||||||
+ InstalledAppTable.Cols.HASH + " TEXT NOT NULL"
|
+ InstalledAppTable.Cols.HASH + " TEXT NOT NULL"
|
||||||
+ " );";
|
+ " );";
|
||||||
|
|
||||||
protected static final int DB_VERSION = 68;
|
protected static final int DB_VERSION = 69;
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
|
|
||||||
@ -273,6 +275,21 @@ class DBHelper extends SQLiteOpenHelper {
|
|||||||
addIndexV1Fields(db, oldVersion);
|
addIndexV1Fields(db, oldVersion);
|
||||||
addIndexV1AppFields(db, oldVersion);
|
addIndexV1AppFields(db, oldVersion);
|
||||||
recalculatePreferredMetadata(db, oldVersion);
|
recalculatePreferredMetadata(db, oldVersion);
|
||||||
|
addWhatsNewAndVideo(db, oldVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addWhatsNewAndVideo(SQLiteDatabase db, int oldVersion) {
|
||||||
|
if (oldVersion >= 69) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!columnExists(db, AppMetadataTable.NAME, AppMetadataTable.Cols.WHATSNEW)) {
|
||||||
|
Utils.debugLog(TAG, "Adding " + AppMetadataTable.Cols.WHATSNEW + " field to " + AppMetadataTable.NAME + " table in db.");
|
||||||
|
db.execSQL("alter table " + AppMetadataTable.NAME + " add column " + AppMetadataTable.Cols.WHATSNEW + " text;");
|
||||||
|
}
|
||||||
|
if (!columnExists(db, AppMetadataTable.NAME, AppMetadataTable.Cols.VIDEO)) {
|
||||||
|
Utils.debugLog(TAG, "Adding " + AppMetadataTable.Cols.VIDEO + " field to " + AppMetadataTable.NAME + " table in db.");
|
||||||
|
db.execSQL("alter table " + AppMetadataTable.NAME + " add column " + AppMetadataTable.Cols.VIDEO + " string;");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void recalculatePreferredMetadata(SQLiteDatabase db, int oldVersion) {
|
private void recalculatePreferredMetadata(SQLiteDatabase db, int oldVersion) {
|
||||||
|
@ -123,12 +123,14 @@ public interface Schema {
|
|||||||
String SUMMARY = "summary";
|
String SUMMARY = "summary";
|
||||||
String ICON = "icon";
|
String ICON = "icon";
|
||||||
String DESCRIPTION = "description";
|
String DESCRIPTION = "description";
|
||||||
|
String WHATSNEW = "whatsNew";
|
||||||
String LICENSE = "license";
|
String LICENSE = "license";
|
||||||
String AUTHOR_NAME = "author";
|
String AUTHOR_NAME = "author";
|
||||||
String AUTHOR_EMAIL = "email";
|
String AUTHOR_EMAIL = "email";
|
||||||
String WEBSITE = "webURL";
|
String WEBSITE = "webURL";
|
||||||
String ISSUE_TRACKER = "trackerURL";
|
String ISSUE_TRACKER = "trackerURL";
|
||||||
String SOURCE_CODE = "sourceURL";
|
String SOURCE_CODE = "sourceURL";
|
||||||
|
String VIDEO = "video";
|
||||||
String CHANGELOG = "changelogURL";
|
String CHANGELOG = "changelogURL";
|
||||||
String DONATE = "donateURL";
|
String DONATE = "donateURL";
|
||||||
String BITCOIN = "bitcoinAddr";
|
String BITCOIN = "bitcoinAddr";
|
||||||
@ -184,8 +186,8 @@ public interface Schema {
|
|||||||
*/
|
*/
|
||||||
String[] ALL_COLS = {
|
String[] ALL_COLS = {
|
||||||
ROW_ID, PACKAGE_ID, REPO_ID, IS_COMPATIBLE, NAME, SUMMARY, ICON, DESCRIPTION,
|
ROW_ID, PACKAGE_ID, REPO_ID, IS_COMPATIBLE, NAME, SUMMARY, ICON, DESCRIPTION,
|
||||||
LICENSE, AUTHOR_NAME, AUTHOR_EMAIL, WEBSITE, ISSUE_TRACKER, SOURCE_CODE,
|
WHATSNEW, LICENSE, AUTHOR_NAME, AUTHOR_EMAIL, WEBSITE, ISSUE_TRACKER, SOURCE_CODE,
|
||||||
CHANGELOG, DONATE, BITCOIN, LITECOIN, FLATTR_ID,
|
VIDEO, CHANGELOG, DONATE, BITCOIN, LITECOIN, FLATTR_ID,
|
||||||
UPSTREAM_VERSION_NAME, UPSTREAM_VERSION_CODE, ADDED, LAST_UPDATED,
|
UPSTREAM_VERSION_NAME, UPSTREAM_VERSION_CODE, ADDED, LAST_UPDATED,
|
||||||
ANTI_FEATURES, REQUIREMENTS, ICON_URL, ICON_URL_LARGE,
|
ANTI_FEATURES, REQUIREMENTS, ICON_URL, ICON_URL_LARGE,
|
||||||
FEATURE_GRAPHIC, PROMO_GRAPHIC, TV_BANNER, PHONE_SCREENSHOTS,
|
FEATURE_GRAPHIC, PROMO_GRAPHIC, TV_BANNER, PHONE_SCREENSHOTS,
|
||||||
@ -200,8 +202,8 @@ public interface Schema {
|
|||||||
*/
|
*/
|
||||||
String[] ALL = {
|
String[] ALL = {
|
||||||
_ID, ROW_ID, REPO_ID, IS_COMPATIBLE, NAME, SUMMARY, ICON, DESCRIPTION,
|
_ID, ROW_ID, REPO_ID, IS_COMPATIBLE, NAME, SUMMARY, ICON, DESCRIPTION,
|
||||||
LICENSE, AUTHOR_NAME, AUTHOR_EMAIL, WEBSITE, ISSUE_TRACKER, SOURCE_CODE,
|
WHATSNEW, LICENSE, AUTHOR_NAME, AUTHOR_EMAIL, WEBSITE, ISSUE_TRACKER, SOURCE_CODE,
|
||||||
CHANGELOG, DONATE, BITCOIN, LITECOIN, FLATTR_ID,
|
VIDEO, CHANGELOG, DONATE, BITCOIN, LITECOIN, FLATTR_ID,
|
||||||
UPSTREAM_VERSION_NAME, UPSTREAM_VERSION_CODE, ADDED, LAST_UPDATED,
|
UPSTREAM_VERSION_NAME, UPSTREAM_VERSION_CODE, ADDED, LAST_UPDATED,
|
||||||
ANTI_FEATURES, REQUIREMENTS, ICON_URL, ICON_URL_LARGE,
|
ANTI_FEATURES, REQUIREMENTS, ICON_URL, ICON_URL_LARGE,
|
||||||
FEATURE_GRAPHIC, PROMO_GRAPHIC, TV_BANNER, PHONE_SCREENSHOTS,
|
FEATURE_GRAPHIC, PROMO_GRAPHIC, TV_BANNER, PHONE_SCREENSHOTS,
|
||||||
|
@ -410,21 +410,17 @@ public class AppDetailsRecyclerViewAdapter
|
|||||||
lastUpdateView.setVisibility(View.GONE);
|
lastUpdateView.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
Apk suggestedApk = getSuggestedApk();
|
if (TextUtils.isEmpty(app.whatsNew)) {
|
||||||
|
|
||||||
// TODO populate whatsNew with suggestedApk.whatsNew once that exists
|
|
||||||
String whatsNew = null;
|
|
||||||
//noinspection ConstantConditions
|
|
||||||
if (suggestedApk == null || TextUtils.isEmpty(whatsNew)) {
|
|
||||||
whatsNewView.setVisibility(View.GONE);
|
whatsNewView.setVisibility(View.GONE);
|
||||||
} else {
|
} else {
|
||||||
//noinspection deprecation Ignore deprecation because the suggested way is only available in API 24.
|
//noinspection deprecation Ignore deprecation because the suggested way is only available in API 24.
|
||||||
Locale locale = context.getResources().getConfiguration().locale;
|
Locale locale = context.getResources().getConfiguration().locale;
|
||||||
|
|
||||||
StringBuilder sbWhatsNew = new StringBuilder();
|
StringBuilder sbWhatsNew = new StringBuilder();
|
||||||
sbWhatsNew.append(whatsNewView.getContext().getString(R.string.details_new_in_version, suggestedApk.versionName).toUpperCase(locale));
|
sbWhatsNew.append(whatsNewView.getContext().getString(R.string.details_new_in_version,
|
||||||
|
getSuggestedApk().versionName).toUpperCase(locale));
|
||||||
sbWhatsNew.append("\n\n");
|
sbWhatsNew.append("\n\n");
|
||||||
sbWhatsNew.append(whatsNew);
|
sbWhatsNew.append(app.whatsNew);
|
||||||
whatsNewView.setText(sbWhatsNew);
|
whatsNewView.setText(sbWhatsNew);
|
||||||
whatsNewView.setVisibility(View.VISIBLE);
|
whatsNewView.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ import org.fdroid.fdroid.data.Schema;
|
|||||||
import org.fdroid.fdroid.views.apps.AppListActivity;
|
import org.fdroid.fdroid.views.apps.AppListActivity;
|
||||||
import org.fdroid.fdroid.views.apps.FeatureImage;
|
import org.fdroid.fdroid.views.apps.FeatureImage;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
public class CategoryController extends RecyclerView.ViewHolder implements LoaderManager.LoaderCallbacks<Cursor> {
|
public class CategoryController extends RecyclerView.ViewHolder implements LoaderManager.LoaderCallbacks<Cursor> {
|
||||||
@ -108,7 +109,7 @@ public class CategoryController extends RecyclerView.ViewHolder implements Loade
|
|||||||
private static int getCategoryResource(Context context, @NonNull String categoryName, String resourceType, boolean requiresLowerCaseId) {
|
private static int getCategoryResource(Context context, @NonNull String categoryName, String resourceType, boolean requiresLowerCaseId) {
|
||||||
String suffix = categoryName.replace(" & ", "_").replace(" ", "_").replace("'", "");
|
String suffix = categoryName.replace(" & ", "_").replace(" ", "_").replace("'", "");
|
||||||
if (requiresLowerCaseId) {
|
if (requiresLowerCaseId) {
|
||||||
suffix = suffix.toLowerCase();
|
suffix = suffix.toLowerCase(Locale.ENGLISH);
|
||||||
}
|
}
|
||||||
return context.getResources().getIdentifier("category_" + suffix, resourceType, context.getPackageName());
|
return context.getResources().getIdentifier("category_" + suffix, resourceType, context.getPackageName());
|
||||||
}
|
}
|
||||||
@ -121,7 +122,7 @@ public class CategoryController extends RecyclerView.ViewHolder implements Loade
|
|||||||
|
|
||||||
// Seed based on the categoryName, so that each time we try to choose a colour for the same
|
// Seed based on the categoryName, so that each time we try to choose a colour for the same
|
||||||
// category it will look the same for each different user, and each different session.
|
// category it will look the same for each different user, and each different session.
|
||||||
Random random = new Random(categoryName.toLowerCase().hashCode());
|
Random random = new Random(categoryName.toLowerCase(Locale.ENGLISH).hashCode());
|
||||||
|
|
||||||
float[] hsv = new float[3];
|
float[] hsv = new float[3];
|
||||||
hsv[0] = random.nextFloat() * 360;
|
hsv[0] = random.nextFloat() * 360;
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
android:paddingBottom="8dp"
|
android:paddingBottom="8dp"
|
||||||
android:paddingRight="8dp"
|
android:paddingRight="8dp"
|
||||||
|
android:paddingEnd="8dp"
|
||||||
android:src="@drawable/ic_repo_app_default" />
|
android:src="@drawable/ic_repo_app_default" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
@ -251,6 +251,7 @@ public class IndexV1UpdaterTest extends FDroidProviderTest {
|
|||||||
"upstreamVersionCode",
|
"upstreamVersionCode",
|
||||||
"upstreamVersionName",
|
"upstreamVersionName",
|
||||||
"video",
|
"video",
|
||||||
|
"whatsNew",
|
||||||
"wearScreenshots",
|
"wearScreenshots",
|
||||||
"webSite",
|
"webSite",
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user