ComposeActivity refactor (#1541)

* Convert ComposeActivity to Kotlin

* More ComposeActivity cleanups

* Move ComposeActivity to it's own package

* Remove ComposeActivity.IntentBuilder

* Re-do part of the media downsizing/uploading

* Add sending of status to ViewModel, draft media descriptions

* Allow uploading video, update description after uploading

* Enable camera, enable upload cancelling

* Cleanup of ComposeActivity

* Extract CaptionDialog, extract ComposeActivity methods

* Fix handling of redrafted media

* Add initial state and media uploading out of Activity

* Change ComposeOptions.mentionedUsernames to be Set rather than List

We probably don't want repeated usernames when we are writing a post
and Set provides such guarantee for free plus it tells it to the
callers. The only disadvantage is lack of order but it shouldn't be a
problem.

* Add combineOptionalLiveData. Add docs.

It it useful for nullable LiveData's. I think we cannot differentiate
between value not being set and value being null so I just added the
variant without null check.

* Add poll support to Compose.

* cleanup code

* move more classes into compose package

* cleanup code

* fix button behavior

* add error handling for media upload

* add caching for instance data again

* merge develop

* fix scheduled toots

* delete unused string

* cleanup ComposeActivity

* fix restoring media from drafts

* make media upload code a little bit clearer

* cleanup autocomplete search code

* avoid duplicate object creation in SavedTootActivity

* perf: avoid unnecessary work when initializing ComposeActivity

* add license header to new files

* use small toot button on bigger displays

* fix ComposeActivityTest

* fix bad merge

* use Singles.zip instead of Single.zip
This commit is contained in:
Ivan Kupalov 2019-12-19 19:09:40 +01:00 committed by Konrad Pozniak
commit 8770fbe986
68 changed files with 3162 additions and 2666 deletions

View file

@ -5,16 +5,18 @@ import android.content.ContentResolver;
import android.content.Context;
import android.net.Uri;
import android.os.AsyncTask;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.FileProvider;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.MimeTypeMap;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.FileProvider;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.keylesspalace.tusky.BuildConfig;
import com.keylesspalace.tusky.db.AppDatabase;
import com.keylesspalace.tusky.db.TootDao;
import com.keylesspalace.tusky.db.TootEntity;
import com.keylesspalace.tusky.entity.NewPoll;
@ -27,6 +29,8 @@ import java.util.Date;
import java.util.List;
import java.util.Locale;
import javax.inject.Inject;
public final class SaveTootHelper {
private static final String TAG = "SaveTootHelper";
@ -35,15 +39,16 @@ public final class SaveTootHelper {
private Context context;
private Gson gson = new Gson();
public SaveTootHelper(@NonNull TootDao tootDao, @NonNull Context context) {
this.tootDao = tootDao;
@Inject
public SaveTootHelper(@NonNull AppDatabase appDatabase, @NonNull Context context) {
this.tootDao = appDatabase.tootDao();
this.context = context;
}
@SuppressLint("StaticFieldLeak")
public boolean saveToot(@NonNull String content,
@NonNull String contentWarning,
@Nullable String savedJsonUrls,
@Nullable List<String> savedJsonUrls,
@NonNull List<String> mediaUris,
@NonNull List<String> mediaDescriptions,
int savedTootUid,
@ -58,31 +63,25 @@ public final class SaveTootHelper {
}
// Get any existing file's URIs.
ArrayList<String> existingUris = null;
if (!TextUtils.isEmpty(savedJsonUrls)) {
existingUris = gson.fromJson(savedJsonUrls,
new TypeToken<ArrayList<String>>() {
}.getType());
}
String mediaUrlsSerialized = null;
String mediaDescriptionsSerialized = null;
if (!ListUtils.isEmpty(mediaUris)) {
List<String> savedList = saveMedia(mediaUris, existingUris);
List<String> savedList = saveMedia(mediaUris, savedJsonUrls);
if (!ListUtils.isEmpty(savedList)) {
mediaUrlsSerialized = gson.toJson(savedList);
if (!ListUtils.isEmpty(existingUris)) {
deleteMedia(setDifference(existingUris, savedList));
if (!ListUtils.isEmpty(savedJsonUrls)) {
deleteMedia(setDifference(savedJsonUrls, savedList));
}
} else {
return false;
}
mediaDescriptionsSerialized = gson.toJson(mediaDescriptions);
} else if (!ListUtils.isEmpty(existingUris)) {
} else if (!ListUtils.isEmpty(savedJsonUrls)) {
/* If there were URIs in the previous draft, but they've now been removed, those files
* can be deleted. */
deleteMedia(existingUris);
deleteMedia(savedJsonUrls);
}
final TootEntity toot = new TootEntity(savedTootUid, content, mediaUrlsSerialized, mediaDescriptionsSerialized, contentWarning,
inReplyToId,
@ -103,15 +102,16 @@ public final class SaveTootHelper {
public void deleteDraft(int tootId) {
TootEntity item = tootDao.find(tootId);
if(item != null) {
if (item != null) {
deleteDraft(item);
}
}
public void deleteDraft(@NonNull TootEntity item){
public void deleteDraft(@NonNull TootEntity item) {
// Delete any media files associated with the status.
ArrayList<String> uris = gson.fromJson(item.getUrls(),
new TypeToken<ArrayList<String>>() {}.getType());
new TypeToken<ArrayList<String>>() {
}.getType());
if (uris != null) {
for (String uriString : uris) {
Uri uri = Uri.parse(uriString);
@ -172,7 +172,7 @@ public final class SaveTootHelper {
}
return null;
}
Uri resultUri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID+".fileprovider", file);
Uri resultUri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".fileprovider", file);
results.add(resultUri.toString());
}
return results;