Loading app/src/main/AndroidManifest.xml +20 −3 Original line number Diff line number Diff line Loading @@ -26,13 +26,30 @@ <activity android:name=".activities.MainActivity" android:configChanges="orientation|screenSize" android:exported="true" > android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="image/*" /> <data android:mimeType="video/*" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.SEND_MULTIPLE" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="image/*" /> <data android:mimeType="video/*" /> </intent-filter> </activity> <activity Loading app/src/main/java/app/fedilab/android/BaseMainActivity.java +152 −0 Original line number Diff line number Diff line Loading @@ -28,11 +28,15 @@ import android.content.SharedPreferences; import android.graphics.PorterDuff; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.text.Editable; import android.text.Html; import android.text.TextWatcher; import android.util.Patterns; import android.view.ContextThemeWrapper; import android.view.Gravity; import android.view.LayoutInflater; Loading Loading @@ -72,8 +76,12 @@ import com.google.android.material.snackbar.Snackbar; import com.jaredrummler.cyanea.Cyanea; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; import app.fedilab.android.activities.AboutActivity; Loading Loading @@ -115,6 +123,7 @@ import app.fedilab.android.client.entities.app.PinnedTimeline; import app.fedilab.android.databinding.ActivityMainBinding; import app.fedilab.android.databinding.NavHeaderMainBinding; import app.fedilab.android.exception.DBException; import app.fedilab.android.helper.CrossActionHelper; import app.fedilab.android.helper.Helper; import app.fedilab.android.helper.MastodonHelper; import app.fedilab.android.helper.PinnedTimelineHelper; Loading @@ -128,6 +137,11 @@ import app.fedilab.android.viewmodel.mastodon.InstancesVM; import app.fedilab.android.viewmodel.mastodon.TimelinesVM; import app.fedilab.android.viewmodel.mastodon.TopBarVM; import es.dmoral.toasty.Toasty; import okhttp3.Call; import okhttp3.Callback; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; public abstract class BaseMainActivity extends BaseActivity implements NetworkStateReceiver.NetworkStateReceiverListener { Loading Loading @@ -234,6 +248,8 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt private void mamageNewIntent(Intent intent) { if (intent == null) return; String action = intent.getAction(); String type = intent.getType(); Bundle extras = intent.getExtras(); String userIdIntent, instanceIntent; if (extras != null && extras.containsKey(Helper.INTENT_ACTION)) { Loading Loading @@ -270,6 +286,142 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt intent.removeExtra(Helper.INTENT_ACTION); } } else if (Intent.ACTION_SEND.equals(action) && type != null) { if ("text/plain".equals(type)) { final String[] url = {null}; String sharedSubject = intent.getStringExtra(Intent.EXTRA_SUBJECT); String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT); //SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(BaseMainActivity.this); //boolean shouldRetrieveMetaData = sharedpreferences.getBoolean(getString(R.string.SET_RETRIEVE_METADATA_IF_URL_FROM_EXTERAL), true); if (sharedText != null) { /* Some apps don't send the URL as the first part of the EXTRA_TEXT, the BBC News app being one such, in this case find where the URL is and strip that out into sharedText. */ Matcher matcher; matcher = Patterns.WEB_URL.matcher(sharedText); while (matcher.find()) { int matchStart = matcher.start(1); int matchEnd = matcher.end(); if (matchStart < matchEnd && sharedText.length() >= matchEnd) url[0] = sharedText.substring(matchStart, matchEnd); } new Thread(() -> { if (url[0].startsWith("www.")) url[0] = "http://" + url[0]; Matcher matcherPattern = Patterns.WEB_URL.matcher(url[0]); String potentialUrl = null; while (matcherPattern.find()) { int matchStart = matcherPattern.start(1); int matchEnd = matcherPattern.end(); if (matchStart < matchEnd && url[0].length() >= matchEnd) potentialUrl = url[0].substring(matchStart, matchEnd); } // If we actually have a URL then make use of it. if (potentialUrl != null && potentialUrl.length() > 0) { Pattern titlePattern = Pattern.compile("meta[ a-zA-Z=\"'-]+property=[\"']og:title[\"']\\s+content=[\"']([^>]*)[\"']"); Pattern descriptionPattern = Pattern.compile("meta[ a-zA-Z=\"'-]+property=[\"']og:description[\"']\\s+content=[\"']([^>]*)[\"']"); Pattern imagePattern = Pattern.compile("meta[ a-zA-Z=\"'-]+property=[\"']og:image[\"']\\s+content=[\"']([^>]*)[\"']"); try { OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) .writeTimeout(10, TimeUnit.SECONDS) .proxy(Helper.getProxy(getApplication().getApplicationContext())) .readTimeout(10, TimeUnit.SECONDS).build(); Request request = new Request.Builder() .url(potentialUrl) .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(@NonNull Call call, @NonNull IOException e) { e.printStackTrace(); runOnUiThread(() -> Toasty.warning(BaseMainActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show()); } @Override public void onResponse(@NonNull Call call, @NonNull final Response response) { if (response.isSuccessful()) { try { String data = response.body().string(); Matcher matcherTitle; matcherTitle = titlePattern.matcher(data); Matcher matcherDescription = descriptionPattern.matcher(data); Matcher matcherImage = imagePattern.matcher(data); String titleEncoded = null; String descriptionEncoded = null; while (matcherTitle.find()) titleEncoded = matcherTitle.group(1); while (matcherDescription.find()) descriptionEncoded = matcherDescription.group(1); String image = null; while (matcherImage.find()) image = matcherImage.group(1); String title = null; String description = null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { if (titleEncoded != null) title = Html.fromHtml(titleEncoded, Html.FROM_HTML_MODE_LEGACY).toString(); if (descriptionEncoded != null) description = Html.fromHtml(descriptionEncoded, Html.FROM_HTML_MODE_LEGACY).toString(); } else { if (titleEncoded != null) title = Html.fromHtml(titleEncoded).toString(); if (descriptionEncoded != null) description = Html.fromHtml(descriptionEncoded).toString(); } String finalImage = image; String finalTitle = title; String finalDescription = description; runOnUiThread(() -> { Bundle b = new Bundle(); b.putString(Helper.ARG_SHARE_URL, url[0]); b.putString(Helper.ARG_SHARE_URL_MEDIA, finalImage); b.putString(Helper.ARG_SHARE_TITLE, finalTitle); b.putString(Helper.ARG_SHARE_DESCRIPTION, finalDescription); b.putString(Helper.ARG_SHARE_SUBJECT, sharedSubject); b.putString(Helper.ARG_SHARE_CONTENT, sharedText); CrossActionHelper.doCrossShare(BaseMainActivity.this, b); }); } catch (Exception e) { e.printStackTrace(); } } else { runOnUiThread(() -> Toasty.warning(BaseMainActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show()); } } }); } catch (IndexOutOfBoundsException e) { Toasty.warning(BaseMainActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show(); } } }).start(); } } else if (type.startsWith("image/") || type.startsWith("video/")) { Uri imageUri = intent.getParcelableExtra(Intent.EXTRA_STREAM); if (imageUri != null) { intent = new Intent(BaseMainActivity.this, ComposeActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); intent.putExtra(Helper.ARG_SHARE_URI, imageUri.toString()); startActivity(intent); } else { Toasty.warning(BaseMainActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show(); } } } else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) { if (type.startsWith("image/") || type.startsWith("video/")) { ArrayList<Uri> imageList = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); if (imageList != null) { Bundle b = new Bundle(); b.putParcelableArrayList(Helper.ARG_SHARE_URI_LIST, imageList); CrossActionHelper.doCrossShare(BaseMainActivity.this, b); } else { Toasty.warning(BaseMainActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show(); } } } } Loading app/src/main/java/app/fedilab/android/activities/ComposeActivity.java +38 −2 Original line number Diff line number Diff line Loading @@ -72,7 +72,6 @@ import app.fedilab.android.client.entities.api.EmojiInstance; import app.fedilab.android.client.entities.api.Mention; import app.fedilab.android.client.entities.api.ScheduledStatus; import app.fedilab.android.client.entities.api.Status; import app.fedilab.android.client.entities.app.Account; import app.fedilab.android.client.entities.app.BaseAccount; import app.fedilab.android.client.entities.app.StatusDraft; import app.fedilab.android.databinding.ActivityPaginationBinding; Loading @@ -84,6 +83,7 @@ import app.fedilab.android.helper.MastodonHelper; import app.fedilab.android.helper.MediaHelper; import app.fedilab.android.helper.SpannableHelper; import app.fedilab.android.helper.ThemeHelper; import app.fedilab.android.interfaces.OnDownloadInterface; import app.fedilab.android.jobs.ScheduleThreadWorker; import app.fedilab.android.services.PostMessageService; import app.fedilab.android.services.ThreadMessageService; Loading Loading @@ -134,6 +134,9 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana private app.fedilab.android.client.entities.api.Account accountMention; private String statusReplyId; private app.fedilab.android.client.entities.api.Account mentionBooster; private ArrayList<Uri> sharedUriList = new ArrayList<>(); private Uri sharedUri; private String sharedSubject, sharedContent, sharedTitle, sharedDescription, shareURL, sharedUrlMedia; @Override protected void onCreate(Bundle savedInstanceState) { Loading @@ -160,13 +163,24 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana scheduledStatus = (ScheduledStatus) b.getSerializable(Helper.ARG_STATUS_SCHEDULED); statusReplyId = b.getString(Helper.ARG_STATUS_REPLY_ID); statusMention = (Status) b.getSerializable(Helper.ARG_STATUS_MENTION); account = (Account) b.getSerializable(Helper.ARG_ACCOUNT); account = (BaseAccount) b.getSerializable(Helper.ARG_ACCOUNT); instance = b.getString(Helper.ARG_INSTANCE, null); token = b.getString(Helper.ARG_TOKEN, null); visibility = b.getString(Helper.ARG_VISIBILITY, null); mentionBooster = (app.fedilab.android.client.entities.api.Account) b.getSerializable(Helper.ARG_MENTION_BOOSTER); accountMention = (app.fedilab.android.client.entities.api.Account) b.getSerializable(Helper.ARG_ACCOUNT_MENTION); //Shared elements sharedUriList = b.getParcelableArrayList(Helper.ARG_SHARE_URI_LIST); sharedUri = b.getParcelable(Helper.ARG_SHARE_URI); sharedUrlMedia = b.getString(Helper.ARG_SHARE_URL_MEDIA); sharedSubject = b.getString(Helper.ARG_SHARE_SUBJECT, null); sharedContent = b.getString(Helper.ARG_SHARE_CONTENT, null); sharedTitle = b.getString(Helper.ARG_SHARE_TITLE, null); sharedDescription = b.getString(Helper.ARG_SHARE_DESCRIPTION, null); shareURL = b.getString(Helper.ARG_SHARE_URL, null); } binding.toolbar.setPopupTheme(Helper.popupStyle()); //Edit a scheduled status from server if (scheduledStatus != null) { Loading Loading @@ -342,6 +356,28 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana storeDraft(false); } }, 0, 10000); if (sharedUriList != null && sharedUriList.size() > 0) { List<Uri> uris = new ArrayList<>(sharedUriList); composeAdapter.addAttachment(-1, uris); } else if (sharedUri != null && !sharedUri.toString().startsWith("http")) { List<Uri> uris = new ArrayList<>(); uris.add(sharedUri); composeAdapter.addAttachment(-1, uris); } else if (shareURL != null) { Helper.download(ComposeActivity.this, sharedUrlMedia, new OnDownloadInterface() { @Override public void onDownloaded(String saveFilePath, String downloadUrl, Error error) { composeAdapter.addSharing(shareURL, sharedTitle, sharedDescription, sharedSubject, sharedContent, saveFilePath); } @Override public void onUpdateProgress(int progress) { } }); } } @Override Loading app/src/main/java/app/fedilab/android/helper/CrossActionHelper.java +45 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package app.fedilab.android.helper; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.os.Handler; import android.os.Looper; Loading @@ -34,6 +35,7 @@ import java.util.concurrent.TimeUnit; import app.fedilab.android.BaseMainActivity; import app.fedilab.android.R; import app.fedilab.android.activities.BaseActivity; import app.fedilab.android.activities.ComposeActivity; import app.fedilab.android.client.endpoints.MastodonSearchService; import app.fedilab.android.client.entities.api.Results; Loading Loading @@ -399,6 +401,49 @@ public class CrossActionHelper { }).start(); } public static void doCrossShare(final Context context, final Bundle bundle) { List<BaseAccount> accounts; try { accounts = new Account(context).getAll(); List<app.fedilab.android.client.entities.api.Account> accountList = new ArrayList<>(); for (BaseAccount account : accounts) { accountList.add(account.mastodon_account); } if (accounts.size() == 1) { Intent intentToot = new Intent(context, ComposeActivity.class); intentToot.putExtras(bundle); context.startActivity(intentToot); ((BaseActivity) context).finish(); } else { AlertDialog.Builder builderSingle = new AlertDialog.Builder(context, Helper.dialogStyle()); builderSingle.setTitle(context.getString(R.string.choose_accounts)); final AccountsSearchAdapter accountsSearchAdapter = new AccountsSearchAdapter(context, accountList); final BaseAccount[] accountArray = new BaseAccount[accounts.size()]; int i = 0; for (BaseAccount account : accounts) { accountArray[i] = account; i++; } builderSingle.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss()); builderSingle.setAdapter(accountsSearchAdapter, (dialog, which) -> { final BaseAccount account = accountArray[which]; Intent intentToot = new Intent(context, ComposeActivity.class); bundle.putSerializable(Helper.ARG_ACCOUNT, account); intentToot.putExtras(bundle); context.startActivity(intentToot); ((BaseActivity) context).finish(); dialog.dismiss(); }); builderSingle.show(); } } catch (DBException e) { e.printStackTrace(); } } public enum TypeOfCrossAction { FOLLOW_ACTION, Loading app/src/main/java/app/fedilab/android/helper/FileNameCleaner.java 0 → 100644 +30 −0 Original line number Diff line number Diff line package app.fedilab.android.helper; import java.util.Arrays; /** * Work from https://stackoverflow.com/a/26420820 */ public class FileNameCleaner { private final static int[] illegalChars = {34, 60, 62, 124, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 58, 42, 63, 92, 47}; static { Arrays.sort(illegalChars); } public static String cleanFileName(String badFileName) { StringBuilder cleanName = new StringBuilder(); if (badFileName.contains("?")) { badFileName = badFileName.split("\\?")[0]; } int len = badFileName.codePointCount(0, badFileName.length()); for (int i = 0; i < len; i++) { int c = badFileName.codePointAt(i); if (Arrays.binarySearch(illegalChars, c) < 0) { cleanName.appendCodePoint(c); } } return cleanName.toString(); } } No newline at end of file Loading
app/src/main/AndroidManifest.xml +20 −3 Original line number Diff line number Diff line Loading @@ -26,13 +26,30 @@ <activity android:name=".activities.MainActivity" android:configChanges="orientation|screenSize" android:exported="true" > android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="image/*" /> <data android:mimeType="video/*" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.SEND_MULTIPLE" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="image/*" /> <data android:mimeType="video/*" /> </intent-filter> </activity> <activity Loading
app/src/main/java/app/fedilab/android/BaseMainActivity.java +152 −0 Original line number Diff line number Diff line Loading @@ -28,11 +28,15 @@ import android.content.SharedPreferences; import android.graphics.PorterDuff; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.text.Editable; import android.text.Html; import android.text.TextWatcher; import android.util.Patterns; import android.view.ContextThemeWrapper; import android.view.Gravity; import android.view.LayoutInflater; Loading Loading @@ -72,8 +76,12 @@ import com.google.android.material.snackbar.Snackbar; import com.jaredrummler.cyanea.Cyanea; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; import app.fedilab.android.activities.AboutActivity; Loading Loading @@ -115,6 +123,7 @@ import app.fedilab.android.client.entities.app.PinnedTimeline; import app.fedilab.android.databinding.ActivityMainBinding; import app.fedilab.android.databinding.NavHeaderMainBinding; import app.fedilab.android.exception.DBException; import app.fedilab.android.helper.CrossActionHelper; import app.fedilab.android.helper.Helper; import app.fedilab.android.helper.MastodonHelper; import app.fedilab.android.helper.PinnedTimelineHelper; Loading @@ -128,6 +137,11 @@ import app.fedilab.android.viewmodel.mastodon.InstancesVM; import app.fedilab.android.viewmodel.mastodon.TimelinesVM; import app.fedilab.android.viewmodel.mastodon.TopBarVM; import es.dmoral.toasty.Toasty; import okhttp3.Call; import okhttp3.Callback; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; public abstract class BaseMainActivity extends BaseActivity implements NetworkStateReceiver.NetworkStateReceiverListener { Loading Loading @@ -234,6 +248,8 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt private void mamageNewIntent(Intent intent) { if (intent == null) return; String action = intent.getAction(); String type = intent.getType(); Bundle extras = intent.getExtras(); String userIdIntent, instanceIntent; if (extras != null && extras.containsKey(Helper.INTENT_ACTION)) { Loading Loading @@ -270,6 +286,142 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt intent.removeExtra(Helper.INTENT_ACTION); } } else if (Intent.ACTION_SEND.equals(action) && type != null) { if ("text/plain".equals(type)) { final String[] url = {null}; String sharedSubject = intent.getStringExtra(Intent.EXTRA_SUBJECT); String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT); //SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(BaseMainActivity.this); //boolean shouldRetrieveMetaData = sharedpreferences.getBoolean(getString(R.string.SET_RETRIEVE_METADATA_IF_URL_FROM_EXTERAL), true); if (sharedText != null) { /* Some apps don't send the URL as the first part of the EXTRA_TEXT, the BBC News app being one such, in this case find where the URL is and strip that out into sharedText. */ Matcher matcher; matcher = Patterns.WEB_URL.matcher(sharedText); while (matcher.find()) { int matchStart = matcher.start(1); int matchEnd = matcher.end(); if (matchStart < matchEnd && sharedText.length() >= matchEnd) url[0] = sharedText.substring(matchStart, matchEnd); } new Thread(() -> { if (url[0].startsWith("www.")) url[0] = "http://" + url[0]; Matcher matcherPattern = Patterns.WEB_URL.matcher(url[0]); String potentialUrl = null; while (matcherPattern.find()) { int matchStart = matcherPattern.start(1); int matchEnd = matcherPattern.end(); if (matchStart < matchEnd && url[0].length() >= matchEnd) potentialUrl = url[0].substring(matchStart, matchEnd); } // If we actually have a URL then make use of it. if (potentialUrl != null && potentialUrl.length() > 0) { Pattern titlePattern = Pattern.compile("meta[ a-zA-Z=\"'-]+property=[\"']og:title[\"']\\s+content=[\"']([^>]*)[\"']"); Pattern descriptionPattern = Pattern.compile("meta[ a-zA-Z=\"'-]+property=[\"']og:description[\"']\\s+content=[\"']([^>]*)[\"']"); Pattern imagePattern = Pattern.compile("meta[ a-zA-Z=\"'-]+property=[\"']og:image[\"']\\s+content=[\"']([^>]*)[\"']"); try { OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) .writeTimeout(10, TimeUnit.SECONDS) .proxy(Helper.getProxy(getApplication().getApplicationContext())) .readTimeout(10, TimeUnit.SECONDS).build(); Request request = new Request.Builder() .url(potentialUrl) .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(@NonNull Call call, @NonNull IOException e) { e.printStackTrace(); runOnUiThread(() -> Toasty.warning(BaseMainActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show()); } @Override public void onResponse(@NonNull Call call, @NonNull final Response response) { if (response.isSuccessful()) { try { String data = response.body().string(); Matcher matcherTitle; matcherTitle = titlePattern.matcher(data); Matcher matcherDescription = descriptionPattern.matcher(data); Matcher matcherImage = imagePattern.matcher(data); String titleEncoded = null; String descriptionEncoded = null; while (matcherTitle.find()) titleEncoded = matcherTitle.group(1); while (matcherDescription.find()) descriptionEncoded = matcherDescription.group(1); String image = null; while (matcherImage.find()) image = matcherImage.group(1); String title = null; String description = null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { if (titleEncoded != null) title = Html.fromHtml(titleEncoded, Html.FROM_HTML_MODE_LEGACY).toString(); if (descriptionEncoded != null) description = Html.fromHtml(descriptionEncoded, Html.FROM_HTML_MODE_LEGACY).toString(); } else { if (titleEncoded != null) title = Html.fromHtml(titleEncoded).toString(); if (descriptionEncoded != null) description = Html.fromHtml(descriptionEncoded).toString(); } String finalImage = image; String finalTitle = title; String finalDescription = description; runOnUiThread(() -> { Bundle b = new Bundle(); b.putString(Helper.ARG_SHARE_URL, url[0]); b.putString(Helper.ARG_SHARE_URL_MEDIA, finalImage); b.putString(Helper.ARG_SHARE_TITLE, finalTitle); b.putString(Helper.ARG_SHARE_DESCRIPTION, finalDescription); b.putString(Helper.ARG_SHARE_SUBJECT, sharedSubject); b.putString(Helper.ARG_SHARE_CONTENT, sharedText); CrossActionHelper.doCrossShare(BaseMainActivity.this, b); }); } catch (Exception e) { e.printStackTrace(); } } else { runOnUiThread(() -> Toasty.warning(BaseMainActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show()); } } }); } catch (IndexOutOfBoundsException e) { Toasty.warning(BaseMainActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show(); } } }).start(); } } else if (type.startsWith("image/") || type.startsWith("video/")) { Uri imageUri = intent.getParcelableExtra(Intent.EXTRA_STREAM); if (imageUri != null) { intent = new Intent(BaseMainActivity.this, ComposeActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); intent.putExtra(Helper.ARG_SHARE_URI, imageUri.toString()); startActivity(intent); } else { Toasty.warning(BaseMainActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show(); } } } else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) { if (type.startsWith("image/") || type.startsWith("video/")) { ArrayList<Uri> imageList = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); if (imageList != null) { Bundle b = new Bundle(); b.putParcelableArrayList(Helper.ARG_SHARE_URI_LIST, imageList); CrossActionHelper.doCrossShare(BaseMainActivity.this, b); } else { Toasty.warning(BaseMainActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show(); } } } } Loading
app/src/main/java/app/fedilab/android/activities/ComposeActivity.java +38 −2 Original line number Diff line number Diff line Loading @@ -72,7 +72,6 @@ import app.fedilab.android.client.entities.api.EmojiInstance; import app.fedilab.android.client.entities.api.Mention; import app.fedilab.android.client.entities.api.ScheduledStatus; import app.fedilab.android.client.entities.api.Status; import app.fedilab.android.client.entities.app.Account; import app.fedilab.android.client.entities.app.BaseAccount; import app.fedilab.android.client.entities.app.StatusDraft; import app.fedilab.android.databinding.ActivityPaginationBinding; Loading @@ -84,6 +83,7 @@ import app.fedilab.android.helper.MastodonHelper; import app.fedilab.android.helper.MediaHelper; import app.fedilab.android.helper.SpannableHelper; import app.fedilab.android.helper.ThemeHelper; import app.fedilab.android.interfaces.OnDownloadInterface; import app.fedilab.android.jobs.ScheduleThreadWorker; import app.fedilab.android.services.PostMessageService; import app.fedilab.android.services.ThreadMessageService; Loading Loading @@ -134,6 +134,9 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana private app.fedilab.android.client.entities.api.Account accountMention; private String statusReplyId; private app.fedilab.android.client.entities.api.Account mentionBooster; private ArrayList<Uri> sharedUriList = new ArrayList<>(); private Uri sharedUri; private String sharedSubject, sharedContent, sharedTitle, sharedDescription, shareURL, sharedUrlMedia; @Override protected void onCreate(Bundle savedInstanceState) { Loading @@ -160,13 +163,24 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana scheduledStatus = (ScheduledStatus) b.getSerializable(Helper.ARG_STATUS_SCHEDULED); statusReplyId = b.getString(Helper.ARG_STATUS_REPLY_ID); statusMention = (Status) b.getSerializable(Helper.ARG_STATUS_MENTION); account = (Account) b.getSerializable(Helper.ARG_ACCOUNT); account = (BaseAccount) b.getSerializable(Helper.ARG_ACCOUNT); instance = b.getString(Helper.ARG_INSTANCE, null); token = b.getString(Helper.ARG_TOKEN, null); visibility = b.getString(Helper.ARG_VISIBILITY, null); mentionBooster = (app.fedilab.android.client.entities.api.Account) b.getSerializable(Helper.ARG_MENTION_BOOSTER); accountMention = (app.fedilab.android.client.entities.api.Account) b.getSerializable(Helper.ARG_ACCOUNT_MENTION); //Shared elements sharedUriList = b.getParcelableArrayList(Helper.ARG_SHARE_URI_LIST); sharedUri = b.getParcelable(Helper.ARG_SHARE_URI); sharedUrlMedia = b.getString(Helper.ARG_SHARE_URL_MEDIA); sharedSubject = b.getString(Helper.ARG_SHARE_SUBJECT, null); sharedContent = b.getString(Helper.ARG_SHARE_CONTENT, null); sharedTitle = b.getString(Helper.ARG_SHARE_TITLE, null); sharedDescription = b.getString(Helper.ARG_SHARE_DESCRIPTION, null); shareURL = b.getString(Helper.ARG_SHARE_URL, null); } binding.toolbar.setPopupTheme(Helper.popupStyle()); //Edit a scheduled status from server if (scheduledStatus != null) { Loading Loading @@ -342,6 +356,28 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana storeDraft(false); } }, 0, 10000); if (sharedUriList != null && sharedUriList.size() > 0) { List<Uri> uris = new ArrayList<>(sharedUriList); composeAdapter.addAttachment(-1, uris); } else if (sharedUri != null && !sharedUri.toString().startsWith("http")) { List<Uri> uris = new ArrayList<>(); uris.add(sharedUri); composeAdapter.addAttachment(-1, uris); } else if (shareURL != null) { Helper.download(ComposeActivity.this, sharedUrlMedia, new OnDownloadInterface() { @Override public void onDownloaded(String saveFilePath, String downloadUrl, Error error) { composeAdapter.addSharing(shareURL, sharedTitle, sharedDescription, sharedSubject, sharedContent, saveFilePath); } @Override public void onUpdateProgress(int progress) { } }); } } @Override Loading
app/src/main/java/app/fedilab/android/helper/CrossActionHelper.java +45 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package app.fedilab.android.helper; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.os.Handler; import android.os.Looper; Loading @@ -34,6 +35,7 @@ import java.util.concurrent.TimeUnit; import app.fedilab.android.BaseMainActivity; import app.fedilab.android.R; import app.fedilab.android.activities.BaseActivity; import app.fedilab.android.activities.ComposeActivity; import app.fedilab.android.client.endpoints.MastodonSearchService; import app.fedilab.android.client.entities.api.Results; Loading Loading @@ -399,6 +401,49 @@ public class CrossActionHelper { }).start(); } public static void doCrossShare(final Context context, final Bundle bundle) { List<BaseAccount> accounts; try { accounts = new Account(context).getAll(); List<app.fedilab.android.client.entities.api.Account> accountList = new ArrayList<>(); for (BaseAccount account : accounts) { accountList.add(account.mastodon_account); } if (accounts.size() == 1) { Intent intentToot = new Intent(context, ComposeActivity.class); intentToot.putExtras(bundle); context.startActivity(intentToot); ((BaseActivity) context).finish(); } else { AlertDialog.Builder builderSingle = new AlertDialog.Builder(context, Helper.dialogStyle()); builderSingle.setTitle(context.getString(R.string.choose_accounts)); final AccountsSearchAdapter accountsSearchAdapter = new AccountsSearchAdapter(context, accountList); final BaseAccount[] accountArray = new BaseAccount[accounts.size()]; int i = 0; for (BaseAccount account : accounts) { accountArray[i] = account; i++; } builderSingle.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss()); builderSingle.setAdapter(accountsSearchAdapter, (dialog, which) -> { final BaseAccount account = accountArray[which]; Intent intentToot = new Intent(context, ComposeActivity.class); bundle.putSerializable(Helper.ARG_ACCOUNT, account); intentToot.putExtras(bundle); context.startActivity(intentToot); ((BaseActivity) context).finish(); dialog.dismiss(); }); builderSingle.show(); } } catch (DBException e) { e.printStackTrace(); } } public enum TypeOfCrossAction { FOLLOW_ACTION, Loading
app/src/main/java/app/fedilab/android/helper/FileNameCleaner.java 0 → 100644 +30 −0 Original line number Diff line number Diff line package app.fedilab.android.helper; import java.util.Arrays; /** * Work from https://stackoverflow.com/a/26420820 */ public class FileNameCleaner { private final static int[] illegalChars = {34, 60, 62, 124, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 58, 42, 63, 92, 47}; static { Arrays.sort(illegalChars); } public static String cleanFileName(String badFileName) { StringBuilder cleanName = new StringBuilder(); if (badFileName.contains("?")) { badFileName = badFileName.split("\\?")[0]; } int len = badFileName.codePointCount(0, badFileName.length()); for (int i = 0; i < len; i++) { int c = badFileName.codePointAt(i); if (Arrays.binarySearch(illegalChars, c) < 0) { cleanName.appendCodePoint(c); } } return cleanName.toString(); } } No newline at end of file