mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-27 04:43:54 +01:00
* Localisation updates from https://translatewiki.net. * Integrate API for displaying featured images (#1456) * Integrate API for displaying featured images * Add pagination and refactor code so that it can be reused for category images * Add license info to the images * Fix author view * Remove unused values * Fix minor issues with featured images * Fix null license url issue * Remove some log lines * Fix back navigation issue * fix tests * fix test inits * Gracefully handling various error situations * Added java docs * Update pull_request_template.md (#1476) * Update pull_request_template.md * Remove Javadocs mention * Added required/optional notes * resolves #1464 : MediaDataExtractor is making inefficient (redundant) server calls (#1496) * Open map of place where picture was taken (#1360) * Intent to map added * Merge conflicts resolved * Added the functionality to hide FAB incase of null coordinate * Merge Conflict resolved * Improve pr quality * Improve Quality * Added nested FAB animations * Nested FAB implemented * Improve Quality * Added up arrow * Javadocs Added * Add nearby tutorial (#1467) * Add dependency for MaterialShowcase * Add actionview class to get a reference to material showcase * Create a NearbyMaterialShowcaseSequence class * Apply sequence steps * Add first three steps of nearby showcase * Add sequence id constants to make sure they will be displayed only once * Add last step of sequence to explain plus fab * Create an object to prevent customize all sequences every time * Fix typo * Code cleanup * Add strings to strings.xml * Code cleanup * Revert irrelevant change * Revert irrelevant change * Remove showcaseview for recenter button * Use single showcaseView instead of sequence * Add single showcase view insted of sequence to be able to edit text style * Make sure it will be displayed only once * Cleanup * Update strings * Change dismiss text style * CONTRIBUTING: fix formatting of the gist of the guidelines (#1453) * CONTRIBUTING: fix formatting of the gist of the guidelines First level headings for a gist seems to be overkill. So, replace first level headings with an ordered-list which sounds more meaningful. * CONTRIBUTING: specify clearly that 'blame' is a feature of "Git" The contributing file specifies about the ability to know who wrote something without the need of @author javadoc tags but incorrectly attributes the feature to GitHub. Correctly attribute the feature to where it belongs, Git, and specify the name of the feature to help users easily take advantage of it. * Feature/switch to butterknife (#1494) * Implemented butterknife in MediaDetailFragment [issue #1491] * Implemented butterknife in MediaDetailPagerFragment [[issue #1491]] * post merge upstream master wip [[issue #1491]] * Localisation updates from https://translatewiki.net. * Bug fix #1504 (#1506) * Bug fix #1504 * Filtered messages with ConnectException [issue #1504] * A generalised message for exceptions in Nearby Activity [issue #1504] * Localisation updates from https://translatewiki.net. * Fix security exception crash while accessing network location provider (#1498) * Fix security exception crash while accessing network location provider * Added java docs * Localisation updates from https://translatewiki.net. * Log P18 edits to wikidata corresponding wikidata entity on uploading a nearby image * Added java docs * Fix test build * Refresh nearby * Refresh nearby list on successful edit * Java docs * Make authenticated wikidata edits * Updated toast message to show entity name that was edited
198 lines
7.1 KiB
Java
198 lines
7.1 KiB
Java
package fr.free.nrw.commons;
|
|
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.net.Uri;
|
|
import android.preference.PreferenceManager;
|
|
import android.support.annotation.NonNull;
|
|
import android.support.customtabs.CustomTabsIntent;
|
|
import android.support.v4.content.ContextCompat;
|
|
import android.widget.Toast;
|
|
|
|
import org.apache.commons.codec.binary.Hex;
|
|
import org.apache.commons.codec.digest.DigestUtils;
|
|
|
|
import java.io.BufferedReader;
|
|
import java.io.IOException;
|
|
import java.io.InputStreamReader;
|
|
import java.io.UnsupportedEncodingException;
|
|
import java.net.URLEncoder;
|
|
import java.util.Locale;
|
|
import java.util.regex.Matcher;
|
|
import java.util.regex.Pattern;
|
|
|
|
import fr.free.nrw.commons.settings.Prefs;
|
|
import timber.log.Timber;
|
|
|
|
import static android.widget.Toast.LENGTH_SHORT;
|
|
|
|
public class Utils {
|
|
|
|
/**
|
|
* Strips localization symbols from a string.
|
|
* Removes the suffix after "@" and quotes.
|
|
*
|
|
* @param s string possibly containing localization symbols
|
|
* @return stripped string
|
|
*/
|
|
public static String stripLocalizedString(String s) {
|
|
Matcher matcher = Pattern.compile("\\\"(.*)\\\"(@\\w+)?").matcher(s);
|
|
if (matcher.find()) {
|
|
return matcher.group(1);
|
|
} else {
|
|
return s;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Creates an URL for thumbnail
|
|
*
|
|
* @param filename Thumbnail file name
|
|
* @return URL of thumbnail
|
|
*/
|
|
public static String makeThumbBaseUrl(@NonNull String filename) {
|
|
String name = new PageTitle(filename).getPrefixedText();
|
|
String sha = new String(Hex.encodeHex(DigestUtils.md5(name)));
|
|
return String.format("%s/%s/%s/%s", BuildConfig.IMAGE_URL_BASE, sha.substring(0, 1), sha.substring(0, 2), urlEncode(name));
|
|
}
|
|
|
|
/**
|
|
* URL Encode an URL in UTF-8 format
|
|
* @param url Unformatted URL
|
|
* @return Encoded URL
|
|
*/
|
|
public static String urlEncode(String url) {
|
|
try {
|
|
return URLEncoder.encode(url, "utf-8");
|
|
} catch (UnsupportedEncodingException e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Capitalizes the first character of a string.
|
|
*
|
|
* @param string String to alter
|
|
* @return string with capitalized first character
|
|
*/
|
|
public static String capitalize(String string) {
|
|
return string.substring(0, 1).toUpperCase(Locale.getDefault()) + string.substring(1);
|
|
}
|
|
|
|
/**
|
|
* Generates licence name with given ID
|
|
* @param license License ID
|
|
* @return Name of license
|
|
*/
|
|
public static int licenseNameFor(String license) {
|
|
switch (license) {
|
|
case Prefs.Licenses.CC_BY_3:
|
|
return R.string.license_name_cc_by;
|
|
case Prefs.Licenses.CC_BY_4:
|
|
return R.string.license_name_cc_by_four;
|
|
case Prefs.Licenses.CC_BY_SA_3:
|
|
return R.string.license_name_cc_by_sa;
|
|
case Prefs.Licenses.CC_BY_SA_4:
|
|
return R.string.license_name_cc_by_sa_four;
|
|
case Prefs.Licenses.CC0:
|
|
return R.string.license_name_cc0;
|
|
case Prefs.Licenses.CC_BY: // for backward compatibility to v2.1
|
|
return R.string.license_name_cc_by_3_0;
|
|
case Prefs.Licenses.CC_BY_SA: // for backward compatibility to v2.1
|
|
return R.string.license_name_cc_by_sa_3_0;
|
|
}
|
|
throw new RuntimeException("Unrecognized license value: " + license);
|
|
}
|
|
|
|
/**
|
|
* Fixing incorrect extension
|
|
* @param title File name
|
|
* @param extension Correct extension
|
|
* @return File with correct extension
|
|
*/
|
|
public static String fixExtension(String title, String extension) {
|
|
Pattern jpegPattern = Pattern.compile("\\.jpeg$", Pattern.CASE_INSENSITIVE);
|
|
|
|
// People are used to ".jpg" more than ".jpeg" which the system gives us.
|
|
if (extension != null && extension.toLowerCase(Locale.ENGLISH).equals("jpeg")) {
|
|
extension = "jpg";
|
|
}
|
|
title = jpegPattern.matcher(title).replaceFirst(".jpg");
|
|
if (extension != null && !title.toLowerCase(Locale.getDefault())
|
|
.endsWith("." + extension.toLowerCase(Locale.ENGLISH))) {
|
|
title += "." + extension;
|
|
}
|
|
return title;
|
|
}
|
|
|
|
/**
|
|
* Tells whether dark theme is active or not
|
|
* @param context Activity context
|
|
* @return The state of dark theme
|
|
*/
|
|
public static boolean isDarkTheme(Context context) {
|
|
return PreferenceManager.getDefaultSharedPreferences(context).getBoolean("theme", false);
|
|
}
|
|
|
|
/**
|
|
* Will be used to fetch the logs generated by the app ever since the beginning of times....
|
|
* i.e. since the time the app started.
|
|
*
|
|
* @return String containing all the logs since the time the app started
|
|
*/
|
|
public static String getAppLogs() {
|
|
final String processId = Integer.toString(android.os.Process.myPid());
|
|
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
|
|
try {
|
|
String[] command = new String[] {"logcat","-d","-v","threadtime"};
|
|
|
|
Process process = Runtime.getRuntime().exec(command);
|
|
|
|
BufferedReader bufferedReader = new BufferedReader(
|
|
new InputStreamReader(process.getInputStream())
|
|
);
|
|
|
|
String line;
|
|
while ((line = bufferedReader.readLine()) != null) {
|
|
if (line.contains(processId)) {
|
|
stringBuilder.append(line);
|
|
}
|
|
}
|
|
} catch (IOException ioe) {
|
|
Timber.e("getAppLogs failed", ioe);
|
|
}
|
|
|
|
return stringBuilder.toString();
|
|
}
|
|
|
|
public static void rateApp(Context context) {
|
|
final String appPackageName = BuildConfig.class.getPackage().getName();
|
|
try {
|
|
context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + appPackageName)));
|
|
}
|
|
catch (android.content.ActivityNotFoundException anfe) {
|
|
context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + appPackageName)));
|
|
}
|
|
}
|
|
|
|
public static void handleWebUrl(Context context, Uri url) {
|
|
Timber.d("Launching web url %s", url.toString());
|
|
Intent browserIntent = new Intent(Intent.ACTION_VIEW, url);
|
|
if (browserIntent.resolveActivity(context.getPackageManager()) == null) {
|
|
Toast toast = Toast.makeText(context, context.getString(R.string.no_web_browser), LENGTH_SHORT);
|
|
toast.show();
|
|
return;
|
|
}
|
|
|
|
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
|
|
builder.setToolbarColor(ContextCompat.getColor(context, R.color.primaryColor));
|
|
builder.setSecondaryToolbarColor(ContextCompat.getColor(context, R.color.primaryDarkColor));
|
|
builder.setExitAnimations(context, android.R.anim.slide_in_left, android.R.anim.slide_out_right);
|
|
CustomTabsIntent customTabsIntent = builder.build();
|
|
customTabsIntent.intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
customTabsIntent.launchUrl(context, url);
|
|
}
|
|
|
|
}
|