Merge branch 'develop' into l10n_crowdin_localization_gitlab
This commit is contained in:
commit
ef52935307
|
@ -7,8 +7,8 @@ android {
|
|||
applicationId "fr.gouv.etalab.mastodon"
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 28
|
||||
versionCode 204
|
||||
versionName "1.41.1"
|
||||
versionCode 230
|
||||
versionName "1.66.0"
|
||||
multiDexEnabled true
|
||||
}
|
||||
dexOptions {
|
||||
|
@ -38,6 +38,9 @@ android {
|
|||
playstore {
|
||||
}
|
||||
}
|
||||
packagingOptions {
|
||||
exclude 'META-INF/proguard/androidx-annotations.pro'
|
||||
}
|
||||
}
|
||||
allprojects {
|
||||
repositories {
|
||||
|
@ -53,9 +56,10 @@ ext.evernoteLibraryVersion = '1.2.6'
|
|||
ext.gsonLibraryVersion = '2.8.2'
|
||||
ext.guavaLibraryVersion = '24.1-android'
|
||||
ext.photoViewLibraryVersion = '2.0.0'
|
||||
ext.swipebackLibraryVersion = '1.0.2'
|
||||
ext.swipebackLibraryVersion = '1.0.3'
|
||||
ext.ratethisappLibraryVersion = '1.2.0'
|
||||
ext.uploadServiceVersion = "3.4.2"
|
||||
ext.torrentstreamVersion = "2.5.0"
|
||||
|
||||
|
||||
dependencies {
|
||||
|
@ -73,16 +77,20 @@ dependencies {
|
|||
implementation "com.google.code.gson:gson:$gsonLibraryVersion"
|
||||
implementation "com.google.guava:guava:$guavaLibraryVersion"
|
||||
implementation "com.github.chrisbanes:PhotoView:$photoViewLibraryVersion"
|
||||
implementation "com.gongwen:swipeback:$swipebackLibraryVersion"
|
||||
implementation "com.github.stom79:SwipeBackLayout:$swipebackLibraryVersion"
|
||||
implementation 'com.github.stom79:country-picker-android:1.2.0'
|
||||
implementation 'com.github.stom79:mytransl:1.5'
|
||||
implementation 'com.github.stom79:SparkButton:1.0.10'
|
||||
implementation "com.koushikdutta.async:androidasync:2.+"
|
||||
implementation 'com.vanniktech:emoji-one:0.6.0-SNAPSHOT'
|
||||
implementation 'com.oguzdev:CircularFloatingActionMenu:1.0.2'
|
||||
implementation 'com.github.franmontiel:LocaleChanger:0.9.2'
|
||||
implementation 'com.github.stom79:SparkButton:1.0.10'
|
||||
implementation 'com.github.GrenderG:Toasty:1.3.0'
|
||||
implementation 'com.github.GrenderG:Toasty:1.3.1'
|
||||
implementation 'com.elconfidencial.bubbleshowcase:bubbleshowcase:1.3.1'
|
||||
implementation 'com.android.support:multidex:1.0.3'
|
||||
implementation 'com.google.android.exoplayer:exoplayer:2.9.3'
|
||||
implementation 'com.github.stom79:android-upload-service:3.4.2-Mastalab'
|
||||
implementation 'com.github.mabbas007:TagsEditText:1.0.5'
|
||||
implementation 'com.jaredrummler:material-spinner:1.3.1'
|
||||
playstoreImplementation "io.github.kobakei:ratethisapp:$ratethisappLibraryVersion"
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-feature android:name="android.hardware.camera" android:required="true" />
|
||||
<application
|
||||
android:name=".activities.MainApplication"
|
||||
|
@ -42,6 +43,7 @@
|
|||
<service
|
||||
android:name=".services.LiveNotificationService"
|
||||
android:exported="false"/>
|
||||
|
||||
<service android:name=".services.BackupStatusService"
|
||||
android:exported="false"/>
|
||||
<service android:name=".services.BackupStatusInDataBaseService"
|
||||
|
@ -59,6 +61,9 @@
|
|||
<action android:name="StopLiveNotificationReceiver" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<service
|
||||
android:name=".services.StreamingHomeTimelineService"
|
||||
android:exported="false"/>
|
||||
<service
|
||||
android:name=".services.StreamingFederatedTimelineService"
|
||||
android:exported="false"/>
|
||||
|
@ -178,6 +183,11 @@
|
|||
android:label="@string/app_name"
|
||||
android:launchMode="singleTask"
|
||||
/>
|
||||
<activity android:name=".activities.LanguageActivity"
|
||||
android:windowSoftInputMode="stateAlwaysHidden"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:label="@string/app_name"
|
||||
/>
|
||||
<activity android:name=".activities.AboutActivity"
|
||||
android:windowSoftInputMode="stateAlwaysHidden"
|
||||
android:configChanges="orientation|screenSize"
|
||||
|
@ -225,6 +235,16 @@
|
|||
android:theme="@style/Base.V7.Theme.AppCompat.Dialog"
|
||||
android:excludeFromRecents="true"
|
||||
/>
|
||||
<activity android:name=".activities.PeertubeUploadActivity"
|
||||
android:windowSoftInputMode="stateAlwaysHidden"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:label="@string/app_name"
|
||||
/>
|
||||
<activity android:name=".activities.PeertubeEditUploadActivity"
|
||||
android:windowSoftInputMode="stateAlwaysHidden"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:label="@string/app_name"
|
||||
/>
|
||||
<provider
|
||||
android:name="android.support.v4.content.FileProvider"
|
||||
android:authorities="fr.gouv.etalab.mastodon.fileProvider"
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -217,12 +217,15 @@ public class EditProfileActivity extends BaseActivity implements OnRetrieveAccou
|
|||
set_profile_name.setText(account.getDisplay_name());
|
||||
set_profile_name.setSelection(set_profile_name.getText().length());
|
||||
|
||||
final String content;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||
content = Html.fromHtml(account.getNote(), Html.FROM_HTML_MODE_LEGACY).toString();
|
||||
else
|
||||
//noinspection deprecation
|
||||
content = Html.fromHtml(account.getNote()).toString();
|
||||
String content = account.getNote();
|
||||
if( content != null) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||
content = Html.fromHtml(content, Html.FROM_HTML_MODE_LEGACY).toString();
|
||||
else
|
||||
//noinspection deprecation
|
||||
content = Html.fromHtml(content).toString();
|
||||
}else
|
||||
content = "";
|
||||
set_profile_description.setText(content);
|
||||
|
||||
set_profile_save.setEnabled(true);
|
||||
|
|
|
@ -126,7 +126,7 @@ public class HashTagActivity extends BaseActivity implements OnRetrieveFeedsInte
|
|||
mainLoader.setVisibility(View.VISIBLE);
|
||||
nextElementLoader.setVisibility(View.GONE);
|
||||
int positionSpinnerTrans = (sharedpreferences.getInt(Helper.SET_TRANSLATOR, Helper.TRANS_YANDEX));
|
||||
statusListAdapter = new StatusListAdapter(HashTagActivity.this, RetrieveFeedsAsyncTask.Type.TAG, null, isOnWifi, behaviorWithAttachments, positionSpinnerTrans, this.statuses);
|
||||
statusListAdapter = new StatusListAdapter(HashTagActivity.this, RetrieveFeedsAsyncTask.Type.TAG, null, isOnWifi, this.statuses);
|
||||
lv_status.setAdapter(statusListAdapter);
|
||||
setTitle(String.format("#%s", tag));
|
||||
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
|
||||
|
|
|
@ -0,0 +1,319 @@
|
|||
/* Copyright 2018 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Mastalab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Mastalab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
package fr.gouv.etalab.mastodon.activities;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import es.dmoral.toasty.Toasty;
|
||||
import fr.gouv.etalab.mastodon.R;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrieveRelationshipAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrieveRemoteDataAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Error;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Relationship;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Results;
|
||||
import fr.gouv.etalab.mastodon.drawers.AccountSearchDevAdapter;
|
||||
import fr.gouv.etalab.mastodon.helper.ExpandableHeightListView;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveRelationshipInterface;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveRemoteAccountInterface;
|
||||
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.THEME_LIGHT;
|
||||
|
||||
|
||||
/**
|
||||
* Created by Thomas on 22/12/2018.
|
||||
* Language activity
|
||||
*/
|
||||
|
||||
public class LanguageActivity extends BaseActivity implements OnRetrieveRemoteAccountInterface, OnRetrieveRelationshipInterface {
|
||||
|
||||
private List<Account> translators = new ArrayList<>();
|
||||
|
||||
private AccountSearchDevAdapter translatorManager;
|
||||
private int count2 = 0;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
|
||||
switch (theme){
|
||||
case Helper.THEME_LIGHT:
|
||||
setTheme(R.style.AppTheme);
|
||||
break;
|
||||
case Helper.THEME_DARK:
|
||||
setTheme(R.style.AppThemeDark);
|
||||
break;
|
||||
case Helper.THEME_BLACK:
|
||||
setTheme(R.style.AppThemeBlack);
|
||||
break;
|
||||
default:
|
||||
setTheme(R.style.AppThemeDark);
|
||||
}
|
||||
|
||||
if( getSupportActionBar() != null)
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if( actionBar != null ) {
|
||||
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
assert inflater != null;
|
||||
@SuppressLint("InflateParams") View view = inflater.inflate(R.layout.simple_bar, null);
|
||||
actionBar.setCustomView(view, new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
|
||||
ImageView toolbar_close = actionBar.getCustomView().findViewById(R.id.toolbar_close);
|
||||
TextView toolbar_title = actionBar.getCustomView().findViewById(R.id.toolbar_title);
|
||||
toolbar_close.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
toolbar_title.setText(R.string.languages);
|
||||
if (theme == THEME_LIGHT){
|
||||
Toolbar toolbar = actionBar.getCustomView().findViewById(R.id.toolbar);
|
||||
Helper.colorizeToolbar(toolbar, R.color.black, LanguageActivity.this);
|
||||
}
|
||||
}
|
||||
setContentView(R.layout.activity_language);
|
||||
|
||||
|
||||
|
||||
Button about_translation = findViewById(R.id.about_translation);
|
||||
|
||||
|
||||
about_translation.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://crowdin.com/project/mastalab"));
|
||||
startActivity(browserIntent);
|
||||
}
|
||||
});
|
||||
|
||||
ExpandableHeightListView lv_translator_manager = findViewById(R.id.lv_translator_manager);
|
||||
|
||||
setTitle(R.string.languages);
|
||||
lv_translator_manager.setExpanded(true);
|
||||
|
||||
translatorManager = new AccountSearchDevAdapter(LanguageActivity.this, translators);
|
||||
lv_translator_manager.setAdapter(translatorManager);
|
||||
|
||||
|
||||
new RetrieveRemoteDataAsyncTask(getApplicationContext(), "ButterflyOfFire", "mstdn.fr", LanguageActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
|
||||
|
||||
|
||||
String currentLanguage = sharedpreferences.getString(Helper.SET_DEFAULT_LOCALE_NEW, Helper.localeToStringStorage(Locale.getDefault()));
|
||||
Locale currentLocale = Helper.restoreLocaleFromString(currentLanguage);
|
||||
final Spinner set_change_locale = findViewById(R.id.set_change_locale);
|
||||
ArrayAdapter<String> adapterLocale = new ArrayAdapter<>(LanguageActivity.this,
|
||||
android.R.layout.simple_spinner_dropdown_item, Helper.getLocales(getApplicationContext()));
|
||||
|
||||
set_change_locale.setAdapter(adapterLocale);
|
||||
|
||||
int positionSpinnerLanguage = Helper.languageSpinnerPosition(getApplicationContext());
|
||||
set_change_locale.setSelection(positionSpinnerLanguage);
|
||||
set_change_locale.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
if( count2 > 0 ) {
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
switch (position) {
|
||||
case 0:
|
||||
editor.remove(Helper.SET_DEFAULT_LOCALE_NEW);
|
||||
editor.commit();
|
||||
break;
|
||||
case 1:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "en");
|
||||
editor.commit();
|
||||
break;
|
||||
case 2:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "fr");
|
||||
editor.commit();
|
||||
break;
|
||||
case 3:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "de");
|
||||
editor.commit();
|
||||
break;
|
||||
case 4:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "it");
|
||||
editor.commit();
|
||||
break;
|
||||
case 5:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "ja");
|
||||
editor.commit();
|
||||
break;
|
||||
case 6:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW,"zh-TW");
|
||||
editor.commit();
|
||||
break;
|
||||
case 7:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "zh-CN");
|
||||
editor.commit();
|
||||
break;
|
||||
case 8:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "eu");
|
||||
editor.commit();
|
||||
break;
|
||||
case 9:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "ar");
|
||||
editor.commit();
|
||||
break;
|
||||
case 10:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "nl");
|
||||
editor.commit();
|
||||
break;
|
||||
case 11:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "gl");
|
||||
editor.commit();
|
||||
break;
|
||||
case 12:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "el");
|
||||
editor.commit();
|
||||
break;
|
||||
case 13:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "pt");
|
||||
editor.commit();
|
||||
break;
|
||||
case 14:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "es");
|
||||
editor.commit();
|
||||
break;
|
||||
case 15:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "pl");
|
||||
editor.commit();
|
||||
break;
|
||||
case 16:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "sr");
|
||||
editor.commit();
|
||||
break;
|
||||
case 17:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "uk");
|
||||
editor.commit();
|
||||
case 18:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "ru");
|
||||
editor.commit();
|
||||
case 19:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "no");
|
||||
editor.commit();
|
||||
break;
|
||||
}
|
||||
|
||||
PackageManager packageManager = getPackageManager();
|
||||
Intent intent = packageManager.getLaunchIntentForPackage(getPackageName());
|
||||
assert intent != null;
|
||||
ComponentName componentName = intent.getComponent();
|
||||
Intent mainIntent = Intent.makeRestartActivityTask(componentName);
|
||||
startActivity(mainIntent);
|
||||
Runtime.getRuntime().exit(0);
|
||||
}
|
||||
count2++;
|
||||
}
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
finish();
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onRetrieveRemoteAccount(Results results) {
|
||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
if( results == null){
|
||||
Toasty.error(getApplicationContext(), getString(R.string.toast_error),Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
List<Account> accounts = results.getAccounts();
|
||||
Account account;
|
||||
if( accounts != null && accounts.size() > 0){
|
||||
account = accounts.get(0);
|
||||
account.setFollowing(true);
|
||||
switch (account.getUsername()) {
|
||||
case "ButterflyOfFire":
|
||||
translators.add(account);
|
||||
translatorManager.notifyDataSetChanged();
|
||||
break;
|
||||
}
|
||||
new RetrieveRelationshipAsyncTask(getApplicationContext(), account.getId(),LanguageActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onResume(){
|
||||
super.onResume();
|
||||
if( translators != null){
|
||||
for(Account account: translators){
|
||||
new RetrieveRelationshipAsyncTask(getApplicationContext(), account.getId(),LanguageActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRetrieveRelationship(Relationship relationship, Error error) {
|
||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, "");
|
||||
if( error != null){
|
||||
return;
|
||||
}
|
||||
for( int i = 0 ; i < translators.size() ; i++){
|
||||
if( translators.get(i).getId() != null && translators.get(i).getId().equals(relationship.getId())){
|
||||
translators.get(i).setFollowing(relationship.isFollowing() || userId.trim().equals(relationship.getId()));
|
||||
translatorManager.notifyDataSetChanged();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,6 +21,7 @@ import android.content.Intent;
|
|||
import android.content.SharedPreferences;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
|
@ -116,10 +117,8 @@ public class ListActivity extends BaseActivity implements OnListActionInterface
|
|||
mainLoader.setVisibility(View.VISIBLE);
|
||||
nextElementLoader.setVisibility(View.GONE);
|
||||
boolean isOnWifi = Helper.isOnWIFI(ListActivity.this);
|
||||
int behaviorWithAttachments = sharedpreferences.getInt(Helper.SET_ATTACHMENT_ACTION, Helper.ATTACHMENT_ALWAYS);
|
||||
int positionSpinnerTrans = sharedpreferences.getInt(Helper.SET_TRANSLATOR, Helper.TRANS_YANDEX);
|
||||
|
||||
statusListAdapter = new StatusListAdapter(ListActivity.this, RetrieveFeedsAsyncTask.Type.LIST, null, isOnWifi, behaviorWithAttachments, positionSpinnerTrans, this.statuses);
|
||||
statusListAdapter = new StatusListAdapter(ListActivity.this, RetrieveFeedsAsyncTask.Type.LIST, null, isOnWifi, this.statuses);
|
||||
|
||||
lv_status.setAdapter(statusListAdapter);
|
||||
mLayoutManager = new LinearLayoutManager(ListActivity.this);
|
||||
|
@ -139,7 +138,7 @@ public class ListActivity extends BaseActivity implements OnListActionInterface
|
|||
|
||||
|
||||
lv_status.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||
public void onScrolled(RecyclerView recyclerView, int dx, int dy)
|
||||
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy)
|
||||
{
|
||||
int firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();
|
||||
if(dy > 0){
|
||||
|
|
|
@ -45,6 +45,7 @@ import android.widget.ArrayAdapter;
|
|||
import android.widget.AutoCompleteTextView;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
@ -91,6 +92,9 @@ public class LoginActivity extends BaseActivity {
|
|||
boolean isLoadingInstance = false;
|
||||
private String oldSearch;
|
||||
private ImageView info_uid, info_instance, info_pwd, info_2FA;
|
||||
private CheckBox peertube_instance;
|
||||
private Button connectionButton;
|
||||
private String actionToken;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -117,12 +121,15 @@ public class LoginActivity extends BaseActivity {
|
|||
try {
|
||||
resobj = new JSONObject(response);
|
||||
String token = resobj.get("access_token").toString();
|
||||
String refresh_token = null;
|
||||
if( resobj.has("refresh_token"))
|
||||
refresh_token = resobj.get("refresh_token").toString();
|
||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.PREF_KEY_OAUTH_TOKEN, token);
|
||||
editor.apply();
|
||||
//Update the account with the token;
|
||||
new UpdateAccountInfoAsyncTask(LoginActivity.this, token, instance).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
new UpdateAccountInfoAsyncTask(LoginActivity.this, token, client_id, client_secret, refresh_token, instance, peertube_instance.isChecked()?UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE:UpdateAccountInfoAsyncTask.SOCIAL.MASTODON).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
} catch (JSONException ignored) {}
|
||||
} catch (Exception ignored) {}
|
||||
}}).start();
|
||||
|
@ -171,7 +178,7 @@ public class LoginActivity extends BaseActivity {
|
|||
} else {
|
||||
changeDrawableColor(getApplicationContext(), R.drawable.mastodon_icon, R.color.mastodonC3);
|
||||
}
|
||||
final Button connectionButton = findViewById(R.id.login_button);
|
||||
|
||||
login_instance = findViewById(R.id.login_instance);
|
||||
login_uid = findViewById(R.id.login_uid);
|
||||
login_passwd = findViewById(R.id.login_passwd);
|
||||
|
@ -179,6 +186,18 @@ public class LoginActivity extends BaseActivity {
|
|||
info_instance = findViewById(R.id.info_instance);
|
||||
info_pwd = findViewById(R.id.info_pwd);
|
||||
info_2FA = findViewById(R.id.info_2FA);
|
||||
peertube_instance = findViewById(R.id.peertube_instance);
|
||||
|
||||
peertube_instance.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
if( isChecked)
|
||||
login_uid.setHint(R.string.username);
|
||||
else
|
||||
login_uid.setHint(R.string.email);
|
||||
}
|
||||
});
|
||||
connectionButton = findViewById(R.id.login_button);
|
||||
|
||||
info_instance.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
|
@ -309,6 +328,7 @@ public class LoginActivity extends BaseActivity {
|
|||
startActivity(browserIntent);
|
||||
}
|
||||
});
|
||||
|
||||
login_instance.setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
||||
@Override
|
||||
public void onFocusChange(View v, boolean hasFocus) {
|
||||
|
@ -369,7 +389,7 @@ public class LoginActivity extends BaseActivity {
|
|||
@Override
|
||||
protected void onResume(){
|
||||
super.onResume();
|
||||
Button connectionButton = findViewById(R.id.login_button);
|
||||
|
||||
if (login_instance != null &&login_instance.getText() != null && login_instance.getText().toString().length() > 0 && client_id_for_webview) {
|
||||
connectionButton.setEnabled(false);
|
||||
client_id_for_webview = false;
|
||||
|
@ -378,24 +398,35 @@ public class LoginActivity extends BaseActivity {
|
|||
}
|
||||
|
||||
private void retrievesClientId(){
|
||||
final Button connectionButton = findViewById(R.id.login_button);
|
||||
try {
|
||||
instance = URLEncoder.encode(login_instance.getText().toString().trim(), "utf-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
Toasty.error(LoginActivity.this,getString(R.string.client_error), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
final String action = "/api/v1/apps";
|
||||
if( !peertube_instance.isChecked())
|
||||
actionToken = "/api/v1/apps";
|
||||
else
|
||||
actionToken = "/api/v1/oauth-clients/local";
|
||||
final HashMap<String, String> parameters = new HashMap<>();
|
||||
parameters.put(Helper.CLIENT_NAME, Helper.CLIENT_NAME_VALUE);
|
||||
parameters.put(Helper.REDIRECT_URIS, client_id_for_webview?Helper.REDIRECT_CONTENT_WEB:Helper.REDIRECT_CONTENT);
|
||||
parameters.put(Helper.SCOPES, Helper.OAUTH_SCOPES);
|
||||
if( !peertube_instance.isChecked()) {
|
||||
parameters.put(Helper.SCOPES, Helper.OAUTH_SCOPES);
|
||||
}else {
|
||||
parameters.put(Helper.SCOPES, Helper.OAUTH_SCOPES_PEERTUBE);
|
||||
}
|
||||
parameters.put(Helper.WEBSITE, Helper.WEBSITE_VALUE);
|
||||
|
||||
new Thread(new Runnable(){
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
final String response = new HttpsConnection(LoginActivity.this).post(Helper.instanceWithProtocol(instance) + action, 30, parameters, null );
|
||||
String response;
|
||||
if( !peertube_instance.isChecked())
|
||||
response = new HttpsConnection(LoginActivity.this).post(Helper.instanceWithProtocol(instance) + actionToken, 30, parameters, null );
|
||||
else
|
||||
response = new HttpsConnection(LoginActivity.this).get(Helper.instanceWithProtocol(instance) + actionToken, 30, parameters, null );
|
||||
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
JSONObject resobj;
|
||||
|
@ -403,7 +434,9 @@ public class LoginActivity extends BaseActivity {
|
|||
resobj = new JSONObject(response);
|
||||
client_id = resobj.get(Helper.CLIENT_ID).toString();
|
||||
client_secret = resobj.get(Helper.CLIENT_SECRET).toString();
|
||||
String id = resobj.get(Helper.ID).toString();
|
||||
String id = null;
|
||||
if( !peertube_instance.isChecked())
|
||||
id = resobj.get(Helper.ID).toString();
|
||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.CLIENT_ID, client_id);
|
||||
|
@ -418,6 +451,7 @@ public class LoginActivity extends BaseActivity {
|
|||
boolean embedded_browser = sharedpreferences.getBoolean(Helper.SET_EMBEDDED_BROWSER, true);
|
||||
if( embedded_browser) {
|
||||
Intent i = new Intent(LoginActivity.this, WebviewConnectActivity.class);
|
||||
i.putExtra("social", peertube_instance.isChecked()?UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE:UpdateAccountInfoAsyncTask.SOCIAL.MASTODON);
|
||||
i.putExtra("instance", instance);
|
||||
startActivity(i);
|
||||
}else{
|
||||
|
@ -471,25 +505,34 @@ public class LoginActivity extends BaseActivity {
|
|||
} catch (UnsupportedEncodingException e) {
|
||||
parameters.put("password",login_passwd.getText().toString());
|
||||
}
|
||||
parameters.put("scope"," read write follow");
|
||||
|
||||
String oauthUrl;
|
||||
if( !peertube_instance.isChecked()) {
|
||||
parameters.put("scope", " read write follow");
|
||||
oauthUrl = "/oauth/token";
|
||||
}else {
|
||||
parameters.put("scope", "user");
|
||||
oauthUrl = "/api/v1/users/token";
|
||||
}
|
||||
new Thread(new Runnable(){
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
final String response = new HttpsConnection(LoginActivity.this).post(Helper.instanceWithProtocol(instance) + "/oauth/token", 30, parameters, null );
|
||||
final String response = new HttpsConnection(LoginActivity.this).post(Helper.instanceWithProtocol(instance) + oauthUrl, 30, parameters, null );
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
JSONObject resobj;
|
||||
try {
|
||||
resobj = new JSONObject(response);
|
||||
String token = resobj.get("access_token").toString();
|
||||
String refresh_token = null;
|
||||
if( resobj.has("refresh_token"))
|
||||
refresh_token = resobj.get("refresh_token").toString();
|
||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.PREF_KEY_OAUTH_TOKEN, token);
|
||||
editor.apply();
|
||||
//Update the account with the token;
|
||||
new UpdateAccountInfoAsyncTask(LoginActivity.this, token, instance).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
new UpdateAccountInfoAsyncTask(LoginActivity.this, token, client_id, client_secret, refresh_token, instance, peertube_instance.isChecked()?UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE:UpdateAccountInfoAsyncTask.SOCIAL.MASTODON).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
} catch (JSONException ignored) {ignored.printStackTrace();}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -19,18 +19,22 @@ import android.content.SharedPreferences;
|
|||
import android.os.StrictMode;
|
||||
import android.support.multidex.MultiDex;
|
||||
import android.support.multidex.MultiDexApplication;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
|
||||
import com.evernote.android.job.JobManager;
|
||||
import com.franmontiel.localechanger.LocaleChanger;
|
||||
|
||||
import net.gotev.uploadservice.UploadService;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import es.dmoral.toasty.Toasty;
|
||||
import fr.gouv.etalab.mastodon.BuildConfig;
|
||||
import fr.gouv.etalab.mastodon.R;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.jobs.ApplicationJob;
|
||||
import fr.gouv.etalab.mastodon.jobs.HomeTimelineSyncJob;
|
||||
import fr.gouv.etalab.mastodon.jobs.NotificationsSyncJob;
|
||||
|
||||
/**
|
||||
|
@ -47,25 +51,37 @@ public class MainApplication extends MultiDexApplication {
|
|||
super.onCreate();
|
||||
JobManager.create(this).addJobCreator(new ApplicationJob());
|
||||
NotificationsSyncJob.schedule(false);
|
||||
HomeTimelineSyncJob.schedule(false);
|
||||
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
|
||||
StrictMode.setVmPolicy(builder.build());
|
||||
try {
|
||||
List<Locale> SUPPORTED_LOCALES = new ArrayList<>();
|
||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
|
||||
String defaultLocaleString = sharedpreferences.getString(Helper.SET_DEFAULT_LOCALE_NEW, Helper.getDefaultLocale());
|
||||
Locale defaultLocale;
|
||||
if( defaultLocaleString.equals("zh-CN"))
|
||||
defaultLocale = Locale.SIMPLIFIED_CHINESE;
|
||||
else if( defaultLocaleString.equals("zh-TW"))
|
||||
defaultLocale = Locale.TRADITIONAL_CHINESE;
|
||||
else
|
||||
defaultLocale = new Locale(defaultLocaleString);
|
||||
SUPPORTED_LOCALES.add(defaultLocale);
|
||||
String defaultLocaleString = sharedpreferences.getString(Helper.SET_DEFAULT_LOCALE_NEW, null);
|
||||
if( defaultLocaleString != null){
|
||||
Locale defaultLocale;
|
||||
if( defaultLocaleString.equals("zh-CN"))
|
||||
defaultLocale = Locale.SIMPLIFIED_CHINESE;
|
||||
else if( defaultLocaleString.equals("zh-TW"))
|
||||
defaultLocale = Locale.TRADITIONAL_CHINESE;
|
||||
else
|
||||
defaultLocale = new Locale(defaultLocaleString);
|
||||
SUPPORTED_LOCALES.add(defaultLocale);
|
||||
}else {
|
||||
SUPPORTED_LOCALES.add(Locale.getDefault());
|
||||
}
|
||||
LocaleChanger.initialize(getApplicationContext(), SUPPORTED_LOCALES);
|
||||
}catch (Exception ignored){ignored.printStackTrace();}
|
||||
Toasty.Config.getInstance().apply();
|
||||
}
|
||||
//Initialize upload service
|
||||
UploadService.NAMESPACE = BuildConfig.APPLICATION_ID;
|
||||
Toasty.Config.getInstance()
|
||||
.setErrorColor(ContextCompat.getColor(getApplicationContext(), R.color.toasty_background))
|
||||
.setInfoColor(ContextCompat.getColor(getApplicationContext(), R.color.toasty_background))
|
||||
.setSuccessColor(ContextCompat.getColor(getApplicationContext(), R.color.toasty_background))
|
||||
.setWarningColor(ContextCompat.getColor(getApplicationContext(), R.color.toasty_background))
|
||||
.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.toasty_text))
|
||||
.apply();
|
||||
Toasty.Config.getInstance().apply();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
|
|
|
@ -20,7 +20,6 @@ import android.content.SharedPreferences;
|
|||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.RectF;
|
||||
import android.media.MediaPlayer;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
|
@ -33,17 +32,22 @@ import android.view.MotionEvent;
|
|||
import android.view.View;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.MediaController;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.VideoView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.request.target.SimpleTarget;
|
||||
import com.bumptech.glide.request.transition.Transition;
|
||||
import com.github.chrisbanes.photoview.OnMatrixChangedListener;
|
||||
import com.github.chrisbanes.photoview.PhotoView;
|
||||
import com.google.android.exoplayer2.ExoPlayerFactory;
|
||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||
import com.google.android.exoplayer2.source.ExtractorMediaSource;
|
||||
import com.google.android.exoplayer2.ui.SimpleExoPlayerView;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import com.gw.swipeback.SwipeBackLayout;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -77,7 +81,7 @@ public class MediaActivity extends BaseActivity implements OnDownloadInterface {
|
|||
private RelativeLayout loader;
|
||||
private ArrayList<Attachment> attachments;
|
||||
private PhotoView imageView;
|
||||
private VideoView videoView;
|
||||
private SimpleExoPlayerView videoView;
|
||||
private float downX;
|
||||
private int mediaPosition;
|
||||
MediaActivity.actionSwipe currentAction;
|
||||
|
@ -94,7 +98,7 @@ public class MediaActivity extends BaseActivity implements OnDownloadInterface {
|
|||
private boolean canSwipe;
|
||||
private TextView media_description;
|
||||
private Attachment attachment;
|
||||
|
||||
SwipeBackLayout mSwipeBackLayout;
|
||||
private enum actionSwipe{
|
||||
RIGHT_TO_LEFT,
|
||||
LEFT_TO_RIGHT,
|
||||
|
@ -112,7 +116,7 @@ public class MediaActivity extends BaseActivity implements OnDownloadInterface {
|
|||
setTheme(R.style.TransparentBlack);
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_media);
|
||||
SwipeBackLayout mSwipeBackLayout = new SwipeBackLayout(MediaActivity.this);
|
||||
mSwipeBackLayout = new SwipeBackLayout(MediaActivity.this);
|
||||
mSwipeBackLayout.setDirectionMode(SwipeBackLayout.FROM_BOTTOM);
|
||||
mSwipeBackLayout.setMaskAlpha(125);
|
||||
mSwipeBackLayout.setSwipeBackFactor(0.5f);
|
||||
|
@ -157,7 +161,7 @@ public class MediaActivity extends BaseActivity implements OnDownloadInterface {
|
|||
media_save.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if(attachment.getType().equals("video") || attachment.getType().equals("gifv")) {
|
||||
if(attachment.getType().toLowerCase().equals("video") || attachment.getType().toLowerCase().equals("gifv")) {
|
||||
if( attachment != null ) {
|
||||
progress.setText("0 %");
|
||||
progress.setVisibility(View.VISIBLE);
|
||||
|
@ -236,6 +240,7 @@ public class MediaActivity extends BaseActivity implements OnDownloadInterface {
|
|||
@Override
|
||||
public void onMatrixChanged(RectF rect) {
|
||||
canSwipe = (imageView.getScale() == 1 );
|
||||
mSwipeBackLayout.isDisabled(imageView.getScale() != 1 );
|
||||
}
|
||||
});
|
||||
pbar_inf = findViewById(R.id.pbar_inf);
|
||||
|
@ -344,9 +349,7 @@ public class MediaActivity extends BaseActivity implements OnDownloadInterface {
|
|||
String url = attachment.getUrl();
|
||||
finalUrlDownload = url;
|
||||
videoView.setVisibility(View.GONE);
|
||||
if( videoView.isPlaying()) {
|
||||
videoView.stopPlayback();
|
||||
}
|
||||
|
||||
imageView.setVisibility(View.GONE);
|
||||
|
||||
if( attachment.getDescription() != null && !attachment.getDescription().equals("null")){
|
||||
|
@ -368,7 +371,7 @@ public class MediaActivity extends BaseActivity implements OnDownloadInterface {
|
|||
attachment.setType(type);
|
||||
}
|
||||
final String finalUrl = url;
|
||||
switch (type){
|
||||
switch (type.toLowerCase()){
|
||||
case "image":
|
||||
pbar_inf.setScaleY(1f);
|
||||
imageView.setVisibility(View.VISIBLE);
|
||||
|
@ -429,37 +432,36 @@ public class MediaActivity extends BaseActivity implements OnDownloadInterface {
|
|||
Uri uri = Uri.parse(file.getAbsolutePath());
|
||||
videoView.setVisibility(View.VISIBLE);
|
||||
|
||||
videoView.setVideoURI(uri);
|
||||
videoView.start();
|
||||
MediaController mc = new MediaController(MediaActivity.this);
|
||||
mc.setPadding(0, 0, 0, (int)Helper.convertDpToPixel(25, MediaActivity.this));
|
||||
videoView.setMediaController(mc);
|
||||
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
|
||||
@Override
|
||||
public void onPrepared(MediaPlayer mp) {
|
||||
loader.setVisibility(View.GONE);
|
||||
mp.start();
|
||||
mp.setLooping(true);
|
||||
}
|
||||
});
|
||||
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(getApplicationContext(),
|
||||
Util.getUserAgent(getApplicationContext(), "Mastalab"), null);
|
||||
|
||||
ExtractorMediaSource videoSource = new ExtractorMediaSource.Factory(dataSourceFactory)
|
||||
.createMediaSource(uri);
|
||||
|
||||
SimpleExoPlayer player = ExoPlayerFactory.newSimpleInstance(MediaActivity.this);
|
||||
videoView.setPlayer(player);
|
||||
loader.setVisibility(View.GONE);
|
||||
player.prepare(videoSource);
|
||||
player.setPlayWhenReady(true);
|
||||
fileVideo = file;
|
||||
downloadedImage = null;
|
||||
}else{
|
||||
videoView.setVisibility(View.VISIBLE);
|
||||
Uri uri = Uri.parse(url);
|
||||
videoView.setVideoURI(uri);
|
||||
videoView.start();
|
||||
MediaController mc = new MediaController(MediaActivity.this);
|
||||
mc.setAnchorView(videoView);
|
||||
videoView.setMediaController(mc);
|
||||
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
|
||||
@Override
|
||||
public void onPrepared(MediaPlayer mp) {
|
||||
mp.start();
|
||||
mp.setLooping(true);
|
||||
}
|
||||
});
|
||||
videoView.start();
|
||||
|
||||
videoView.setVisibility(View.VISIBLE);
|
||||
|
||||
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(getApplicationContext(),
|
||||
Util.getUserAgent(getApplicationContext(), "Mastalab"), null);
|
||||
|
||||
ExtractorMediaSource videoSource = new ExtractorMediaSource.Factory(dataSourceFactory)
|
||||
.createMediaSource(uri);
|
||||
|
||||
SimpleExoPlayer player = ExoPlayerFactory.newSimpleInstance(MediaActivity.this);
|
||||
videoView.setPlayer(player);
|
||||
loader.setVisibility(View.GONE);
|
||||
player.prepare(videoSource);
|
||||
player.setPlayWhenReady(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -164,11 +164,9 @@ public class OwnerStatusActivity extends BaseActivity implements OnRetrieveFeeds
|
|||
firstLoad = true;
|
||||
swiped = false;
|
||||
boolean isOnWifi = Helper.isOnWIFI(OwnerStatusActivity.this);
|
||||
int positionSpinnerTrans = sharedpreferences.getInt(Helper.SET_TRANSLATOR, Helper.TRANS_YANDEX);
|
||||
int behaviorWithAttachments = sharedpreferences.getInt(Helper.SET_ATTACHMENT_ACTION, Helper.ATTACHMENT_ALWAYS);
|
||||
lv_status.addItemDecoration(new DividerItemDecoration(OwnerStatusActivity.this, DividerItemDecoration.VERTICAL));
|
||||
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
statusListAdapter = new StatusListAdapter(OwnerStatusActivity.this, RetrieveFeedsAsyncTask.Type.CACHE_STATUS, userId, isOnWifi, behaviorWithAttachments, positionSpinnerTrans, this.statuses);
|
||||
statusListAdapter = new StatusListAdapter(OwnerStatusActivity.this, RetrieveFeedsAsyncTask.Type.CACHE_STATUS, userId, isOnWifi, this.statuses);
|
||||
lv_status.setAdapter(statusListAdapter);
|
||||
mLayoutManager = new LinearLayoutManager(OwnerStatusActivity.this);
|
||||
lv_status.setLayoutManager(mLayoutManager);
|
||||
|
|
|
@ -17,22 +17,23 @@ package fr.gouv.etalab.mastodon.activities;
|
|||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.media.MediaPlayer;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.widget.AppCompatImageView;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
|
@ -43,13 +44,27 @@ import android.view.MenuItem;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.webkit.WebView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.EditText;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import android.widget.VideoView;
|
||||
|
||||
import com.google.android.exoplayer2.ExoPlayerFactory;
|
||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||
import com.google.android.exoplayer2.source.ExtractorMediaSource;
|
||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
||||
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout;
|
||||
import com.google.android.exoplayer2.ui.PlaybackControlView;
|
||||
import com.google.android.exoplayer2.ui.SimpleExoPlayerView;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.security.KeyManagementException;
|
||||
|
@ -61,11 +76,14 @@ import javax.net.ssl.HttpsURLConnection;
|
|||
|
||||
import es.dmoral.toasty.Toasty;
|
||||
import fr.gouv.etalab.mastodon.R;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.PostActionAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrieveFeedsAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrievePeertubeSingleAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrievePeertubeSingleCommentsAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.UpdateAccountInfoAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.client.API;
|
||||
import fr.gouv.etalab.mastodon.client.APIResponse;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Error;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Peertube;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Results;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Status;
|
||||
|
@ -73,12 +91,17 @@ import fr.gouv.etalab.mastodon.client.TLSSocketFactory;
|
|||
import fr.gouv.etalab.mastodon.drawers.StatusListAdapter;
|
||||
import fr.gouv.etalab.mastodon.helper.FullScreenMediaController;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnPostActionInterface;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrievePeertubeInterface;
|
||||
import fr.gouv.etalab.mastodon.sqlite.PeertubeFavoritesDAO;
|
||||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||
import fr.gouv.etalab.mastodon.webview.MastalabWebChromeClient;
|
||||
import fr.gouv.etalab.mastodon.webview.MastalabWebViewClient;
|
||||
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.EXTERNAL_STORAGE_REQUEST_CODE;
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.THEME_LIGHT;
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.VIDEO_MODE_DIRECT;
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.VIDEO_MODE_WEBVIEW;
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.changeDrawableColor;
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.manageDownloads;
|
||||
|
||||
|
||||
|
@ -87,19 +110,26 @@ import static fr.gouv.etalab.mastodon.helper.Helper.manageDownloads;
|
|||
* Peertube activity
|
||||
*/
|
||||
|
||||
public class PeertubeActivity extends BaseActivity implements OnRetrievePeertubeInterface {
|
||||
public class PeertubeActivity extends BaseActivity implements OnRetrievePeertubeInterface, OnPostActionInterface {
|
||||
|
||||
private String peertubeInstance, videoId;
|
||||
private FullScreenMediaController.fullscreen fullscreen;
|
||||
private VideoView videoView;
|
||||
private RelativeLayout loader;
|
||||
private TextView peertube_view_count, peertube_bookmark, peertube_like_count, peertube_dislike_count, peertube_share, peertube_download, peertube_description, peertube_title;
|
||||
private ScrollView peertube_information_container;
|
||||
private MediaPlayer mediaPlayer;
|
||||
private FullScreenMediaController fullScreenMediaController;
|
||||
private int stopPosition;
|
||||
private Peertube peertube;
|
||||
private TextView toolbar_title;
|
||||
public static String video_id;
|
||||
private SimpleExoPlayerView playerView;
|
||||
private SimpleExoPlayer player;
|
||||
private boolean fullScreenMode;
|
||||
private Dialog fullScreenDialog;
|
||||
private AppCompatImageView fullScreenIcon;
|
||||
private TextView resolution;
|
||||
private DefaultTrackSelector trackSelector;
|
||||
private int mode;
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -120,7 +150,7 @@ public class PeertubeActivity extends BaseActivity implements OnRetrievePeertube
|
|||
default:
|
||||
setTheme(R.style.AppThemeDark);
|
||||
}
|
||||
|
||||
fullScreenMode = false;
|
||||
setContentView(R.layout.activity_peertube);
|
||||
loader = findViewById(R.id.loader);
|
||||
peertube_view_count = findViewById(R.id.peertube_view_count);
|
||||
|
@ -132,8 +162,9 @@ public class PeertubeActivity extends BaseActivity implements OnRetrievePeertube
|
|||
peertube_description = findViewById(R.id.peertube_description);
|
||||
peertube_title = findViewById(R.id.peertube_title);
|
||||
peertube_information_container = findViewById(R.id.peertube_information_container);
|
||||
WebView webview_video = findViewById(R.id.webview_video);
|
||||
playerView = findViewById(R.id.media_video);
|
||||
|
||||
loader.setVisibility(View.VISIBLE);
|
||||
Bundle b = getIntent().getExtras();
|
||||
if(b != null) {
|
||||
peertubeInstance = b.getString("peertube_instance", null);
|
||||
|
@ -161,15 +192,75 @@ public class PeertubeActivity extends BaseActivity implements OnRetrievePeertube
|
|||
Helper.colorizeToolbar(toolbar, R.color.black, PeertubeActivity.this);
|
||||
}
|
||||
}
|
||||
videoView = findViewById(R.id.media_video);
|
||||
new RetrievePeertubeSingleAsyncTask(PeertubeActivity.this, peertubeInstance, videoId, PeertubeActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
|
||||
|
||||
mode = sharedpreferences.getInt(Helper.SET_VIDEO_MODE, Helper.VIDEO_MODE_DIRECT);
|
||||
if( mode != Helper.VIDEO_MODE_WEBVIEW && mode != Helper.VIDEO_MODE_DIRECT)
|
||||
mode = VIDEO_MODE_DIRECT;
|
||||
if( mode == Helper.VIDEO_MODE_WEBVIEW){
|
||||
webview_video.setVisibility(View.VISIBLE);
|
||||
playerView.setVisibility(View.GONE);
|
||||
|
||||
webview_video = Helper.initializeWebview(PeertubeActivity.this, R.id.webview_video);
|
||||
FrameLayout webview_container = findViewById(R.id.main_media_frame);
|
||||
final ViewGroup videoLayout = findViewById(R.id.videoLayout);
|
||||
|
||||
MastalabWebChromeClient mastalabWebChromeClient = new MastalabWebChromeClient(PeertubeActivity.this, webview_video, webview_container, videoLayout);
|
||||
mastalabWebChromeClient.setOnToggledFullscreen(new MastalabWebChromeClient.ToggledFullscreenCallback() {
|
||||
@Override
|
||||
public void toggledFullscreen(boolean fullscreen) {
|
||||
|
||||
if (fullscreen) {
|
||||
videoLayout.setVisibility(View.VISIBLE);
|
||||
WindowManager.LayoutParams attrs = getWindow().getAttributes();
|
||||
attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
|
||||
attrs.flags |= WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
|
||||
getWindow().setAttributes(attrs);
|
||||
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
|
||||
peertube_information_container.setVisibility(View.GONE);
|
||||
} else {
|
||||
WindowManager.LayoutParams attrs = getWindow().getAttributes();
|
||||
attrs.flags &= ~WindowManager.LayoutParams.FLAG_FULLSCREEN;
|
||||
attrs.flags &= ~WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
|
||||
getWindow().setAttributes(attrs);
|
||||
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
|
||||
videoLayout.setVisibility(View.GONE);
|
||||
peertube_information_container.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
});
|
||||
webview_video.getSettings().setAllowFileAccess(true);
|
||||
webview_video.setWebChromeClient(mastalabWebChromeClient);
|
||||
webview_video.getSettings().setDomStorageEnabled(true);
|
||||
webview_video.getSettings().setAppCacheEnabled(true);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
webview_video.getSettings().setMediaPlaybackRequiresUserGesture(false);
|
||||
}
|
||||
webview_video.setWebViewClient(new MastalabWebViewClient(PeertubeActivity.this));
|
||||
webview_video.loadUrl("https://" + peertubeInstance + "/videos/embed/" + videoId);
|
||||
}else {
|
||||
webview_video.setVisibility(View.GONE);
|
||||
playerView.setVisibility(View.VISIBLE);
|
||||
loader.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
|
||||
if( mode != Helper.VIDEO_MODE_WEBVIEW){
|
||||
playerView.setControllerShowTimeoutMs(1000);
|
||||
playerView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FIT);
|
||||
initFullscreenDialog();
|
||||
initFullscreenButton();
|
||||
}
|
||||
|
||||
|
||||
|
||||
new RetrievePeertubeSingleAsyncTask(PeertubeActivity.this, peertubeInstance, videoId, PeertubeActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
public void change(){
|
||||
if(fullscreen == FullScreenMediaController.fullscreen.ON){
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN |
|
||||
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
Objects.requireNonNull(getSupportActionBar()).hide();
|
||||
peertube_information_container.setVisibility(View.GONE);
|
||||
}else{
|
||||
|
@ -200,41 +291,84 @@ public class PeertubeActivity extends BaseActivity implements OnRetrievePeertube
|
|||
finish();
|
||||
return true;
|
||||
case R.id.action_comment:
|
||||
Toasty.info(PeertubeActivity.this, getString(R.string.retrieve_remote_status), Toast.LENGTH_LONG).show();
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
if( MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON) {
|
||||
Toasty.info(PeertubeActivity.this, getString(R.string.retrieve_remote_status), Toast.LENGTH_LONG).show();
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
|
||||
private List<fr.gouv.etalab.mastodon.client.Entities.Status> remoteStatuses;
|
||||
private WeakReference<Context> contextReference = new WeakReference<>(PeertubeActivity.this);
|
||||
private List<fr.gouv.etalab.mastodon.client.Entities.Status> remoteStatuses;
|
||||
private WeakReference<Context> contextReference = new WeakReference<>(PeertubeActivity.this);
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... voids) {
|
||||
@Override
|
||||
protected Void doInBackground(Void... voids) {
|
||||
|
||||
if(peertube != null) {
|
||||
Results search = new API(contextReference.get()).search("https://" + peertube.getAccount().getHost() + "/videos/watch/" + peertube.getUuid());
|
||||
if (search != null) {
|
||||
remoteStatuses = search.getStatuses();
|
||||
if (peertube != null) {
|
||||
Results search = new API(contextReference.get()).search("https://" + peertube.getAccount().getHost() + "/videos/watch/" + peertube.getUuid());
|
||||
if (search != null) {
|
||||
remoteStatuses = search.getStatuses();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void result) {
|
||||
Intent intent = new Intent(contextReference.get(), TootActivity.class);
|
||||
Bundle b = new Bundle();
|
||||
if (remoteStatuses == null || remoteStatuses.size() == 0) {
|
||||
Toasty.error(contextReference.get(), getString(R.string.toast_error), Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
if (remoteStatuses.get(0).getReblog() != null) {
|
||||
b.putParcelable("tootReply", remoteStatuses.get(0).getReblog());
|
||||
} else {
|
||||
b.putParcelable("tootReply", remoteStatuses.get(0));
|
||||
}
|
||||
intent.putExtras(b); //Put your id to your next Intent
|
||||
contextReference.get().startActivity(intent);
|
||||
}
|
||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}else if( MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE){
|
||||
if(! peertube.isCommentsEnabled()) {
|
||||
Toasty.info(PeertubeActivity.this, getString(R.string.comment_no_allowed_peertube),Toast.LENGTH_LONG).show();
|
||||
return true;
|
||||
}
|
||||
int style;
|
||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
|
||||
if (theme == Helper.THEME_DARK) {
|
||||
style = R.style.DialogDark;
|
||||
} else if (theme == Helper.THEME_BLACK){
|
||||
style = R.style.DialogBlack;
|
||||
}else {
|
||||
style = R.style.Dialog;
|
||||
}
|
||||
AlertDialog.Builder builderInner;
|
||||
builderInner = new AlertDialog.Builder(PeertubeActivity.this, style);
|
||||
builderInner.setTitle(R.string.comment);
|
||||
EditText input = new EditText(PeertubeActivity.this);
|
||||
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT);
|
||||
input.setLayoutParams(lp);
|
||||
builderInner.setView(input);
|
||||
builderInner.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog,int which) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
builderInner.setPositiveButton(R.string.validate, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog,int which) {
|
||||
String comment = input.getText().toString();
|
||||
if( comment.trim().length() > 0 ) {
|
||||
new PostActionAsyncTask(getApplicationContext(), API.StatusAction.PEERTUBECOMMENT, peertube.getId(), null, comment, PeertubeActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
dialog.dismiss();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void result) {
|
||||
Intent intent = new Intent(contextReference.get(), TootActivity.class);
|
||||
Bundle b = new Bundle();
|
||||
if( remoteStatuses == null || remoteStatuses.size() == 0){
|
||||
Toasty.error(contextReference.get(), getString(R.string.toast_error), Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
if( remoteStatuses.get(0).getReblog() != null ) {
|
||||
b.putParcelable("tootReply", remoteStatuses.get(0).getReblog());
|
||||
}else {
|
||||
b.putParcelable("tootReply", remoteStatuses.get(0));
|
||||
}
|
||||
intent.putExtras(b); //Put your id to your next Intent
|
||||
contextReference.get().startActivity(intent);
|
||||
}
|
||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR );
|
||||
});
|
||||
builderInner.show();
|
||||
}
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
|
@ -280,8 +414,32 @@ public class PeertubeActivity extends BaseActivity implements OnRetrievePeertube
|
|||
peertube_dislike_count.setText(String.valueOf(peertube.getDislike()));
|
||||
peertube_like_count.setText(String.valueOf(peertube.getLike()));
|
||||
peertube_view_count.setText(String.valueOf(peertube.getView()));
|
||||
video_id = peertube.getId();
|
||||
|
||||
changeColor();
|
||||
initResolution();
|
||||
|
||||
if( MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE){
|
||||
peertube_like_count.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
String newState = peertube.getMyRating().equals("like")?"none":"like";
|
||||
new PostActionAsyncTask(getApplicationContext(), API.StatusAction.RATEVIDEO, peertube.getId(), null, newState, PeertubeActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
peertube.setMyRating(newState);
|
||||
changeColor();
|
||||
}
|
||||
});
|
||||
peertube_dislike_count.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
String newState = peertube.getMyRating().equals("dislike")?"none":"dislike";
|
||||
new PostActionAsyncTask(getApplicationContext(), API.StatusAction.RATEVIDEO, peertube.getId(), null, newState, PeertubeActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
peertube.setMyRating(newState);
|
||||
changeColor();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Uri uri = Uri.parse(apiResponse.getPeertubes().get(0).getFileUrl(null));
|
||||
try {
|
||||
HttpsURLConnection.setDefaultSSLSocketFactory(new TLSSocketFactory());
|
||||
} catch (KeyManagementException e) {
|
||||
|
@ -289,29 +447,30 @@ public class PeertubeActivity extends BaseActivity implements OnRetrievePeertube
|
|||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
videoView.setVideoURI(uri);
|
||||
videoView.getCurrentPosition();
|
||||
fullScreenMediaController = new FullScreenMediaController(PeertubeActivity.this, peertube);
|
||||
fullScreenMediaController.setPadding(0, 0, 0, (int)Helper.convertDpToPixel(25, PeertubeActivity.this));
|
||||
fullScreenMediaController.setAnchorView(videoView);
|
||||
videoView.setMediaController(fullScreenMediaController);
|
||||
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
|
||||
@Override
|
||||
public void onPrepared(MediaPlayer mp) {
|
||||
loader.setVisibility(View.GONE);
|
||||
mediaPlayer = mp;
|
||||
mp.start();
|
||||
}
|
||||
});
|
||||
|
||||
videoView.start();
|
||||
if( mode == Helper.VIDEO_MODE_DIRECT){
|
||||
|
||||
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(getApplicationContext(),
|
||||
Util.getUserAgent(getApplicationContext(), "Mastalab"), null);
|
||||
|
||||
ExtractorMediaSource videoSource = new ExtractorMediaSource.Factory(dataSourceFactory)
|
||||
.createMediaSource(Uri.parse(apiResponse.getPeertubes().get(0).getFileUrl(null)));
|
||||
|
||||
player = ExoPlayerFactory.newSimpleInstance(PeertubeActivity.this);
|
||||
playerView.setPlayer(player);
|
||||
loader.setVisibility(View.GONE);
|
||||
|
||||
player.prepare(videoSource);
|
||||
player.setPlayWhenReady(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
peertube_download.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if(Build.VERSION.SDK_INT >= 23 ){
|
||||
if (ContextCompat.checkSelfPermission(PeertubeActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(PeertubeActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
||||
ActivityCompat.requestPermissions(PeertubeActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, EXTERNAL_STORAGE_REQUEST_CODE);
|
||||
} else {
|
||||
manageDownloads(PeertubeActivity.this, peertube.getFileDownloadUrl(null));
|
||||
}
|
||||
|
@ -380,6 +539,34 @@ public class PeertubeActivity extends BaseActivity implements OnRetrievePeertube
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
|
||||
if( mode != VIDEO_MODE_WEBVIEW) {
|
||||
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||
openFullscreenDialog();
|
||||
setFullscreen(FullScreenMediaController.fullscreen.ON);
|
||||
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||
closeFullscreenDialog();
|
||||
setFullscreen(FullScreenMediaController.fullscreen.OFF);
|
||||
}
|
||||
change();
|
||||
}else {
|
||||
final ViewGroup videoLayout = findViewById(R.id.videoLayout);
|
||||
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||
setFullscreen(FullScreenMediaController.fullscreen.ON);
|
||||
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||
setFullscreen(FullScreenMediaController.fullscreen.OFF);
|
||||
}
|
||||
change();
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRetrievePeertubeComments(APIResponse apiResponse) {
|
||||
if( apiResponse == null || (apiResponse.getError() != null && apiResponse.getError().getStatusCode() != 404) ){
|
||||
|
@ -390,19 +577,18 @@ public class PeertubeActivity extends BaseActivity implements OnRetrievePeertube
|
|||
return;
|
||||
}
|
||||
List<Status> statuses = apiResponse.getStatuses();
|
||||
RelativeLayout no_action = findViewById(R.id.no_action);
|
||||
RecyclerView lv_comments = findViewById(R.id.peertube_comments);
|
||||
if( statuses == null || statuses.size() == 0){
|
||||
RelativeLayout no_action = findViewById(R.id.no_action);
|
||||
no_action.setVisibility(View.VISIBLE);
|
||||
RecyclerView lv_comments = findViewById(R.id.peertube_comments);
|
||||
lv_comments.setVisibility(View.GONE);
|
||||
}else {
|
||||
no_action.setVisibility(View.GONE);
|
||||
lv_comments.setVisibility(View.VISIBLE);
|
||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
boolean isOnWifi = Helper.isOnWIFI(PeertubeActivity.this);
|
||||
int behaviorWithAttachments = sharedpreferences.getInt(Helper.SET_ATTACHMENT_ACTION, Helper.ATTACHMENT_ALWAYS);
|
||||
int positionSpinnerTrans = sharedpreferences.getInt(Helper.SET_TRANSLATOR, Helper.TRANS_YANDEX);
|
||||
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
StatusListAdapter statusListAdapter = new StatusListAdapter(PeertubeActivity.this, RetrieveFeedsAsyncTask.Type.REMOTE_INSTANCE, userId, isOnWifi, behaviorWithAttachments, positionSpinnerTrans, statuses);
|
||||
RecyclerView lv_comments = findViewById(R.id.peertube_comments);
|
||||
StatusListAdapter statusListAdapter = new StatusListAdapter(PeertubeActivity.this, RetrieveFeedsAsyncTask.Type.REMOTE_INSTANCE, userId, isOnWifi, statuses);
|
||||
LinearLayoutManager mLayoutManager = new LinearLayoutManager(PeertubeActivity.this);
|
||||
lv_comments.setLayoutManager(mLayoutManager);
|
||||
lv_comments.setNestedScrollingEnabled(false);
|
||||
|
@ -411,22 +597,30 @@ public class PeertubeActivity extends BaseActivity implements OnRetrievePeertube
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRetrievePeertubeChannels(APIResponse apiResponse) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
if( videoView != null) {
|
||||
stopPosition = videoView.getCurrentPosition(); //stopPosition is an int
|
||||
videoView.pause();
|
||||
if( player != null) {
|
||||
player.setPlayWhenReady(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onResume(){
|
||||
super.onResume();
|
||||
if( videoView != null) {
|
||||
videoView.seekTo(stopPosition);
|
||||
videoView.resume();
|
||||
videoView.start();
|
||||
if( player != null) {
|
||||
player.setPlayWhenReady(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -456,17 +650,117 @@ public class PeertubeActivity extends BaseActivity implements OnRetrievePeertube
|
|||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
String res = arrayAdapter.getItem(which).substring(0, arrayAdapter.getItem(which).length() - 1);
|
||||
if( mediaPlayer != null) {
|
||||
int position = videoView.getCurrentPosition();
|
||||
mediaPlayer.stop();
|
||||
videoView.setVideoURI(Uri.parse(peertube.getFileUrl(res)));
|
||||
fullScreenMediaController.setResolutionVal(res);
|
||||
videoView.seekTo(position);
|
||||
videoView.start();
|
||||
|
||||
if( playerView != null) {
|
||||
loader.setVisibility(View.VISIBLE);
|
||||
long position = player.getCurrentPosition();
|
||||
PlaybackControlView controlView = playerView.findViewById(R.id.exo_controller);
|
||||
resolution = controlView.findViewById(R.id.resolution);
|
||||
resolution.setText(String.format("%sp",res));
|
||||
if( mode == VIDEO_MODE_DIRECT){
|
||||
|
||||
player = ExoPlayerFactory.newSimpleInstance(PeertubeActivity.this);
|
||||
playerView.setPlayer(player);
|
||||
loader.setVisibility(View.GONE);
|
||||
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(getApplicationContext(),
|
||||
Util.getUserAgent(getApplicationContext(), "Mastalab"), null);
|
||||
|
||||
ExtractorMediaSource videoSource = new ExtractorMediaSource.Factory(dataSourceFactory)
|
||||
.createMediaSource(Uri.parse(peertube.getFileUrl(res)));
|
||||
player.prepare(videoSource);
|
||||
player.seekTo(0, position);
|
||||
player.setPlayWhenReady(true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
builderSingle.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPostAction(int statusCode, API.StatusAction statusAction, String userId, Error error) {
|
||||
|
||||
if( peertube.isCommentsEnabled() && statusAction == API.StatusAction.PEERTUBECOMMENT)
|
||||
new RetrievePeertubeSingleCommentsAsyncTask(PeertubeActivity.this, peertubeInstance, videoId, PeertubeActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void initFullscreenDialog() {
|
||||
|
||||
fullScreenDialog = new Dialog(this, android.R.style.Theme_Black_NoTitleBar_Fullscreen) {
|
||||
public void onBackPressed() {
|
||||
if (fullScreenMode)
|
||||
closeFullscreenDialog();
|
||||
super.onBackPressed();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void openFullscreenDialog() {
|
||||
|
||||
((ViewGroup) playerView.getParent()).removeView(playerView);
|
||||
fullScreenDialog.addContentView(playerView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
fullScreenIcon.setImageDrawable(ContextCompat.getDrawable(PeertubeActivity.this, R.drawable.ic_fullscreen_exit));
|
||||
fullScreenMode = true;
|
||||
fullScreenDialog.show();
|
||||
}
|
||||
|
||||
|
||||
private void closeFullscreenDialog() {
|
||||
|
||||
((ViewGroup) playerView.getParent()).removeView(playerView);
|
||||
((FrameLayout) findViewById(R.id.main_media_frame)).addView(playerView);
|
||||
fullScreenMode = false;
|
||||
fullScreenDialog.dismiss();
|
||||
fullScreenIcon.setImageDrawable(ContextCompat.getDrawable(PeertubeActivity.this, R.drawable.ic_fullscreen));
|
||||
}
|
||||
|
||||
private void initFullscreenButton() {
|
||||
|
||||
PlaybackControlView controlView = playerView.findViewById(R.id.exo_controller);
|
||||
fullScreenIcon = controlView.findViewById(R.id.exo_fullscreen_icon);
|
||||
View fullScreenButton = controlView.findViewById(R.id.exo_fullscreen_button);
|
||||
fullScreenButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (!fullScreenMode)
|
||||
openFullscreenDialog();
|
||||
else
|
||||
closeFullscreenDialog();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initResolution() {
|
||||
PlaybackControlView controlView = playerView.findViewById(R.id.exo_controller);
|
||||
resolution = controlView.findViewById(R.id.resolution);
|
||||
resolution.setText(String.format("%sp",peertube.getResolution().get(0)));
|
||||
resolution.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
displayResolution();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void changeColor(){
|
||||
if( peertube.getMyRating() != null && peertube.getMyRating().equals("like")){
|
||||
changeDrawableColor(getApplicationContext(), R.drawable.ic_thumb_up_peertube,R.color.positive_thumbs);
|
||||
changeDrawableColor(getApplicationContext(), R.drawable.ic_thumb_down_peertube,R.color.neutral_thumbs);
|
||||
}else if( peertube.getMyRating() != null && peertube.getMyRating().equals("dislike")){
|
||||
changeDrawableColor(getApplicationContext(), R.drawable.ic_thumb_up_peertube,R.color.neutral_thumbs);
|
||||
changeDrawableColor(getApplicationContext(), R.drawable.ic_thumb_down_peertube,R.color.negative_thumbs);
|
||||
}else {
|
||||
changeDrawableColor(getApplicationContext(), R.drawable.ic_thumb_up_peertube,R.color.neutral_thumbs);
|
||||
changeDrawableColor(getApplicationContext(), R.drawable.ic_thumb_down_peertube,R.color.neutral_thumbs);
|
||||
}
|
||||
Drawable thumbUp = ContextCompat.getDrawable(getApplicationContext(), R.drawable.ic_thumb_up_peertube);
|
||||
Drawable thumbDown = ContextCompat.getDrawable(getApplicationContext(), R.drawable.ic_thumb_down_peertube);
|
||||
peertube_like_count.setCompoundDrawablesWithIntrinsicBounds( null, thumbUp, null, null);
|
||||
peertube_dislike_count.setCompoundDrawablesWithIntrinsicBounds( null, thumbDown, null, null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,624 @@
|
|||
package fr.gouv.etalab.mastodon.activities;
|
||||
/* Copyright 2019 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Mastalab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Mastalab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.jaredrummler.materialspinner.MaterialSpinner;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import es.dmoral.toasty.Toasty;
|
||||
import fr.gouv.etalab.mastodon.R;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.PostActionAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.PostPeertubeAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrievePeertubeChannelsAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrievePeertubeSingleAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.client.API;
|
||||
import fr.gouv.etalab.mastodon.client.APIResponse;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Error;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Peertube;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnPostActionInterface;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrievePeertubeInterface;
|
||||
import mabbas007.tagsedittext.TagsEditText;
|
||||
|
||||
import static android.os.AsyncTask.THREAD_POOL_EXECUTOR;
|
||||
import static fr.gouv.etalab.mastodon.asynctasks.RetrievePeertubeInformationAsyncTask.peertubeInformation;
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.INTENT_ACTION;
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.RELOAD_MYVIDEOS;
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.THEME_LIGHT;
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.changeMaterialSpinnerColor;
|
||||
|
||||
public class PeertubeEditUploadActivity extends BaseActivity implements OnRetrievePeertubeInterface, OnPostActionInterface {
|
||||
|
||||
|
||||
private Button set_upload_submit, set_upload_delete;
|
||||
private MaterialSpinner set_upload_privacy, set_upload_categories, set_upload_licenses, set_upload_languages, set_upload_channel;
|
||||
private EditText p_video_title, p_video_description;
|
||||
private TagsEditText p_video_tags;
|
||||
private CheckBox set_upload_nsfw, set_upload_enable_comments;
|
||||
private LinkedHashMap<String, String> channels;
|
||||
private String videoId;
|
||||
private Account channel;
|
||||
HashMap<Integer, String> categoryToSend;
|
||||
HashMap<Integer, String> licenseToSend;
|
||||
HashMap<Integer, String> privacyToSend;
|
||||
HashMap<String, String> languageToSend;
|
||||
HashMap<String, String> channelToSend;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
|
||||
switch (theme){
|
||||
case Helper.THEME_LIGHT:
|
||||
setTheme(R.style.AppTheme);
|
||||
break;
|
||||
case Helper.THEME_DARK:
|
||||
setTheme(R.style.AppThemeDark);
|
||||
break;
|
||||
case Helper.THEME_BLACK:
|
||||
setTheme(R.style.AppThemeBlack);
|
||||
break;
|
||||
default:
|
||||
setTheme(R.style.AppThemeDark);
|
||||
}
|
||||
Bundle b = getIntent().getExtras();
|
||||
|
||||
if(b != null) {
|
||||
videoId = b.getString("video_id", null);
|
||||
}
|
||||
if( videoId == null){
|
||||
videoId = sharedpreferences.getString(Helper.VIDEO_ID, null);
|
||||
}
|
||||
if( getSupportActionBar() != null)
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if( actionBar != null ) {
|
||||
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
assert inflater != null;
|
||||
@SuppressLint("InflateParams") View view = inflater.inflate(R.layout.simple_bar, null);
|
||||
actionBar.setCustomView(view, new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
|
||||
ImageView toolbar_close = actionBar.getCustomView().findViewById(R.id.toolbar_close);
|
||||
TextView toolbar_title = actionBar.getCustomView().findViewById(R.id.toolbar_title);
|
||||
toolbar_close.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
toolbar_title.setText(R.string.update_video);
|
||||
if (theme == THEME_LIGHT){
|
||||
Toolbar toolbar = actionBar.getCustomView().findViewById(R.id.toolbar);
|
||||
Helper.colorizeToolbar(toolbar, R.color.black, PeertubeEditUploadActivity.this);
|
||||
}
|
||||
}
|
||||
setContentView(R.layout.activity_peertube_edit);
|
||||
|
||||
|
||||
set_upload_submit = findViewById(R.id.set_upload_submit);
|
||||
set_upload_delete = findViewById(R.id.set_upload_delete);
|
||||
set_upload_privacy = findViewById(R.id.set_upload_privacy);
|
||||
set_upload_channel = findViewById(R.id.set_upload_channel);
|
||||
set_upload_categories = findViewById(R.id.set_upload_categories);
|
||||
set_upload_licenses = findViewById(R.id.set_upload_licenses);
|
||||
set_upload_languages = findViewById(R.id.set_upload_languages);
|
||||
p_video_title = findViewById(R.id.p_video_title);
|
||||
p_video_description = findViewById(R.id.p_video_description);
|
||||
p_video_tags = findViewById(R.id.p_video_tags);
|
||||
set_upload_nsfw = findViewById(R.id.set_upload_nsfw);
|
||||
set_upload_enable_comments = findViewById(R.id.set_upload_enable_comments);
|
||||
|
||||
|
||||
|
||||
//Change spinner colors
|
||||
changeMaterialSpinnerColor(PeertubeEditUploadActivity.this, set_upload_channel);
|
||||
changeMaterialSpinnerColor(PeertubeEditUploadActivity.this, set_upload_categories);
|
||||
changeMaterialSpinnerColor(PeertubeEditUploadActivity.this, set_upload_licenses);
|
||||
changeMaterialSpinnerColor(PeertubeEditUploadActivity.this, set_upload_languages);
|
||||
changeMaterialSpinnerColor(PeertubeEditUploadActivity.this, set_upload_privacy);
|
||||
|
||||
|
||||
set_upload_delete.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
AlertDialog.Builder builderInner;
|
||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
|
||||
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
|
||||
int style;
|
||||
if (theme == Helper.THEME_DARK) {
|
||||
style = R.style.DialogDark;
|
||||
} else if (theme == Helper.THEME_BLACK){
|
||||
style = R.style.DialogBlack;
|
||||
}else {
|
||||
style = R.style.Dialog;
|
||||
}
|
||||
builderInner = new AlertDialog.Builder(PeertubeEditUploadActivity.this, style);
|
||||
builderInner.setMessage(getString(R.string.delete_video_confirmation));
|
||||
builderInner.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog,int which) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
builderInner.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog,int which) {
|
||||
new PostActionAsyncTask(getApplicationContext(), API.StatusAction.PEERTUBEDELETEVIDEO, videoId, PeertubeEditUploadActivity.this).executeOnExecutor(THREAD_POOL_EXECUTOR);
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
builderInner.show();
|
||||
}
|
||||
});
|
||||
//Get params from the API
|
||||
LinkedHashMap<Integer, String> categories = new LinkedHashMap<>(peertubeInformation.getCategories());
|
||||
LinkedHashMap<Integer, String> licences = new LinkedHashMap<>(peertubeInformation.getLicences());
|
||||
LinkedHashMap<Integer, String> privacies = new LinkedHashMap<>(peertubeInformation.getPrivacies());
|
||||
LinkedHashMap<String, String> languages = new LinkedHashMap<>(peertubeInformation.getLanguages());
|
||||
LinkedHashMap<String, String> translations = null;
|
||||
if( peertubeInformation.getTranslations() != null)
|
||||
translations = new LinkedHashMap<>(peertubeInformation.getTranslations());
|
||||
//Populate catgories
|
||||
String[] categoriesA = new String[categories.size()];
|
||||
Iterator it = categories.entrySet().iterator();
|
||||
int i = 0;
|
||||
while (it.hasNext()) {
|
||||
Map.Entry pair = (Map.Entry)it.next();
|
||||
if( translations == null ||translations.size() == 0 || !translations.containsKey((String)pair.getValue()))
|
||||
categoriesA[i] = (String)pair.getValue();
|
||||
else
|
||||
categoriesA[i] = translations.get((String)pair.getValue());
|
||||
it.remove();
|
||||
i++;
|
||||
}
|
||||
ArrayAdapter<String> adapterCatgories = new ArrayAdapter<>(PeertubeEditUploadActivity.this,
|
||||
android.R.layout.simple_spinner_dropdown_item, categoriesA);
|
||||
set_upload_categories.setAdapter(adapterCatgories);
|
||||
|
||||
|
||||
|
||||
//Populate licenses
|
||||
String[] licensesA = new String[licences.size()];
|
||||
it = licences.entrySet().iterator();
|
||||
i = 0;
|
||||
while (it.hasNext()) {
|
||||
Map.Entry pair = (Map.Entry)it.next();
|
||||
if( translations == null || translations.size() == 0 || !translations.containsKey((String)pair.getValue()))
|
||||
licensesA[i] = (String)pair.getValue();
|
||||
else
|
||||
licensesA[i] = translations.get((String)pair.getValue());
|
||||
it.remove();
|
||||
i++;
|
||||
}
|
||||
ArrayAdapter<String> adapterLicenses = new ArrayAdapter<>(PeertubeEditUploadActivity.this,
|
||||
android.R.layout.simple_spinner_dropdown_item, licensesA);
|
||||
set_upload_licenses.setAdapter(adapterLicenses);
|
||||
|
||||
|
||||
//Populate languages
|
||||
String[] languagesA = new String[languages.size()];
|
||||
it = languages.entrySet().iterator();
|
||||
i = 0;
|
||||
while (it.hasNext()) {
|
||||
Map.Entry pair = (Map.Entry)it.next();
|
||||
if( translations == null || translations.size() == 0 || !translations.containsKey((String)pair.getValue()))
|
||||
languagesA[i] = (String)pair.getValue();
|
||||
else
|
||||
languagesA[i] = translations.get((String)pair.getValue());
|
||||
it.remove();
|
||||
i++;
|
||||
}
|
||||
ArrayAdapter<String> adapterLanguages = new ArrayAdapter<>(PeertubeEditUploadActivity.this,
|
||||
android.R.layout.simple_spinner_dropdown_item, languagesA);
|
||||
set_upload_languages.setAdapter(adapterLanguages);
|
||||
|
||||
|
||||
//Populate languages
|
||||
String[] privaciesA = new String[privacies.size()];
|
||||
it = privacies.entrySet().iterator();
|
||||
i = 0;
|
||||
while (it.hasNext()) {
|
||||
Map.Entry pair = (Map.Entry)it.next();
|
||||
if( translations == null || translations.size() == 0 || !translations.containsKey((String)pair.getValue()))
|
||||
privaciesA[i] = (String)pair.getValue();
|
||||
else
|
||||
privaciesA[i] = translations.get((String)pair.getValue());
|
||||
it.remove();
|
||||
i++;
|
||||
}
|
||||
ArrayAdapter<String> adapterPrivacies = new ArrayAdapter<>(PeertubeEditUploadActivity.this,
|
||||
android.R.layout.simple_spinner_dropdown_item, privaciesA);
|
||||
set_upload_privacy.setAdapter(adapterPrivacies);
|
||||
|
||||
|
||||
String peertubeInstance = Helper.getLiveInstance(getApplicationContext());
|
||||
new RetrievePeertubeSingleAsyncTask(PeertubeEditUploadActivity.this, peertubeInstance, videoId, PeertubeEditUploadActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
|
||||
channels = new LinkedHashMap<>();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onRetrievePeertube(APIResponse apiResponse) {
|
||||
if( apiResponse.getError() != null || apiResponse.getPeertubes() == null || apiResponse.getPeertubes().size() == 0){
|
||||
if ( apiResponse.getError() != null && apiResponse.getError().getError() != null)
|
||||
Toasty.error(PeertubeEditUploadActivity.this, apiResponse.getError().getError(), Toast.LENGTH_LONG).show();
|
||||
else
|
||||
Toasty.error(PeertubeEditUploadActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show();
|
||||
set_upload_submit.setEnabled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
//Peertube video
|
||||
Peertube peertube = apiResponse.getPeertubes().get(0);
|
||||
|
||||
if( peertube.isUpdate()){
|
||||
Toasty.success(PeertubeEditUploadActivity.this, getString(R.string.toast_peertube_video_updated), Toast.LENGTH_LONG).show();
|
||||
peertube.setUpdate(false);
|
||||
set_upload_submit.setEnabled(true);
|
||||
}else {
|
||||
new RetrievePeertubeChannelsAsyncTask(PeertubeEditUploadActivity.this, PeertubeEditUploadActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
languageToSend = peertube.getLanguage();
|
||||
licenseToSend = peertube.getLicense();
|
||||
privacyToSend = peertube.getPrivacy();
|
||||
categoryToSend = peertube.getCategory();
|
||||
|
||||
|
||||
if( languageToSend == null){
|
||||
LinkedHashMap<String, String> languages = new LinkedHashMap<>(peertubeInformation.getLanguages());
|
||||
Map.Entry<String,String> entryString = languages.entrySet().iterator().next();
|
||||
languageToSend = new HashMap<>();
|
||||
languageToSend.put(entryString.getKey(), entryString.getValue());
|
||||
}
|
||||
|
||||
if( licenseToSend == null){
|
||||
LinkedHashMap<Integer, String> licences = new LinkedHashMap<>(peertubeInformation.getLicences());
|
||||
Map.Entry<Integer,String> entryInt = licences.entrySet().iterator().next();
|
||||
licenseToSend = new HashMap<>();
|
||||
licenseToSend.put(entryInt.getKey(), entryInt.getValue());
|
||||
}
|
||||
|
||||
if( categoryToSend == null){
|
||||
LinkedHashMap<Integer, String> categories = new LinkedHashMap<>(peertubeInformation.getCategories());
|
||||
Map.Entry<Integer,String> entryInt = categories.entrySet().iterator().next();
|
||||
categoryToSend = new HashMap<>();
|
||||
categoryToSend.put(entryInt.getKey(), entryInt.getValue());
|
||||
}
|
||||
if( privacyToSend == null){
|
||||
LinkedHashMap<Integer, String> privacies = new LinkedHashMap<>(peertubeInformation.getPrivacies());
|
||||
Map.Entry<Integer,String> entryInt = privacies.entrySet().iterator().next();
|
||||
privacyToSend = new HashMap<>();
|
||||
privacyToSend.put(entryInt.getKey(), entryInt.getValue());
|
||||
}
|
||||
|
||||
String language = null;
|
||||
|
||||
if( languageToSend != null) {
|
||||
Map.Entry<String, String> entryString = languageToSend.entrySet().iterator().next();
|
||||
language = entryString.getValue();
|
||||
}
|
||||
|
||||
String license = null;
|
||||
if( licenseToSend != null) {
|
||||
Map.Entry<Integer, String> entryInt = licenseToSend.entrySet().iterator().next();
|
||||
license = entryInt.getValue();
|
||||
}
|
||||
|
||||
String privacy = null;
|
||||
if( privacyToSend != null) {
|
||||
Map.Entry<Integer, String> entryInt = privacyToSend.entrySet().iterator().next();
|
||||
privacy = entryInt.getValue();
|
||||
}
|
||||
|
||||
String category = null;
|
||||
if( categoryToSend != null) {
|
||||
Map.Entry<Integer, String> entryInt = categoryToSend.entrySet().iterator().next();
|
||||
category = entryInt.getValue();
|
||||
}
|
||||
|
||||
channel = peertube.getChannel();
|
||||
String title = peertube.getName();
|
||||
boolean commentEnabled = peertube.isCommentsEnabled();
|
||||
boolean isNSFW = peertube.isSensitive();
|
||||
|
||||
set_upload_enable_comments.setChecked(commentEnabled);
|
||||
set_upload_nsfw.setChecked(isNSFW);
|
||||
|
||||
p_video_title.setText(title);
|
||||
p_video_description.setText(peertube.getDescription());
|
||||
|
||||
|
||||
LinkedHashMap<Integer, String> categories = new LinkedHashMap<>(peertubeInformation.getCategories());
|
||||
LinkedHashMap<Integer, String> licences = new LinkedHashMap<>(peertubeInformation.getLicences());
|
||||
LinkedHashMap<Integer, String> privacies = new LinkedHashMap<>(peertubeInformation.getPrivacies());
|
||||
LinkedHashMap<String, String> languages = new LinkedHashMap<>(peertubeInformation.getLanguages());
|
||||
LinkedHashMap<String, String> translations = null;
|
||||
if( peertubeInformation.getTranslations() != null)
|
||||
translations = new LinkedHashMap<>(peertubeInformation.getTranslations());
|
||||
|
||||
|
||||
int languagePosition = 0;
|
||||
if( languages.containsValue(language)){
|
||||
Iterator it = languages.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Map.Entry pair = (Map.Entry)it.next();
|
||||
if(pair.getValue().equals(language))
|
||||
break;
|
||||
it.remove();
|
||||
languagePosition++;
|
||||
}
|
||||
}
|
||||
int privacyPosition = 0;
|
||||
if( privacy != null && privacies.containsValue(privacy)){
|
||||
Iterator it = privacies.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Map.Entry pair = (Map.Entry)it.next();
|
||||
if(pair.getValue().equals(privacy))
|
||||
break;
|
||||
it.remove();
|
||||
privacyPosition++;
|
||||
}
|
||||
}
|
||||
int licensePosition = 0;
|
||||
if( license != null && licences.containsValue(license)){
|
||||
Iterator it = licences.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Map.Entry pair = (Map.Entry)it.next();
|
||||
if(pair.getValue().equals(license))
|
||||
break;
|
||||
it.remove();
|
||||
licensePosition++;
|
||||
}
|
||||
}
|
||||
int categoryPosition = 0;
|
||||
if(category != null && categories.containsValue(category)){
|
||||
Iterator it = categories.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Map.Entry pair = (Map.Entry)it.next();
|
||||
if(pair.getValue().equals(category))
|
||||
break;
|
||||
it.remove();
|
||||
categoryPosition++;
|
||||
}
|
||||
}
|
||||
|
||||
//Manage privacies
|
||||
set_upload_privacy.setOnItemSelectedListener(new MaterialSpinner.OnItemSelectedListener<String>() {
|
||||
@Override
|
||||
public void onItemSelected(MaterialSpinner view, int position, long id, String item) {
|
||||
LinkedHashMap<Integer, String> privaciesCheck = new LinkedHashMap<>(peertubeInformation.getPrivacies());
|
||||
Iterator it = privaciesCheck.entrySet().iterator();
|
||||
int i = 0;
|
||||
while (it.hasNext()) {
|
||||
Map.Entry pair = (Map.Entry)it.next();
|
||||
if( i == position){
|
||||
privacyToSend = new HashMap<>();
|
||||
privacyToSend.put((Integer)pair.getKey(), (String)pair.getValue());
|
||||
break;
|
||||
}
|
||||
it.remove();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
});
|
||||
//Manage license
|
||||
set_upload_licenses.setOnItemSelectedListener(new MaterialSpinner.OnItemSelectedListener<String>() {
|
||||
@Override
|
||||
public void onItemSelected(MaterialSpinner view, int position, long id, String item) {
|
||||
LinkedHashMap<Integer, String> licensesCheck = new LinkedHashMap<>(peertubeInformation.getLicences());
|
||||
Iterator it = licensesCheck.entrySet().iterator();
|
||||
int i = 0;
|
||||
while (it.hasNext()) {
|
||||
Map.Entry pair = (Map.Entry)it.next();
|
||||
if( i == position){
|
||||
licenseToSend = new HashMap<>();
|
||||
licenseToSend.put((Integer)pair.getKey(), (String)pair.getValue());
|
||||
break;
|
||||
}
|
||||
it.remove();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
});
|
||||
//Manage categories
|
||||
set_upload_categories.setOnItemSelectedListener(new MaterialSpinner.OnItemSelectedListener<String>() {
|
||||
@Override
|
||||
public void onItemSelected(MaterialSpinner view, int position, long id, String item) {
|
||||
LinkedHashMap<Integer, String> categoriesCheck = new LinkedHashMap<>(peertubeInformation.getCategories());
|
||||
Iterator it = categoriesCheck.entrySet().iterator();
|
||||
int i = 0;
|
||||
while (it.hasNext()) {
|
||||
Map.Entry pair = (Map.Entry)it.next();
|
||||
if( i == position){
|
||||
categoryToSend = new HashMap<>();
|
||||
categoryToSend.put((Integer)pair.getKey(), (String)pair.getValue());
|
||||
break;
|
||||
}
|
||||
it.remove();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
});
|
||||
//Manage languages
|
||||
set_upload_languages.setOnItemSelectedListener(new MaterialSpinner.OnItemSelectedListener<String>() {
|
||||
@Override
|
||||
public void onItemSelected(MaterialSpinner view, int position, long id, String item) {
|
||||
LinkedHashMap<String, String> languagesCheck = new LinkedHashMap<>(peertubeInformation.getLanguages());
|
||||
Iterator it = languagesCheck.entrySet().iterator();
|
||||
int i = 0;
|
||||
while (it.hasNext()) {
|
||||
Map.Entry pair = (Map.Entry)it.next();
|
||||
if( i == position){
|
||||
languageToSend = new HashMap<>();
|
||||
languageToSend.put((String)pair.getKey(), (String)pair.getValue());
|
||||
break;
|
||||
}
|
||||
it.remove();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//Manage languages
|
||||
set_upload_channel.setOnItemSelectedListener(new MaterialSpinner.OnItemSelectedListener<String>() {
|
||||
@Override
|
||||
public void onItemSelected(MaterialSpinner view, int position, long id, String item) {
|
||||
LinkedHashMap<String, String> channelsCheck = new LinkedHashMap<>(channels);
|
||||
Iterator it = channelsCheck.entrySet().iterator();
|
||||
int i = 0;
|
||||
while (it.hasNext()) {
|
||||
Map.Entry pair = (Map.Entry)it.next();
|
||||
if( i == position){
|
||||
channelToSend = new HashMap<>();
|
||||
channelToSend.put((String)pair.getKey(), (String)pair.getValue());
|
||||
|
||||
break;
|
||||
}
|
||||
it.remove();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
set_upload_submit.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
String title = p_video_title.getText().toString().trim();
|
||||
String description = p_video_description.getText().toString().trim();
|
||||
boolean isNSFW = set_upload_nsfw.isChecked();
|
||||
boolean commentEnabled = set_upload_enable_comments.isChecked();
|
||||
peertube.setName(title);
|
||||
peertube.setDescription(description);
|
||||
peertube.setSensitive(isNSFW);
|
||||
peertube.setCommentsEnabled(commentEnabled);
|
||||
peertube.setCategory(categoryToSend);
|
||||
peertube.setLicense(licenseToSend);
|
||||
peertube.setLanguage(languageToSend);
|
||||
peertube.setChannelForUpdate(channelToSend);
|
||||
peertube.setPrivacy(privacyToSend);
|
||||
List<String> tags = p_video_tags.getTags();
|
||||
peertube.setTags(tags);
|
||||
set_upload_submit.setEnabled(false);
|
||||
new PostPeertubeAsyncTask(PeertubeEditUploadActivity.this, peertube, PeertubeEditUploadActivity.this).executeOnExecutor(THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
});
|
||||
|
||||
set_upload_privacy.setSelectedIndex(privacyPosition);
|
||||
set_upload_languages.setSelectedIndex(languagePosition);
|
||||
set_upload_licenses.setSelectedIndex(licensePosition);
|
||||
set_upload_categories.setSelectedIndex(categoryPosition);
|
||||
|
||||
List<String> tags = peertube.getTags();
|
||||
if( tags != null && tags.size() > 0) {
|
||||
String[] tagsA = tags.toArray(new String[tags.size()]);
|
||||
p_video_tags.setTags(tagsA);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRetrievePeertubeComments(APIResponse apiResponse) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRetrievePeertubeChannels(APIResponse apiResponse) {
|
||||
if( apiResponse.getError() != null || apiResponse.getAccounts() == null || apiResponse.getAccounts().size() == 0){
|
||||
if ( apiResponse.getError().getError() != null)
|
||||
Toasty.error(PeertubeEditUploadActivity.this, apiResponse.getError().getError(), Toast.LENGTH_LONG).show();
|
||||
else
|
||||
Toasty.error(PeertubeEditUploadActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
//Populate channels
|
||||
List<Account> accounts = apiResponse.getAccounts();
|
||||
String[] channelName = new String[accounts.size()];
|
||||
int i = 0;
|
||||
for(Account account: accounts){
|
||||
channels.put(account.getUsername(),account.getId());
|
||||
channelName[i] = account.getUsername();
|
||||
i++;
|
||||
}
|
||||
ArrayAdapter<String> adapterChannel = new ArrayAdapter<>(PeertubeEditUploadActivity.this,
|
||||
android.R.layout.simple_spinner_dropdown_item, channelName);
|
||||
set_upload_channel.setAdapter(adapterChannel);
|
||||
|
||||
int channelPosition = 0;
|
||||
if( channels.containsKey(channel.getUsername())){
|
||||
LinkedHashMap<String, String> channelsIterator = new LinkedHashMap<>(channels);
|
||||
Iterator it = channelsIterator.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Map.Entry pair = (Map.Entry)it.next();
|
||||
if(pair.getKey().equals(channel.getUsername())) {
|
||||
channelToSend = new HashMap<>();
|
||||
channelToSend.put((String)pair.getKey(), (String)pair.getValue());
|
||||
break;
|
||||
}
|
||||
it.remove();
|
||||
channelPosition++;
|
||||
}
|
||||
}
|
||||
set_upload_channel.setSelectedIndex(channelPosition);
|
||||
|
||||
set_upload_submit.setEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPostAction(int statusCode, API.StatusAction statusAction, String userId, Error error) {
|
||||
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
|
||||
intent.putExtra(INTENT_ACTION, RELOAD_MYVIDEOS);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,403 @@
|
|||
package fr.gouv.etalab.mastodon.activities;
|
||||
/* Copyright 2019 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Mastalab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Mastalab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.OpenableColumns;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.jaredrummler.materialspinner.MaterialSpinner;
|
||||
|
||||
import net.gotev.uploadservice.MultipartUploadRequest;
|
||||
import net.gotev.uploadservice.ServerResponse;
|
||||
import net.gotev.uploadservice.UploadInfo;
|
||||
import net.gotev.uploadservice.UploadNotificationAction;
|
||||
import net.gotev.uploadservice.UploadNotificationConfig;
|
||||
import net.gotev.uploadservice.UploadStatusDelegate;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import es.dmoral.toasty.Toasty;
|
||||
import fr.gouv.etalab.mastodon.R;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrievePeertubeChannelsAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.client.APIResponse;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrievePeertubeInterface;
|
||||
|
||||
import static fr.gouv.etalab.mastodon.asynctasks.RetrievePeertubeInformationAsyncTask.peertubeInformation;
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.THEME_LIGHT;
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.changeMaterialSpinnerColor;
|
||||
|
||||
public class PeertubeUploadActivity extends BaseActivity implements OnRetrievePeertubeInterface {
|
||||
|
||||
|
||||
private final int PICK_IVDEO = 52378;
|
||||
private Button set_upload_file, set_upload_submit;
|
||||
private MaterialSpinner set_upload_privacy, set_upload_channel;
|
||||
private TextView set_upload_file_name;
|
||||
private HashMap<String, String> channels;
|
||||
private final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 724;
|
||||
private Uri uri;
|
||||
private String filename;
|
||||
private HashMap<Integer, String> privacyToSend;
|
||||
private HashMap<String, String> channelToSend;
|
||||
private String videoID;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
|
||||
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
|
||||
switch (theme){
|
||||
case Helper.THEME_LIGHT:
|
||||
setTheme(R.style.AppTheme);
|
||||
break;
|
||||
case Helper.THEME_DARK:
|
||||
setTheme(R.style.AppThemeDark);
|
||||
break;
|
||||
case Helper.THEME_BLACK:
|
||||
setTheme(R.style.AppThemeBlack);
|
||||
break;
|
||||
default:
|
||||
setTheme(R.style.AppThemeDark);
|
||||
}
|
||||
if( getSupportActionBar() != null)
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if( actionBar != null ) {
|
||||
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
assert inflater != null;
|
||||
@SuppressLint("InflateParams") View view = inflater.inflate(R.layout.simple_bar, null);
|
||||
actionBar.setCustomView(view, new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
|
||||
ImageView toolbar_close = actionBar.getCustomView().findViewById(R.id.toolbar_close);
|
||||
TextView toolbar_title = actionBar.getCustomView().findViewById(R.id.toolbar_title);
|
||||
toolbar_close.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
toolbar_title.setText(R.string.upload_video);
|
||||
if (theme == THEME_LIGHT){
|
||||
Toolbar toolbar = actionBar.getCustomView().findViewById(R.id.toolbar);
|
||||
Helper.colorizeToolbar(toolbar, R.color.black, PeertubeUploadActivity.this);
|
||||
}
|
||||
}
|
||||
setContentView(R.layout.activity_peertube_upload);
|
||||
|
||||
set_upload_file = findViewById(R.id.set_upload_file);
|
||||
set_upload_file_name = findViewById(R.id.set_upload_file_name);
|
||||
set_upload_channel = findViewById(R.id.set_upload_channel);
|
||||
set_upload_privacy = findViewById(R.id.set_upload_privacy);
|
||||
set_upload_submit = findViewById(R.id.set_upload_submit);
|
||||
|
||||
changeMaterialSpinnerColor(PeertubeUploadActivity.this, set_upload_privacy);
|
||||
changeMaterialSpinnerColor(PeertubeUploadActivity.this, set_upload_channel);
|
||||
|
||||
new RetrievePeertubeChannelsAsyncTask(PeertubeUploadActivity.this, PeertubeUploadActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
channels = new HashMap<>();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (requestCode == PICK_IVDEO && resultCode == Activity.RESULT_OK) {
|
||||
if (data == null || data.getData() == null) {
|
||||
Toasty.error(getApplicationContext(),getString(R.string.toot_select_image_error),Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
set_upload_submit.setEnabled(true);
|
||||
|
||||
uri = data.getData();
|
||||
String uriString = uri.toString();
|
||||
File myFile = new File(uriString);
|
||||
filename = null;
|
||||
if (uriString.startsWith("content://")) {
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
cursor = getContentResolver().query(uri, null, null, null, null);
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
|
||||
}
|
||||
} finally {
|
||||
assert cursor != null;
|
||||
cursor.close();
|
||||
}
|
||||
} else if (uriString.startsWith("file://")) {
|
||||
filename = myFile.getName();
|
||||
}
|
||||
if( filename != null) {
|
||||
set_upload_file_name.setVisibility(View.VISIBLE);
|
||||
set_upload_file_name.setText(filename);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRetrievePeertube(APIResponse apiResponse) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRetrievePeertubeComments(APIResponse apiResponse) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRetrievePeertubeChannels(APIResponse apiResponse) {
|
||||
if( apiResponse.getError() != null || apiResponse.getAccounts() == null || apiResponse.getAccounts().size() == 0){
|
||||
if ( apiResponse.getError() != null && apiResponse.getError().getError() != null)
|
||||
Toasty.error(PeertubeUploadActivity.this, apiResponse.getError().getError(), Toast.LENGTH_LONG).show();
|
||||
else
|
||||
Toasty.error(PeertubeUploadActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
//Populate channels
|
||||
List<Account> accounts = apiResponse.getAccounts();
|
||||
String[] channelName = new String[accounts.size()];
|
||||
String[] channelId= new String[accounts.size()];
|
||||
int i = 0;
|
||||
for(Account account: accounts){
|
||||
channels.put(account.getUsername(),account.getId());
|
||||
channelName[i] = account.getUsername();
|
||||
channelId[i] = account.getId();
|
||||
i++;
|
||||
}
|
||||
|
||||
channelToSend = new HashMap<>();
|
||||
channelToSend.put(channelName[0], channelId[0]);
|
||||
ArrayAdapter<String> adapterChannel = new ArrayAdapter<>(PeertubeUploadActivity.this,
|
||||
android.R.layout.simple_spinner_dropdown_item, channelName);
|
||||
set_upload_channel.setAdapter(adapterChannel);
|
||||
|
||||
LinkedHashMap<String, String> translations = null;
|
||||
if( peertubeInformation.getTranslations() != null)
|
||||
translations = new LinkedHashMap<>(peertubeInformation.getTranslations());
|
||||
|
||||
LinkedHashMap<Integer, String> privaciesInit = new LinkedHashMap<>(peertubeInformation.getPrivacies());
|
||||
Map.Entry<Integer,String> entryInt = privaciesInit.entrySet().iterator().next();
|
||||
privacyToSend = new HashMap<>();
|
||||
privacyToSend.put(entryInt.getKey(), entryInt.getValue());
|
||||
LinkedHashMap<Integer, String> privacies = new LinkedHashMap<>(peertubeInformation.getPrivacies());
|
||||
//Populate privacies
|
||||
String[] privaciesA = new String[privacies.size()];
|
||||
Iterator it = privacies.entrySet().iterator();
|
||||
i = 0;
|
||||
while (it.hasNext()) {
|
||||
Map.Entry pair = (Map.Entry)it.next();
|
||||
if( translations == null || translations.size() == 0 || !translations.containsKey((String)pair.getValue()))
|
||||
privaciesA[i] = (String)pair.getValue();
|
||||
else
|
||||
privaciesA[i] = translations.get((String)pair.getValue());
|
||||
it.remove();
|
||||
i++;
|
||||
}
|
||||
|
||||
ArrayAdapter<String> adapterPrivacies = new ArrayAdapter<>(PeertubeUploadActivity.this,
|
||||
android.R.layout.simple_spinner_dropdown_item, privaciesA);
|
||||
set_upload_privacy.setAdapter(adapterPrivacies);
|
||||
|
||||
//Manage privacies
|
||||
set_upload_privacy.setOnItemSelectedListener(new MaterialSpinner.OnItemSelectedListener<String>() {
|
||||
@Override
|
||||
public void onItemSelected(MaterialSpinner view, int position, long id, String item) {
|
||||
LinkedHashMap<Integer, String> privaciesCheck = new LinkedHashMap<>(peertubeInformation.getPrivacies());
|
||||
Iterator it = privaciesCheck.entrySet().iterator();
|
||||
int i = 0;
|
||||
while (it.hasNext()) {
|
||||
Map.Entry pair = (Map.Entry)it.next();
|
||||
if( i == position){
|
||||
privacyToSend = new HashMap<>();
|
||||
privacyToSend.put((Integer)pair.getKey(), (String)pair.getValue());
|
||||
break;
|
||||
}
|
||||
it.remove();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
set_upload_file.setEnabled(true);
|
||||
|
||||
set_upload_file.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
if (ContextCompat.checkSelfPermission(PeertubeUploadActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) !=
|
||||
PackageManager.PERMISSION_GRANTED) {
|
||||
ActivityCompat.requestPermissions(PeertubeUploadActivity.this,
|
||||
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
|
||||
MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
|
||||
intent.setType("*/*");
|
||||
String[] mimetypes = {"video/*"};
|
||||
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimetypes);
|
||||
startActivityForResult(intent, PICK_IVDEO);
|
||||
}else {
|
||||
intent.setType("video/*");
|
||||
Intent pickIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
|
||||
Intent chooserIntent = Intent.createChooser(intent, getString(R.string.toot_select_image));
|
||||
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] {pickIntent});
|
||||
startActivityForResult(chooserIntent, PICK_IVDEO);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
//Manage languages
|
||||
set_upload_channel.setOnItemSelectedListener(new MaterialSpinner.OnItemSelectedListener<String>() {
|
||||
@Override
|
||||
public void onItemSelected(MaterialSpinner view, int position, long id, String item) {
|
||||
LinkedHashMap<String, String> channelsCheck = new LinkedHashMap<>(channels);
|
||||
Iterator it = channelsCheck.entrySet().iterator();
|
||||
int i = 0;
|
||||
while (it.hasNext()) {
|
||||
Map.Entry pair = (Map.Entry)it.next();
|
||||
if( i == position){
|
||||
channelToSend = new HashMap<>();
|
||||
channelToSend.put((String)pair.getKey(), (String)pair.getValue());
|
||||
|
||||
break;
|
||||
}
|
||||
it.remove();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
});
|
||||
set_upload_submit.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if( uri != null) {
|
||||
Map.Entry<String, String> channelM = channelToSend.entrySet().iterator().next();
|
||||
String idChannel = channelM.getValue();
|
||||
Map.Entry<Integer, String> privacyM = privacyToSend.entrySet().iterator().next();
|
||||
Integer idPrivacy = privacyM.getKey();
|
||||
|
||||
try {
|
||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
|
||||
String token = sharedpreferences.getString(Helper.PREF_KEY_OAUTH_TOKEN, null);
|
||||
UploadNotificationConfig uploadConfig = new UploadNotificationConfig();
|
||||
Intent in = new Intent(getApplicationContext(), PeertubeEditUploadActivity.class );
|
||||
PendingIntent clickIntent = PendingIntent.getActivity(getApplicationContext(), 1, in, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
uploadConfig
|
||||
.setClearOnActionForAllStatuses(true);
|
||||
|
||||
|
||||
uploadConfig.getProgress().message = getString(R.string.uploading);
|
||||
uploadConfig.getCompleted().message = getString(R.string.upload_video_success);
|
||||
uploadConfig.getError().message = getString(R.string.toast_error);
|
||||
uploadConfig.getCancelled().message = getString(R.string.toast_cancelled);
|
||||
uploadConfig.getCompleted().actions.add(new UploadNotificationAction(R.drawable.ic_check, getString(R.string.video_uploaded_action), clickIntent));
|
||||
|
||||
|
||||
String uploadId =
|
||||
new MultipartUploadRequest(PeertubeUploadActivity.this, "https://" + Helper.getLiveInstance(PeertubeUploadActivity.this) + "/api/v1/videos/upload")
|
||||
.addFileToUpload(uri.toString().replace("file://",""), "videofile")
|
||||
.addHeader("Authorization", "Bearer " + token)
|
||||
.setNotificationConfig(uploadConfig)
|
||||
.addParameter("name", filename)
|
||||
.addParameter("channelId", idChannel)
|
||||
.addParameter("privacy", String.valueOf(idPrivacy))
|
||||
.addParameter("nsfw", "false")
|
||||
.addParameter("commentsEnabled", "true")
|
||||
.addParameter("waitTranscoding", "true")
|
||||
.setMaxRetries(2)
|
||||
.setDelegate(new UploadStatusDelegate() {
|
||||
@Override
|
||||
public void onProgress(Context context, UploadInfo uploadInfo) {
|
||||
// your code here
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Context context, UploadInfo uploadInfo, ServerResponse serverResponse,
|
||||
Exception exception) {
|
||||
// your code here
|
||||
exception.printStackTrace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCompleted(Context context, UploadInfo uploadInfo, ServerResponse serverResponse) {
|
||||
try {
|
||||
JSONObject response = new JSONObject(serverResponse.getBodyAsString());
|
||||
videoID = response.getJSONObject("video").get("id").toString();
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.VIDEO_ID, videoID);
|
||||
editor.commit();
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancelled(Context context, UploadInfo uploadInfo) {
|
||||
// your code here
|
||||
}
|
||||
})
|
||||
.startUpload();
|
||||
finish();
|
||||
} catch (Exception exc) {
|
||||
exc.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -16,12 +16,15 @@ package fr.gouv.etalab.mastodon.activities;
|
|||
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
|
@ -41,6 +44,8 @@ import java.util.List;
|
|||
import es.dmoral.toasty.Toasty;
|
||||
import fr.gouv.etalab.mastodon.R;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrieveContextAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.UpdateAccountInfoAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.client.API;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Context;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Error;
|
||||
|
@ -72,6 +77,7 @@ public class ShowConversationActivity extends BaseActivity implements OnRetriev
|
|||
private List<Status> statuses;
|
||||
private StatusListAdapter statusListAdapter;
|
||||
private boolean expanded;
|
||||
private BroadcastReceiver receive_action;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -110,6 +116,26 @@ public class ShowConversationActivity extends BaseActivity implements OnRetriev
|
|||
if( detailsStatus == null || detailsStatus.getId() == null)
|
||||
finish();
|
||||
|
||||
|
||||
if( MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON) {
|
||||
|
||||
if( receive_action != null)
|
||||
LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(receive_action);
|
||||
receive_action = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(android.content.Context context, Intent intent) {
|
||||
Bundle b = intent.getExtras();
|
||||
assert b != null;
|
||||
Status status = b.getParcelable("status");
|
||||
API.StatusAction statusAction = (API.StatusAction) b.getSerializable("action");
|
||||
if( status != null) {
|
||||
statusListAdapter.notifyStatusWithActionChanged(statusAction, status);
|
||||
}
|
||||
}
|
||||
};
|
||||
LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(receive_action, new IntentFilter(Helper.RECEIVE_ACTION));
|
||||
}
|
||||
|
||||
if( getSupportActionBar() != null)
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
if( getSupportActionBar() != null) {
|
||||
|
@ -198,13 +224,11 @@ public class ShowConversationActivity extends BaseActivity implements OnRetriev
|
|||
|
||||
swipeRefreshLayout = findViewById(R.id.swipeContainer);
|
||||
boolean isOnWifi = Helper.isOnWIFI(getApplicationContext());
|
||||
int behaviorWithAttachments = sharedpreferences.getInt(Helper.SET_ATTACHMENT_ACTION, Helper.ATTACHMENT_ALWAYS);
|
||||
int positionSpinnerTrans = sharedpreferences.getInt(Helper.SET_TRANSLATOR, Helper.TRANS_YANDEX);
|
||||
if( initialStatus != null)
|
||||
statuses.add(initialStatus);
|
||||
else
|
||||
statuses.add(detailsStatus);
|
||||
statusListAdapter = new StatusListAdapter(ShowConversationActivity.this, 0, null, isOnWifi, behaviorWithAttachments, positionSpinnerTrans, statuses);
|
||||
statusListAdapter = new StatusListAdapter(ShowConversationActivity.this, 0, null, isOnWifi, statuses);
|
||||
|
||||
final LinearLayoutManager mLayoutManager;
|
||||
mLayoutManager = new LinearLayoutManager(this);
|
||||
|
@ -271,6 +295,12 @@ public class ShowConversationActivity extends BaseActivity implements OnRetriev
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if( receive_action != null)
|
||||
LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(receive_action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRetrieveContext(Context context, Error error) {
|
||||
|
|
|
@ -23,7 +23,6 @@ import android.os.Bundle;
|
|||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
|
|
|
@ -96,29 +96,32 @@ import java.util.Date;
|
|||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import es.dmoral.toasty.Toasty;
|
||||
import fr.gouv.etalab.mastodon.R;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.PostActionAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.PostStatusAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrieveAccountsForReplyAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrieveEmojiAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrieveSearchAccountsAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrieveSearchAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.UpdateDescriptionAttachmentAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.client.API;
|
||||
import fr.gouv.etalab.mastodon.client.APIResponse;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Attachment;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Emojis;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Error;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Mention;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Notification;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Results;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Status;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.StoredStatus;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Version;
|
||||
import fr.gouv.etalab.mastodon.client.Glide.GlideApp;
|
||||
import fr.gouv.etalab.mastodon.client.HttpsConnection;
|
||||
import fr.gouv.etalab.mastodon.drawers.AccountsReplyAdapter;
|
||||
import fr.gouv.etalab.mastodon.drawers.AccountsSearchAdapter;
|
||||
|
@ -129,6 +132,7 @@ import fr.gouv.etalab.mastodon.drawers.TagsSearchAdapter;
|
|||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.helper.MastalabAutoCompleteTextView;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnDownloadInterface;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnPostActionInterface;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnPostStatusActionInterface;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveAccountsReplyInterface;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveAttachmentInterface;
|
||||
|
@ -152,7 +156,7 @@ import static fr.gouv.etalab.mastodon.helper.Helper.convertDpToPixel;
|
|||
* Toot activity class
|
||||
*/
|
||||
|
||||
public class TootActivity extends BaseActivity implements OnRetrieveSearcAccountshInterface, OnRetrieveAttachmentInterface, OnPostStatusActionInterface, OnRetrieveSearchInterface, OnRetrieveAccountsReplyInterface, OnRetrieveEmojiInterface, OnDownloadInterface {
|
||||
public class TootActivity extends BaseActivity implements OnPostActionInterface, OnRetrieveSearcAccountshInterface, OnRetrieveAttachmentInterface, OnPostStatusActionInterface, OnRetrieveSearchInterface, OnRetrieveAccountsReplyInterface, OnRetrieveEmojiInterface, OnDownloadInterface {
|
||||
|
||||
|
||||
private String visibility;
|
||||
|
@ -198,7 +202,8 @@ public class TootActivity extends BaseActivity implements OnRetrieveSearcAccount
|
|||
private boolean restoredScheduled;
|
||||
static boolean active = false;
|
||||
private int style;
|
||||
|
||||
private StoredStatus scheduledstatus;
|
||||
private boolean isScheduled;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -275,7 +280,7 @@ public class TootActivity extends BaseActivity implements OnRetrieveSearcAccount
|
|||
toot_sensitive = findViewById(R.id.toot_sensitive);
|
||||
drawer_layout = findViewById(R.id.drawer_layout);
|
||||
ImageButton toot_emoji = findViewById(R.id.toot_emoji);
|
||||
|
||||
isScheduled = false;
|
||||
if( sharedpreferences.getBoolean(Helper.SET_DISPLAY_EMOJI, true)) {
|
||||
final EmojiPopup emojiPopup = EmojiPopup.Builder.fromRootView(drawer_layout).build(toot_content);
|
||||
|
||||
|
@ -315,6 +320,7 @@ public class TootActivity extends BaseActivity implements OnRetrieveSearcAccount
|
|||
restored = -1;
|
||||
if(b != null) {
|
||||
tootReply = b.getParcelable("tootReply");
|
||||
scheduledstatus = b.getParcelable("storedStatus");
|
||||
String accountReplyToken = b.getString("accountReplyToken", null);
|
||||
accountReply = null;
|
||||
if( accountReplyToken != null){
|
||||
|
@ -348,7 +354,8 @@ public class TootActivity extends BaseActivity implements OnRetrieveSearcAccount
|
|||
}
|
||||
restored = b.getLong("restored", -1);
|
||||
}
|
||||
|
||||
if( scheduledstatus != null)
|
||||
toot_it.setText(R.string.modify);
|
||||
if(restoredScheduled){
|
||||
toot_it.setVisibility(View.GONE);
|
||||
invalidateOptionsMenu();
|
||||
|
@ -499,35 +506,7 @@ public class TootActivity extends BaseActivity implements OnRetrieveSearcAccount
|
|||
toot_it.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
toot_it.setEnabled(false);
|
||||
if(toot_content.getText().toString().trim().length() == 0 && attachments.size() == 0){
|
||||
Toasty.error(getApplicationContext(),getString(R.string.toot_select_image_error),Toast.LENGTH_LONG).show();
|
||||
toot_it.setEnabled(true);
|
||||
return;
|
||||
}
|
||||
boolean split_toot = sharedpreferences.getBoolean(Helper.SET_AUTOMATICALLY_SPLIT_TOOTS, false);
|
||||
int split_toot_size = sharedpreferences.getInt(Helper.SET_AUTOMATICALLY_SPLIT_TOOTS_SIZE, Helper.SPLIT_TOOT_SIZE);
|
||||
String tootContent;
|
||||
if( toot_cw_content.getText() != null && toot_cw_content.getText().toString().trim().length() > 0 )
|
||||
split_toot_size -= toot_cw_content.getText().toString().trim().length();
|
||||
if( !split_toot || (toot_content.getText().toString().trim().length() < split_toot_size)){
|
||||
tootContent = toot_content.getText().toString().trim();
|
||||
}else{
|
||||
splitToot = Helper.splitToots(toot_content.getText().toString().trim(), split_toot_size);
|
||||
tootContent = splitToot.get(0);
|
||||
stepSpliToot = 1;
|
||||
}
|
||||
Status toot = new Status();
|
||||
toot.setSensitive(isSensitive);
|
||||
toot.setMedia_attachments(attachments);
|
||||
if( toot_cw_content.getText().toString().trim().length() > 0)
|
||||
toot.setSpoiler_text(toot_cw_content.getText().toString().trim());
|
||||
toot.setVisibility(visibility);
|
||||
if( tootReply != null)
|
||||
toot.setIn_reply_to_id(tootReply.getId());
|
||||
toot.setContent(tootContent);
|
||||
new PostStatusAsyncTask(getApplicationContext(), accountReply, toot, TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
|
||||
sendToot(null);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -655,6 +634,8 @@ public class TootActivity extends BaseActivity implements OnRetrieveSearcAccount
|
|||
}
|
||||
});
|
||||
|
||||
if( scheduledstatus != null)
|
||||
restoreServerSchedule(scheduledstatus.getStatus());
|
||||
|
||||
if( restored != -1 ){
|
||||
restoreToot(restored);
|
||||
|
@ -796,6 +777,16 @@ public class TootActivity extends BaseActivity implements OnRetrieveSearcAccount
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPostAction(int statusCode, API.StatusAction statusAction, String userId, Error error) {
|
||||
if( error != null){
|
||||
Toasty.error(getApplicationContext(),getString(R.string.toast_error),Toast.LENGTH_LONG).show();
|
||||
}else {
|
||||
Toasty.success(getApplicationContext(),getString(R.string.toot_scheduled),Toast.LENGTH_LONG).show();
|
||||
resetForNextToot();
|
||||
}
|
||||
}
|
||||
|
||||
private class asyncPicture extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
ByteArrayInputStream bs;
|
||||
|
@ -1255,33 +1246,40 @@ public class TootActivity extends BaseActivity implements OnRetrieveSearcAccount
|
|||
datePicker.getDayOfMonth(),
|
||||
hour,
|
||||
minute);
|
||||
long time = calendar.getTimeInMillis();
|
||||
if( (time - new Date().getTime()) < 60000 ){
|
||||
final long[] time = {calendar.getTimeInMillis()};
|
||||
|
||||
if( (time[0] - new Date().getTime()) < 60000 ){
|
||||
Toasty.warning(getApplicationContext(), getString(R.string.toot_scheduled_date), Toast.LENGTH_LONG).show();
|
||||
}else {
|
||||
//Store the toot as draft first
|
||||
storeToot(false, false);
|
||||
//Schedules the toot
|
||||
ScheduledTootsSyncJob.schedule(getApplicationContext(), currentToId, time);
|
||||
//Clear content
|
||||
toot_content.setText("");
|
||||
toot_cw_content.setText("");
|
||||
toot_space_left.setText("0");
|
||||
if( attachments != null) {
|
||||
for (Attachment attachment : attachments) {
|
||||
View namebar = findViewById(Integer.parseInt(attachment.getId()));
|
||||
if (namebar != null && namebar.getParent() != null)
|
||||
((ViewGroup) namebar.getParent()).removeView(namebar);
|
||||
}
|
||||
List<Attachment> tmp_attachment = new ArrayList<>();
|
||||
tmp_attachment.addAll(attachments);
|
||||
attachments.removeAll(tmp_attachment);
|
||||
tmp_attachment.clear();
|
||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
|
||||
String instanceVersion = sharedpreferences.getString(Helper.INSTANCE_VERSION + userId + instance, null);
|
||||
Version currentVersion = new Version(instanceVersion);
|
||||
Version minVersion = new Version("2.7");
|
||||
if (currentVersion.compareTo(minVersion) == 1 || currentVersion.equals(minVersion)) {
|
||||
AlertDialog.Builder builderSingle = new AlertDialog.Builder(TootActivity.this, style);
|
||||
builderSingle.setTitle(getString(R.string.choose_schedule));
|
||||
builderSingle.setNegativeButton(R.string.device_schedule, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
deviceSchedule(time[0]);
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
builderSingle.setPositiveButton(R.string.server_schedule, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(final DialogInterface dialog, int which) {
|
||||
int offset = TimeZone.getDefault().getRawOffset();
|
||||
calendar.add(Calendar.MILLISECOND, -offset);
|
||||
final String date = Helper.dateToString(new Date(calendar.getTimeInMillis()));
|
||||
serverSchedule(date);
|
||||
}
|
||||
});
|
||||
builderSingle.show();
|
||||
|
||||
} else {
|
||||
deviceSchedule(time[0]);
|
||||
}
|
||||
isSensitive = false;
|
||||
toot_sensitive.setVisibility(View.GONE);
|
||||
currentToId = -1;
|
||||
Toasty.info(TootActivity.this,getString(R.string.toot_scheduled), Toast.LENGTH_LONG).show();
|
||||
|
||||
alertDialog.dismiss();
|
||||
}
|
||||
}
|
||||
|
@ -1293,6 +1291,92 @@ public class TootActivity extends BaseActivity implements OnRetrieveSearcAccount
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private void sendToot(String timestamp){
|
||||
toot_it.setEnabled(false);
|
||||
if(toot_content.getText().toString().trim().length() == 0 && attachments.size() == 0){
|
||||
Toasty.error(getApplicationContext(),getString(R.string.toot_error_no_content),Toast.LENGTH_LONG).show();
|
||||
toot_it.setEnabled(true);
|
||||
return;
|
||||
}
|
||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
|
||||
boolean split_toot = sharedpreferences.getBoolean(Helper.SET_AUTOMATICALLY_SPLIT_TOOTS, false);
|
||||
int split_toot_size = sharedpreferences.getInt(Helper.SET_AUTOMATICALLY_SPLIT_TOOTS_SIZE, Helper.SPLIT_TOOT_SIZE);
|
||||
String tootContent;
|
||||
if( toot_cw_content.getText() != null && toot_cw_content.getText().toString().trim().length() > 0 )
|
||||
split_toot_size -= toot_cw_content.getText().toString().trim().length();
|
||||
if( !split_toot || (toot_content.getText().toString().trim().length() < split_toot_size)){
|
||||
tootContent = toot_content.getText().toString().trim();
|
||||
}else{
|
||||
splitToot = Helper.splitToots(toot_content.getText().toString().trim(), split_toot_size);
|
||||
tootContent = splitToot.get(0);
|
||||
stepSpliToot = 1;
|
||||
}
|
||||
Status toot = new Status();
|
||||
toot.setSensitive(isSensitive);
|
||||
toot.setMedia_attachments(attachments);
|
||||
if( toot_cw_content.getText().toString().trim().length() > 0)
|
||||
toot.setSpoiler_text(toot_cw_content.getText().toString().trim());
|
||||
toot.setVisibility(visibility);
|
||||
if( tootReply != null)
|
||||
toot.setIn_reply_to_id(tootReply.getId());
|
||||
toot.setContent(tootContent);
|
||||
if( timestamp == null)
|
||||
if( scheduledstatus == null)
|
||||
new PostStatusAsyncTask(getApplicationContext(), accountReply, toot, TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
else {
|
||||
toot.setScheduled_at(Helper.dateToString(scheduledstatus.getScheduled_date()));
|
||||
scheduledstatus.setStatus(toot);
|
||||
isScheduled = true;
|
||||
new PostActionAsyncTask(getApplicationContext(), API.StatusAction.DELETESCHEDULED, scheduledstatus, TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
new PostStatusAsyncTask(getApplicationContext(), accountReply, toot, TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
else {
|
||||
toot.setScheduled_at(timestamp);
|
||||
new PostStatusAsyncTask(getApplicationContext(), accountReply, toot, TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void serverSchedule(String time){
|
||||
sendToot(time);
|
||||
isScheduled = true;
|
||||
resetForNextToot();
|
||||
}
|
||||
|
||||
private void deviceSchedule(long time){
|
||||
//Store the toot as draft first
|
||||
storeToot(false, false);
|
||||
isScheduled = true;
|
||||
//Schedules the toot
|
||||
ScheduledTootsSyncJob.schedule(getApplicationContext(), currentToId, time);
|
||||
resetForNextToot();
|
||||
}
|
||||
|
||||
|
||||
private void resetForNextToot(){
|
||||
//Clear content
|
||||
toot_content.setText("");
|
||||
toot_cw_content.setText("");
|
||||
toot_space_left.setText("0");
|
||||
if( attachments != null) {
|
||||
for (Attachment attachment : attachments) {
|
||||
View namebar = findViewById(Integer.parseInt(attachment.getId()));
|
||||
if (namebar != null && namebar.getParent() != null)
|
||||
((ViewGroup) namebar.getParent()).removeView(namebar);
|
||||
}
|
||||
List<Attachment> tmp_attachment = new ArrayList<>();
|
||||
tmp_attachment.addAll(attachments);
|
||||
attachments.removeAll(tmp_attachment);
|
||||
tmp_attachment.clear();
|
||||
}
|
||||
isSensitive = false;
|
||||
toot_sensitive.setVisibility(View.GONE);
|
||||
currentToId = -1;
|
||||
Toasty.info(TootActivity.this,getString(R.string.toot_scheduled), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.main_toot, menu);
|
||||
|
@ -1477,7 +1561,7 @@ public class TootActivity extends BaseActivity implements OnRetrieveSearcAccount
|
|||
final EditText input = popup_media_description.findViewById(R.id.media_description);
|
||||
input.setFilters(new InputFilter[]{new InputFilter.LengthFilter(420)});
|
||||
final ImageView media_picture = popup_media_description.findViewById(R.id.media_picture);
|
||||
GlideApp.with(getApplicationContext())
|
||||
Glide.with(getApplicationContext())
|
||||
.asBitmap()
|
||||
.load(attachment.getUrl())
|
||||
.into(new SimpleTarget<Bitmap>() {
|
||||
|
@ -1677,7 +1761,10 @@ public class TootActivity extends BaseActivity implements OnRetrieveSearcAccount
|
|||
isSensitive = false;
|
||||
toot_sensitive.setVisibility(View.GONE);
|
||||
currentToId = -1;
|
||||
Toasty.success(TootActivity.this, getString(R.string.toot_sent), Toast.LENGTH_LONG).show();
|
||||
if( scheduledstatus == null && !isScheduled)
|
||||
Toasty.success(TootActivity.this, getString(R.string.toot_sent), Toast.LENGTH_LONG).show();
|
||||
else
|
||||
Toasty.success(TootActivity.this, getString(R.string.toot_scheduled), Toast.LENGTH_LONG).show();
|
||||
toot_it.setEnabled(true);
|
||||
//It's a reply, so the user will be redirect to its answer
|
||||
if( tootReply != null){
|
||||
|
@ -1762,6 +1849,11 @@ public class TootActivity extends BaseActivity implements OnRetrieveSearcAccount
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRetrieveEmoji(Notification notification) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRetrieveSearchEmoji(final List<Emojis> emojis) {
|
||||
if( pp_progress != null && pp_actionBar != null) {
|
||||
|
@ -1863,6 +1955,8 @@ public class TootActivity extends BaseActivity implements OnRetrieveSearcAccount
|
|||
private void restoreToot(long id){
|
||||
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
StoredStatus draft = new StatusStoredDAO(TootActivity.this, db).getStatus(id);
|
||||
if( draft == null)
|
||||
return;
|
||||
Status status = draft.getStatus();
|
||||
//Retrieves attachments
|
||||
if( removed ){
|
||||
|
@ -2009,6 +2103,139 @@ public class TootActivity extends BaseActivity implements OnRetrieveSearcAccount
|
|||
}
|
||||
|
||||
|
||||
private void restoreServerSchedule(Status status){
|
||||
|
||||
attachments = status.getMedia_attachments();
|
||||
int childCount = toot_picture_container.getChildCount();
|
||||
ArrayList<ImageView> toRemove = new ArrayList<>();
|
||||
if( childCount > 0 ){
|
||||
for(int i = 0 ; i < childCount ; i++){
|
||||
if( toot_picture_container.getChildAt(i) instanceof ImageView)
|
||||
toRemove.add((ImageView)toot_picture_container.getChildAt(i));
|
||||
}
|
||||
if( toRemove.size() > 0){
|
||||
for(ImageView imageView: toRemove)
|
||||
toot_picture_container.removeView(imageView);
|
||||
}
|
||||
toRemove.clear();
|
||||
}
|
||||
String content = status.getContent();
|
||||
Pattern mentionLink = Pattern.compile("(<\\s?a\\s?href=\"https?:\\/\\/([\\da-z\\.-]+\\.[a-z\\.]{2,10})\\/(@[\\/\\w._-]*)\"\\s?[^.]*<\\s?\\/\\s?a\\s?>)");
|
||||
Matcher matcher = mentionLink.matcher(content);
|
||||
if (matcher.find()) {
|
||||
content = matcher.replaceAll("$3@$2");
|
||||
}
|
||||
if( removed ) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||
content = Html.fromHtml(content, Html.FROM_HTML_MODE_LEGACY).toString();
|
||||
else
|
||||
//noinspection deprecation
|
||||
content = Html.fromHtml(content).toString();
|
||||
}
|
||||
if( attachments != null && attachments.size() > 0){
|
||||
toot_picture_container.setVisibility(View.VISIBLE);
|
||||
picture_scrollview.setVisibility(View.VISIBLE);
|
||||
int i = 0 ;
|
||||
for(final Attachment attachment: attachments){
|
||||
String url = attachment.getPreview_url();
|
||||
if( url == null || url.trim().equals(""))
|
||||
url = attachment.getUrl();
|
||||
final ImageView imageView = new ImageView(getApplicationContext());
|
||||
imageView.setId(Integer.parseInt(attachment.getId()));
|
||||
|
||||
LinearLayout.LayoutParams imParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
|
||||
imParams.setMargins(20, 5, 20, 5);
|
||||
imParams.height = (int) Helper.convertDpToPixel(100, getApplicationContext());
|
||||
imageView.setAdjustViewBounds(true);
|
||||
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
|
||||
toot_picture_container.addView(imageView, i, imParams);
|
||||
|
||||
Glide.with(imageView.getContext())
|
||||
.asBitmap()
|
||||
.load(url)
|
||||
.into(new SimpleTarget<Bitmap>() {
|
||||
@Override
|
||||
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
|
||||
imageView.setImageBitmap(resource);
|
||||
}
|
||||
});
|
||||
imageView.setTag(attachment.getId());
|
||||
imageView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
|
||||
String instanceVersion = sharedpreferences.getString(Helper.INSTANCE_VERSION + userId + instance, null);
|
||||
if (instanceVersion != null) {
|
||||
Version currentVersion = new Version(instanceVersion);
|
||||
Version minVersion = new Version("2.0");
|
||||
if (currentVersion.compareTo(minVersion) == 1 || currentVersion.equals(minVersion)) {
|
||||
imageView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
showAddDescription(attachment);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
imageView.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View view) {
|
||||
showRemove(imageView.getId());
|
||||
return false;
|
||||
}
|
||||
});
|
||||
addBorder();
|
||||
if( attachments.size() < 4)
|
||||
toot_picture.setEnabled(true);
|
||||
toot_sensitive.setVisibility(View.VISIBLE);
|
||||
i++;
|
||||
}
|
||||
}else {
|
||||
toot_picture_container.setVisibility(View.GONE);
|
||||
}
|
||||
//Sensitive content
|
||||
toot_sensitive.setChecked(status.isSensitive());
|
||||
if( status.getSpoiler_text() != null && status.getSpoiler_text().length() > 0 ){
|
||||
toot_cw_content.setText(status.getSpoiler_text());
|
||||
toot_cw_content.setVisibility(View.VISIBLE);
|
||||
}else {
|
||||
toot_cw_content.setText("");
|
||||
toot_cw_content.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
toot_content.setText(content);
|
||||
toot_space_left.setText(String.valueOf(toot_content.length()));
|
||||
toot_content.setSelection(toot_content.getText().length());
|
||||
switch (status.getVisibility()){
|
||||
case "public":
|
||||
visibility = "public";
|
||||
toot_visibility.setImageResource(R.drawable.ic_public_toot);
|
||||
break;
|
||||
case "unlisted":
|
||||
visibility = "unlisted";
|
||||
toot_visibility.setImageResource(R.drawable.ic_lock_open_toot);
|
||||
break;
|
||||
case "private":
|
||||
visibility = "private";
|
||||
toot_visibility.setImageResource(R.drawable.ic_lock_outline_toot);
|
||||
break;
|
||||
case "direct":
|
||||
visibility = "direct";
|
||||
toot_visibility.setImageResource(R.drawable.ic_mail_outline_toot);
|
||||
break;
|
||||
}
|
||||
|
||||
if( title != null)
|
||||
title.setText(getString(R.string.toot_title));
|
||||
else
|
||||
setTitle(R.string.toot_title);
|
||||
invalidateOptionsMenu();
|
||||
initialContent = toot_content.getText().toString();
|
||||
toot_space_left.setText(String.valueOf(toot_content.getText().length() + toot_cw_content.getText().length()));
|
||||
}
|
||||
|
||||
private void tootReply(){
|
||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
|
||||
if( title != null)
|
||||
|
@ -2257,7 +2484,7 @@ public class TootActivity extends BaseActivity implements OnRetrieveSearcAccount
|
|||
View v = toot_picture_container.getChildAt(i);
|
||||
if (v instanceof ImageView) {
|
||||
for(Attachment attachment: attachments){
|
||||
if(attachment.getType().equals("image"))
|
||||
if(attachment.getType().toLowerCase().equals("image"))
|
||||
if( v.getTag().toString().trim().equals(attachment.getId().trim())){
|
||||
int borderSize = (int)convertDpToPixel(1, TootActivity.this);
|
||||
int borderSizeTop = (int)convertDpToPixel(6, TootActivity.this);
|
||||
|
|
|
@ -142,13 +142,13 @@ public class TootInfoActivity extends BaseActivity {
|
|||
case 0:
|
||||
DisplayAccountsFragment displayAccountsFragment = new DisplayAccountsFragment();
|
||||
bundle.putSerializable("type", RetrieveAccountsAsyncTask.Type.REBLOGGED);
|
||||
bundle.putString("targetedId", toot_id);
|
||||
bundle.putString("targetedid", toot_id);
|
||||
displayAccountsFragment.setArguments(bundle);
|
||||
return displayAccountsFragment;
|
||||
case 1:
|
||||
displayAccountsFragment = new DisplayAccountsFragment();
|
||||
bundle.putSerializable("type", RetrieveAccountsAsyncTask.Type.FAVOURITED);
|
||||
bundle.putString("targetedId", toot_id);
|
||||
bundle.putString("targetedid", toot_id);
|
||||
displayAccountsFragment.setArguments(bundle);
|
||||
return displayAccountsFragment;
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ public class WebviewActivity extends BaseActivity {
|
|||
if( getSupportActionBar() != null)
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
webView = Helper.initializeWebview(WebviewActivity.this, R.id.webview);
|
||||
webView = Helper.initializeWebview(WebviewActivity.this, R.id.webview);
|
||||
setTitle("");
|
||||
FrameLayout webview_container = findViewById(R.id.webview_container);
|
||||
final ViewGroup videoLayout = findViewById(R.id.videoLayout); // Your own view, read class comments
|
||||
|
|
|
@ -63,6 +63,7 @@ public class WebviewConnectActivity extends BaseActivity {
|
|||
private AlertDialog alert;
|
||||
private String clientId, clientSecret;
|
||||
private String instance;
|
||||
private UpdateAccountInfoAsyncTask.SOCIAL social;
|
||||
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
@ -84,8 +85,10 @@ public class WebviewConnectActivity extends BaseActivity {
|
|||
|
||||
setContentView(R.layout.activity_webview_connect);
|
||||
Bundle b = getIntent().getExtras();
|
||||
if(b != null)
|
||||
if(b != null) {
|
||||
instance = b.getString("instance");
|
||||
social = (UpdateAccountInfoAsyncTask.SOCIAL) b.getSerializable("social");
|
||||
}
|
||||
if( instance == null)
|
||||
finish();
|
||||
clientId = sharedpreferences.getString(Helper.CLIENT_ID, null);
|
||||
|
@ -162,12 +165,15 @@ public class WebviewConnectActivity extends BaseActivity {
|
|||
try {
|
||||
resobj = new JSONObject(response);
|
||||
String token = resobj.get("access_token").toString();
|
||||
String refresh_token = null;
|
||||
if( resobj.has("refresh_token"))
|
||||
refresh_token = resobj.get("refresh_token").toString();
|
||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.PREF_KEY_OAUTH_TOKEN, token);
|
||||
editor.apply();
|
||||
//Update the account with the token;
|
||||
new UpdateAccountInfoAsyncTask(WebviewConnectActivity.this, token, instance).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
new UpdateAccountInfoAsyncTask(WebviewConnectActivity.this, token, clientId, clientSecret, refresh_token, instance, social).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
} catch (JSONException ignored) {}
|
||||
} catch (Exception ignored) {}
|
||||
}}).start();
|
||||
|
|
|
@ -20,9 +20,13 @@ import android.os.AsyncTask;
|
|||
import java.lang.ref.WeakReference;
|
||||
import java.util.List;
|
||||
|
||||
import fr.gouv.etalab.mastodon.activities.MainActivity;
|
||||
import fr.gouv.etalab.mastodon.client.API;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Error;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Results;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.StoredStatus;
|
||||
import fr.gouv.etalab.mastodon.client.PeertubeAPI;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnPostActionInterface;
|
||||
|
||||
|
@ -37,16 +41,22 @@ public class PostActionAsyncTask extends AsyncTask<Void, Void, Void> {
|
|||
private OnPostActionInterface listener;
|
||||
private int statusCode;
|
||||
private API.StatusAction apiAction;
|
||||
private String targetedId;
|
||||
private String targetedId, targetedComment;
|
||||
private String comment;
|
||||
private fr.gouv.etalab.mastodon.client.Entities.Status status;
|
||||
private API api;
|
||||
private Account account, remoteAccount;
|
||||
private fr.gouv.etalab.mastodon.client.Entities.Status remoteStatus;
|
||||
private WeakReference<Context> contextReference;
|
||||
private boolean muteNotifications;
|
||||
private Error error;
|
||||
private StoredStatus storedStatus;
|
||||
|
||||
|
||||
public PostActionAsyncTask(Context context, API.StatusAction apiAction, StoredStatus storedStatus, OnPostActionInterface onPostActionInterface){
|
||||
this.contextReference = new WeakReference<>(context);
|
||||
this.listener = onPostActionInterface;
|
||||
this.apiAction = apiAction;
|
||||
this.storedStatus = storedStatus;
|
||||
}
|
||||
|
||||
public PostActionAsyncTask(Context context, API.StatusAction apiAction, String targetedId, OnPostActionInterface onPostActionInterface){
|
||||
this.contextReference = new WeakReference<>(context);
|
||||
|
@ -95,63 +105,105 @@ public class PostActionAsyncTask extends AsyncTask<Void, Void, Void> {
|
|||
this.muteNotifications = muteNotifications;
|
||||
}
|
||||
|
||||
|
||||
public PostActionAsyncTask(Context context, String targetedId, String comment, String targetedComment, OnPostActionInterface onPostActionInterface){
|
||||
this.contextReference = new WeakReference<>(context);
|
||||
this.listener = onPostActionInterface;
|
||||
this.apiAction = API.StatusAction.PEERTUBEREPLY;
|
||||
this.targetedId = targetedId;
|
||||
this.comment = comment;
|
||||
this.targetedComment = targetedComment;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
|
||||
//Remote action
|
||||
if (account != null)
|
||||
api = new API(contextReference.get(), account.getInstance(), account.getToken());
|
||||
else
|
||||
api = new API(contextReference.get());
|
||||
if (remoteStatus != null) {
|
||||
String uri;
|
||||
if (remoteStatus.getReblog() != null) {
|
||||
if (remoteStatus.getReblog().getUri().startsWith("http"))
|
||||
uri = remoteStatus.getReblog().getUri();
|
||||
else
|
||||
uri = remoteStatus.getReblog().getUrl();
|
||||
} else {
|
||||
if (remoteStatus.getUri().startsWith("http"))
|
||||
uri = remoteStatus.getUri();
|
||||
else
|
||||
uri = remoteStatus.getUrl();
|
||||
}
|
||||
Results search = api.search(uri);
|
||||
if (search != null) {
|
||||
List<fr.gouv.etalab.mastodon.client.Entities.Status> remoteStatuses = search.getStatuses();
|
||||
if (remoteStatuses != null && remoteStatuses.size() > 0) {
|
||||
fr.gouv.etalab.mastodon.client.Entities.Status statusTmp = remoteStatuses.get(0);
|
||||
this.targetedId = statusTmp.getId();
|
||||
statusCode = api.postAction(apiAction, targetedId);
|
||||
}
|
||||
}
|
||||
}else if(remoteAccount != null){
|
||||
String searchString = remoteAccount.getAcct().contains("@")?"@" + remoteAccount.getAcct():"@" + remoteAccount.getAcct() + "@" + Helper.getLiveInstance(contextReference.get());
|
||||
Results search = api.search(searchString);
|
||||
if (search != null) {
|
||||
List<Account> accounts = search.getAccounts();
|
||||
if (accounts != null && accounts.size() > 0) {
|
||||
Account accountTmp = accounts.get(0);
|
||||
this.targetedId = accountTmp.getId();
|
||||
statusCode = api.postAction(apiAction, targetedId);
|
||||
}
|
||||
}
|
||||
}else {
|
||||
if (apiAction == API.StatusAction.REPORT)
|
||||
statusCode = api.reportAction(status, comment);
|
||||
else if (apiAction == API.StatusAction.CREATESTATUS)
|
||||
statusCode = api.statusAction(status);
|
||||
else if( apiAction == API.StatusAction.MUTE_NOTIFICATIONS)
|
||||
statusCode = api.muteNotifications(targetedId, muteNotifications);
|
||||
if(MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON || MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PIXELFED) {
|
||||
//Remote action
|
||||
API api;
|
||||
if (account != null)
|
||||
api = new API(contextReference.get(), account.getInstance(), account.getToken());
|
||||
else
|
||||
statusCode = api.postAction(apiAction, targetedId);
|
||||
api = new API(contextReference.get());
|
||||
if (remoteStatus != null) {
|
||||
String uri;
|
||||
if (remoteStatus.getReblog() != null) {
|
||||
if (remoteStatus.getReblog().getUri().startsWith("http"))
|
||||
uri = remoteStatus.getReblog().getUri();
|
||||
else
|
||||
uri = remoteStatus.getReblog().getUrl();
|
||||
} else {
|
||||
if (remoteStatus.getUri().startsWith("http"))
|
||||
uri = remoteStatus.getUri();
|
||||
else
|
||||
uri = remoteStatus.getUrl();
|
||||
}
|
||||
Results search = api.search(uri);
|
||||
if (search != null) {
|
||||
List<fr.gouv.etalab.mastodon.client.Entities.Status> remoteStatuses = search.getStatuses();
|
||||
if (remoteStatuses != null && remoteStatuses.size() > 0) {
|
||||
fr.gouv.etalab.mastodon.client.Entities.Status statusTmp = remoteStatuses.get(0);
|
||||
this.targetedId = statusTmp.getId();
|
||||
statusCode = api.postAction(apiAction, targetedId);
|
||||
}
|
||||
}
|
||||
} else if (remoteAccount != null) {
|
||||
String searchString = remoteAccount.getAcct().contains("@") ? "@" + remoteAccount.getAcct() : "@" + remoteAccount.getAcct() + "@" + Helper.getLiveInstance(contextReference.get());
|
||||
Results search = api.search(searchString);
|
||||
if (search != null) {
|
||||
List<Account> accounts = search.getAccounts();
|
||||
if (accounts != null && accounts.size() > 0) {
|
||||
Account accountTmp = accounts.get(0);
|
||||
this.targetedId = accountTmp.getId();
|
||||
statusCode = api.postAction(apiAction, targetedId);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (apiAction == API.StatusAction.REPORT)
|
||||
statusCode = api.reportAction(status, comment);
|
||||
else if (apiAction == API.StatusAction.CREATESTATUS)
|
||||
statusCode = api.statusAction(status);
|
||||
else if(apiAction == API.StatusAction.UPDATESERVERSCHEDULE) {
|
||||
api.scheduledAction("PUT", storedStatus.getStatus(), null, storedStatus.getScheduledServerdId());
|
||||
}
|
||||
else if(apiAction == API.StatusAction.DELETESCHEDULED) {
|
||||
api.scheduledAction("DELETE", null, null, storedStatus.getScheduledServerdId());
|
||||
}else if (apiAction == API.StatusAction.MUTE_NOTIFICATIONS)
|
||||
statusCode = api.muteNotifications(targetedId, muteNotifications);
|
||||
else
|
||||
statusCode = api.postAction(apiAction, targetedId);
|
||||
}
|
||||
error = api.getError();
|
||||
}else if( MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE){
|
||||
//Remote action
|
||||
PeertubeAPI peertubeAPI;
|
||||
if (account != null)
|
||||
peertubeAPI = new PeertubeAPI(contextReference.get(), account.getInstance(), account.getToken());
|
||||
else
|
||||
peertubeAPI = new PeertubeAPI(contextReference.get());
|
||||
|
||||
if( apiAction == API.StatusAction.FOLLOW || apiAction == API.StatusAction.UNFOLLOW)
|
||||
statusCode = peertubeAPI.postAction(apiAction, targetedId);
|
||||
else if( apiAction == API.StatusAction.RATEVIDEO )
|
||||
statusCode = peertubeAPI.postRating(targetedId, comment);
|
||||
else if( apiAction == API.StatusAction.PEERTUBECOMMENT)
|
||||
statusCode = peertubeAPI.postComment(targetedId, comment);
|
||||
else if( apiAction == API.StatusAction.PEERTUBEREPLY)
|
||||
statusCode = peertubeAPI.postReply(targetedId, comment, targetedComment);
|
||||
else if( apiAction == API.StatusAction.PEERTUBEDELETECOMMENT) {
|
||||
statusCode = peertubeAPI.deleteComment(targetedId, comment);
|
||||
targetedId = comment;
|
||||
} else if( apiAction == API.StatusAction.PEERTUBEDELETEVIDEO) {
|
||||
statusCode = peertubeAPI.deleteVideo(targetedId);
|
||||
}
|
||||
error = peertubeAPI.getError();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void result) {
|
||||
listener.onPostAction(statusCode, apiAction, targetedId, api.getError());
|
||||
listener.onPostAction(statusCode, apiAction, targetedId, error);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
/* Copyright 2019 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Mastalab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Mastalab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
package fr.gouv.etalab.mastodon.asynctasks;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import fr.gouv.etalab.mastodon.client.APIResponse;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Peertube;
|
||||
import fr.gouv.etalab.mastodon.client.PeertubeAPI;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrievePeertubeInterface;
|
||||
|
||||
|
||||
/**
|
||||
* Created by Thomas on 09/01/2019.
|
||||
* Update a Peertube video
|
||||
*/
|
||||
|
||||
public class PostPeertubeAsyncTask extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
|
||||
|
||||
private APIResponse apiResponse;
|
||||
private OnRetrievePeertubeInterface listener;
|
||||
private WeakReference<Context> contextReference;
|
||||
private Peertube peertube;
|
||||
|
||||
|
||||
|
||||
public PostPeertubeAsyncTask(Context context, Peertube peertube, OnRetrievePeertubeInterface onRetrievePeertubeInterface){
|
||||
this.contextReference = new WeakReference<>(context);
|
||||
this.listener = onRetrievePeertubeInterface;
|
||||
this.peertube = peertube;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
PeertubeAPI peertubeAPI = new PeertubeAPI(this.contextReference.get());
|
||||
apiResponse = peertubeAPI.updateVideo(peertube);
|
||||
if( apiResponse != null && apiResponse.getPeertubes() != null && apiResponse.getPeertubes().size() > 0)
|
||||
apiResponse.getPeertubes().get(0).setUpdate(true);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void result) {
|
||||
listener.onRetrievePeertube(apiResponse);
|
||||
}
|
||||
}
|
|
@ -19,9 +19,12 @@ import android.os.AsyncTask;
|
|||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveAccountInterface;
|
||||
import fr.gouv.etalab.mastodon.activities.MainActivity;
|
||||
import fr.gouv.etalab.mastodon.client.API;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Error;
|
||||
import fr.gouv.etalab.mastodon.client.PeertubeAPI;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveAccountInterface;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -35,7 +38,7 @@ public class RetrieveAccountAsyncTask extends AsyncTask<Void, Void, Void> {
|
|||
private String targetedId;
|
||||
private Account account;
|
||||
private OnRetrieveAccountInterface listener;
|
||||
private API api;
|
||||
private Error error;
|
||||
private WeakReference<Context> contextReference;
|
||||
|
||||
public RetrieveAccountAsyncTask(Context context, String targetedId, OnRetrieveAccountInterface onRetrieveAccountInterface){
|
||||
|
@ -46,14 +49,21 @@ public class RetrieveAccountAsyncTask extends AsyncTask<Void, Void, Void> {
|
|||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
api = new API(this.contextReference.get());
|
||||
account = api.getAccount(targetedId);
|
||||
if(MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON) {
|
||||
API api = new API(this.contextReference.get());
|
||||
account = api.getAccount(targetedId);
|
||||
error = api.getError();
|
||||
}else if(MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE) {
|
||||
PeertubeAPI peertubeAPI = new PeertubeAPI(this.contextReference.get());
|
||||
account = peertubeAPI.getAccount(targetedId);
|
||||
error = peertubeAPI.getError();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void result) {
|
||||
listener.onRetrieveAccount(account, api.getError());
|
||||
listener.onRetrieveAccount(account, error);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/* Copyright 2018 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Mastalab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Mastalab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
package fr.gouv.etalab.mastodon.asynctasks;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import fr.gouv.etalab.mastodon.client.API;
|
||||
import fr.gouv.etalab.mastodon.client.APIResponse;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveFeedsAfterBookmarkInterface;
|
||||
|
||||
|
||||
/**
|
||||
* Created by Thomas on 22/12/2018.
|
||||
* Retrieves toots younger than the bookmarks
|
||||
*/
|
||||
|
||||
public class RetrieveFeedsAfterBookmarkAsyncTask extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
|
||||
private APIResponse apiResponse;
|
||||
private OnRetrieveFeedsAfterBookmarkInterface listener;
|
||||
private WeakReference<Context> contextReference;
|
||||
private String max_id;
|
||||
|
||||
|
||||
public RetrieveFeedsAfterBookmarkAsyncTask(Context context, String max_id, OnRetrieveFeedsAfterBookmarkInterface onRetrieveFeedsAfterBookmarkInterface){
|
||||
this.contextReference = new WeakReference<>(context);
|
||||
this.listener = onRetrieveFeedsAfterBookmarkInterface;
|
||||
this.max_id = max_id;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
API api = new API(this.contextReference.get());
|
||||
apiResponse = api.getHomeTimeline(max_id);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void result) {
|
||||
listener.onRetrieveFeedsAfterBookmark(apiResponse);
|
||||
}
|
||||
}
|
|
@ -21,11 +21,13 @@ import android.os.AsyncTask;
|
|||
import java.lang.ref.WeakReference;
|
||||
import java.util.List;
|
||||
|
||||
import fr.gouv.etalab.mastodon.activities.MainActivity;
|
||||
import fr.gouv.etalab.mastodon.client.API;
|
||||
import fr.gouv.etalab.mastodon.client.APIResponse;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Peertube;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.RemoteInstance;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.TagTimeline;
|
||||
import fr.gouv.etalab.mastodon.client.PeertubeAPI;
|
||||
import fr.gouv.etalab.mastodon.helper.FilterToots;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveFeedsInterface;
|
||||
import fr.gouv.etalab.mastodon.sqlite.InstancesDAO;
|
||||
|
@ -74,7 +76,22 @@ public class RetrieveFeedsAsyncTask extends AsyncTask<Void, Void, Void> {
|
|||
CACHE_BOOKMARKS_PEERTUBE,
|
||||
CACHE_STATUS,
|
||||
REMOTE_INSTANCE,
|
||||
ART
|
||||
ART,
|
||||
NOTIFICATION,
|
||||
PIXELFED,
|
||||
PSUBSCRIPTIONS,
|
||||
POVERVIEW,
|
||||
PTRENDING,
|
||||
PRECENTLYADDED,
|
||||
PMYVIDEOS,
|
||||
PLOCAL,
|
||||
CHANNEL,
|
||||
MYVIDEOS,
|
||||
PF_HOME,
|
||||
PF_LOCAL,
|
||||
PF_DISCOVER,
|
||||
PF_NOTIFICATION,
|
||||
SCHEDULED_TOOTS
|
||||
}
|
||||
|
||||
|
||||
|
@ -152,6 +169,9 @@ public class RetrieveFeedsAsyncTask extends AsyncTask<Void, Void, Void> {
|
|||
case PUBLIC:
|
||||
apiResponse = api.getPublicTimeline(false, max_id);
|
||||
break;
|
||||
case SCHEDULED_TOOTS:
|
||||
apiResponse = api.scheduledAction("GET", null, max_id, null);
|
||||
break;
|
||||
case DIRECT:
|
||||
apiResponse = api.getDirectTimeline(max_id);
|
||||
break;
|
||||
|
@ -171,6 +191,16 @@ public class RetrieveFeedsAsyncTask extends AsyncTask<Void, Void, Void> {
|
|||
status.setType(action);
|
||||
}
|
||||
}
|
||||
}else if(remoteInstanceObj != null && remoteInstanceObj.size() > 0 && remoteInstanceObj.get(0).getType().equals("MISSKEY")){
|
||||
apiResponse = api.getMisskey(this.instanceName, max_id);
|
||||
List<fr.gouv.etalab.mastodon.client.Entities.Status> statusesTemp = apiResponse.getStatuses();
|
||||
if( statusesTemp != null){
|
||||
for(fr.gouv.etalab.mastodon.client.Entities.Status status: statusesTemp){
|
||||
status.setType(action);
|
||||
}
|
||||
}
|
||||
} else if(remoteInstanceObj != null && remoteInstanceObj.size() > 0 && remoteInstanceObj.get(0).getType().equals("PIXELFED") ) {
|
||||
apiResponse = api.getPixelfedTimeline(instanceName, max_id);
|
||||
}else {
|
||||
apiResponse = api.getPeertube(this.instanceName, max_id);
|
||||
}
|
||||
|
@ -180,12 +210,25 @@ public class RetrieveFeedsAsyncTask extends AsyncTask<Void, Void, Void> {
|
|||
apiResponse = api.getFavourites(max_id);
|
||||
break;
|
||||
case USER:
|
||||
if( showMediaOnly)
|
||||
apiResponse = api.getStatusWithMedia(targetedID, max_id);
|
||||
else if (showPinned)
|
||||
apiResponse = api.getPinnedStatuses(targetedID, max_id);
|
||||
else
|
||||
apiResponse = api.getAccountTLStatuses(targetedID, max_id, !showReply);
|
||||
if(MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON) {
|
||||
if (showMediaOnly)
|
||||
apiResponse = api.getStatusWithMedia(targetedID, max_id);
|
||||
else if (showPinned)
|
||||
apiResponse = api.getPinnedStatuses(targetedID, max_id);
|
||||
else
|
||||
apiResponse = api.getAccountTLStatuses(targetedID, max_id, !showReply);
|
||||
}else if( MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE){
|
||||
PeertubeAPI peertubeAPI = new PeertubeAPI(this.contextReference.get());
|
||||
apiResponse = peertubeAPI.getVideos(targetedID, max_id);
|
||||
}
|
||||
break;
|
||||
case MYVIDEOS:
|
||||
PeertubeAPI peertubeAPI = new PeertubeAPI(this.contextReference.get());
|
||||
apiResponse = peertubeAPI.getMyVideos(max_id);
|
||||
break;
|
||||
case CHANNEL:
|
||||
peertubeAPI = new PeertubeAPI(this.contextReference.get());
|
||||
apiResponse = peertubeAPI.getVideosChannel(targetedID, max_id);
|
||||
break;
|
||||
case ONESTATUS:
|
||||
apiResponse = api.getStatusbyId(targetedID);
|
||||
|
@ -196,16 +239,16 @@ public class RetrieveFeedsAsyncTask extends AsyncTask<Void, Void, Void> {
|
|||
TagTimeline tagTimeline = tagTimelines.get(0);
|
||||
boolean isArt = tagTimeline.isART();
|
||||
if( isArt)
|
||||
apiResponse = api.getCustomArtTimeline(false, tag, max_id);
|
||||
apiResponse = api.getCustomArtTimeline(false, tag, max_id,tagTimelines.get(0).getAny(), tagTimelines.get(0).getAll(), tagTimelines.get(0).getNone());
|
||||
else
|
||||
apiResponse = api.getPublicTimelineTag(tag, false, max_id);
|
||||
apiResponse = api.getPublicTimelineTag(tag, false, max_id, tagTimelines.get(0).getAny(), tagTimelines.get(0).getAll(), tagTimelines.get(0).getNone());
|
||||
}else{
|
||||
apiResponse = api.getPublicTimelineTag(tag, false, max_id);
|
||||
apiResponse = api.getPublicTimelineTag(tag, false, max_id, null, null, null);
|
||||
}
|
||||
|
||||
break;
|
||||
case ART:
|
||||
apiResponse = api.getArtTimeline(false, max_id);
|
||||
apiResponse = api.getArtTimeline(false, max_id, null, null, null);
|
||||
break;
|
||||
case CACHE_BOOKMARKS:
|
||||
apiResponse = new APIResponse();
|
||||
|
@ -233,9 +276,54 @@ public class RetrieveFeedsAsyncTask extends AsyncTask<Void, Void, Void> {
|
|||
apiResponse.setSince_id(null);
|
||||
}
|
||||
break;
|
||||
|
||||
case PSUBSCRIPTIONS:
|
||||
peertubeAPI = new PeertubeAPI(this.contextReference.get());
|
||||
apiResponse = peertubeAPI.getSubscriptionsTL(max_id);
|
||||
break;
|
||||
case POVERVIEW:
|
||||
peertubeAPI = new PeertubeAPI(this.contextReference.get());
|
||||
apiResponse = peertubeAPI.getOverviewTL(max_id);
|
||||
break;
|
||||
case PTRENDING:
|
||||
peertubeAPI = new PeertubeAPI(this.contextReference.get());
|
||||
apiResponse = peertubeAPI.getTrendingTL(max_id);
|
||||
break;
|
||||
case PRECENTLYADDED:
|
||||
peertubeAPI = new PeertubeAPI(this.contextReference.get());
|
||||
apiResponse = peertubeAPI.getRecentlyAddedTL(max_id);
|
||||
break;
|
||||
case PLOCAL:
|
||||
peertubeAPI = new PeertubeAPI(this.contextReference.get());
|
||||
apiResponse = peertubeAPI.getLocalTL(max_id);
|
||||
break;
|
||||
case PMYVIDEOS:
|
||||
peertubeAPI = new PeertubeAPI(this.contextReference.get());
|
||||
apiResponse = peertubeAPI.getLocalTL(max_id);
|
||||
break;
|
||||
case PF_HOME:
|
||||
api = new API(this.contextReference.get());
|
||||
apiResponse = api.getHomeTimeline(max_id);
|
||||
break;
|
||||
case PF_LOCAL:
|
||||
api = new API(this.contextReference.get());
|
||||
apiResponse = api.getPublicTimeline(true,max_id);
|
||||
case PF_DISCOVER:
|
||||
api = new API(this.contextReference.get());
|
||||
apiResponse = api.getDiscoverTimeline(true,max_id);
|
||||
break;
|
||||
case HASHTAG:
|
||||
break;
|
||||
}
|
||||
if( MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON) {
|
||||
List<String> bookmarks = new StatusCacheDAO(contextReference.get(), db).getAllStatusId(StatusCacheDAO.BOOKMARK_CACHE);
|
||||
if (apiResponse != null && apiResponse.getStatuses() != null && bookmarks != null && apiResponse.getStatuses().size() > 0) {
|
||||
List<fr.gouv.etalab.mastodon.client.Entities.Status> statuses = apiResponse.getStatuses();
|
||||
for (fr.gouv.etalab.mastodon.client.Entities.Status status : statuses) {
|
||||
status.setBookmarked(bookmarks.contains(status.getId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
package fr.gouv.etalab.mastodon.asynctasks;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
@ -26,7 +27,10 @@ import fr.gouv.etalab.mastodon.client.API;
|
|||
import fr.gouv.etalab.mastodon.client.APIResponse;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Conversation;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.TagTimeline;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveMissingFeedsInterface;
|
||||
import fr.gouv.etalab.mastodon.sqlite.SearchDAO;
|
||||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -66,9 +70,9 @@ public class RetrieveMissingFeedsAsyncTask extends AsyncTask<Void, Void, Void> {
|
|||
API api = new API(this.contextReference.get());
|
||||
List<fr.gouv.etalab.mastodon.client.Entities.Status> tempStatus = null;
|
||||
APIResponse apiResponse = null;
|
||||
if( type == RetrieveFeedsAsyncTask.Type.HOME)
|
||||
apiResponse = api.getHomeTimeline(since_id);
|
||||
else if( type == RetrieveFeedsAsyncTask.Type.DIRECT)
|
||||
if( type == RetrieveFeedsAsyncTask.Type.HOME) {
|
||||
apiResponse = api.getHomeTimelineSinceId(since_id);
|
||||
}else if( type == RetrieveFeedsAsyncTask.Type.DIRECT)
|
||||
apiResponse = api.getDirectTimelineSinceId(since_id);
|
||||
else if( type == RetrieveFeedsAsyncTask.Type.CONVERSATION)
|
||||
apiResponse = api.getConversationTimelineSinceId(since_id);
|
||||
|
@ -78,6 +82,21 @@ public class RetrieveMissingFeedsAsyncTask extends AsyncTask<Void, Void, Void> {
|
|||
apiResponse = api.getPublicTimelineSinceId(false, since_id);
|
||||
else if (type == RetrieveFeedsAsyncTask.Type.REMOTE_INSTANCE)
|
||||
apiResponse = api.getInstanceTimelineSinceId(remoteInstance, since_id);
|
||||
else if (type == RetrieveFeedsAsyncTask.Type.TAG) {
|
||||
SQLiteDatabase db = Sqlite.getInstance(contextReference.get(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
List<TagTimeline> tagTimelines = new SearchDAO(contextReference.get(), db).getTimelineInfo(remoteInstance);
|
||||
if( tagTimelines != null && tagTimelines.size() > 0){
|
||||
TagTimeline tagTimeline = tagTimelines.get(0);
|
||||
boolean isArt = tagTimeline.isART();
|
||||
if( isArt)
|
||||
apiResponse = api.getCustomArtTimelineSinceId(false, remoteInstance, since_id, tagTimelines.get(0).getAny(), tagTimelines.get(0).getAll(), tagTimelines.get(0).getNone());
|
||||
else
|
||||
apiResponse = api.getPublicTimelineTagSinceId(remoteInstance, false, since_id, tagTimelines.get(0).getAny(), tagTimelines.get(0).getAll(), tagTimelines.get(0).getNone());
|
||||
}else{
|
||||
apiResponse = api.getPublicTimelineTag(remoteInstance, false, since_id, tagTimelines.get(0).getAny(), tagTimelines.get(0).getAll(), tagTimelines.get(0).getNone());
|
||||
}
|
||||
}else if (type == RetrieveFeedsAsyncTask.Type.ART)
|
||||
apiResponse = api.getArtTimelineSinceId( false, since_id, null, null, null);
|
||||
if (apiResponse != null) {
|
||||
if( type != RetrieveFeedsAsyncTask.Type.CONVERSATION)
|
||||
tempStatus = apiResponse.getStatuses();
|
||||
|
|
|
@ -16,8 +16,8 @@ package fr.gouv.etalab.mastodon.asynctasks;
|
|||
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import fr.gouv.etalab.mastodon.activities.MainActivity;
|
||||
|
@ -37,8 +37,8 @@ public class RetrieveMissingNotificationsAsyncTask extends AsyncTask<Void, Void,
|
|||
|
||||
private String since_id;
|
||||
private OnRetrieveMissingNotificationsInterface listener;
|
||||
private List<Notification> notifications = new ArrayList<>();
|
||||
private WeakReference<Context> contextReference;
|
||||
private List<Notification> notifications;
|
||||
|
||||
public RetrieveMissingNotificationsAsyncTask(Context context, String since_id, OnRetrieveMissingNotificationsInterface onRetrieveMissingNotifications){
|
||||
this.contextReference = new WeakReference<>(context);
|
||||
|
@ -49,20 +49,10 @@ public class RetrieveMissingNotificationsAsyncTask extends AsyncTask<Void, Void,
|
|||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
int loopInc = 0;
|
||||
API api = new API(this.contextReference.get());
|
||||
List<Notification> tempNotifications;
|
||||
while (loopInc < 10){
|
||||
APIResponse apiResponse = api.getNotificationsSince(since_id, 40, false);
|
||||
String max_id = apiResponse.getMax_id();
|
||||
since_id = apiResponse.getSince_id();
|
||||
tempNotifications = apiResponse.getNotifications();
|
||||
if( notifications != null && tempNotifications != null)
|
||||
notifications.addAll(0, tempNotifications);
|
||||
loopInc++;
|
||||
if( max_id == null || max_id.equals(since_id))
|
||||
break;
|
||||
}
|
||||
APIResponse apiResponse = api.getNotificationsSince(since_id, 40, false);
|
||||
since_id = apiResponse.getSince_id();
|
||||
notifications = apiResponse.getNotifications();
|
||||
if( notifications != null && notifications.size() > 0) {
|
||||
MainActivity.lastNotificationId = notifications.get(0).getId();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/* Copyright 2019 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Mastalab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Mastalab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
package fr.gouv.etalab.mastodon.asynctasks;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import fr.gouv.etalab.mastodon.client.APIResponse;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
import fr.gouv.etalab.mastodon.client.PeertubeAPI;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrievePeertubeInterface;
|
||||
import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
|
||||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||
|
||||
|
||||
/**
|
||||
* Created by Thomas on 07/01/2019.
|
||||
* Retrieves peertube Channels
|
||||
*/
|
||||
|
||||
public class RetrievePeertubeChannelsAsyncTask extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
|
||||
|
||||
private APIResponse apiResponse;
|
||||
private OnRetrievePeertubeInterface listener;
|
||||
private WeakReference<Context> contextReference;
|
||||
|
||||
|
||||
|
||||
|
||||
public RetrievePeertubeChannelsAsyncTask(Context context, OnRetrievePeertubeInterface onRetrievePeertubeInterface){
|
||||
this.contextReference = new WeakReference<>(context);
|
||||
this.listener = onRetrievePeertubeInterface;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
PeertubeAPI peertubeAPI = new PeertubeAPI(this.contextReference.get());
|
||||
SQLiteDatabase db = Sqlite.getInstance(contextReference.get(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
SharedPreferences sharedpreferences = contextReference.get().getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
String token = sharedpreferences.getString(Helper.PREF_KEY_OAUTH_TOKEN, null);
|
||||
Account account = new AccountDAO(contextReference.get(), db).getAccountByToken(token);
|
||||
apiResponse = peertubeAPI.getPeertubeChannel(account.getUsername());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void result) {
|
||||
listener.onRetrievePeertubeChannels(apiResponse);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/* Copyright 2019 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Mastalab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Mastalab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
package fr.gouv.etalab.mastodon.asynctasks;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import fr.gouv.etalab.mastodon.client.Entities.PeertubeInformation;
|
||||
import fr.gouv.etalab.mastodon.client.HttpsConnection;
|
||||
import fr.gouv.etalab.mastodon.client.PeertubeAPI;
|
||||
|
||||
|
||||
/**
|
||||
* Created by Thomas on 07/01/2019.
|
||||
* Retrieves peertube informations
|
||||
*/
|
||||
|
||||
public class RetrievePeertubeInformationAsyncTask extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
|
||||
|
||||
private WeakReference<Context> contextReference;
|
||||
public static PeertubeInformation peertubeInformation;
|
||||
|
||||
|
||||
|
||||
public RetrievePeertubeInformationAsyncTask(Context context){
|
||||
this.contextReference = new WeakReference<>(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
PeertubeAPI peertubeAPI = new PeertubeAPI(this.contextReference.get());
|
||||
try {
|
||||
peertubeInformation = peertubeAPI.getPeertubeInformation();
|
||||
} catch (HttpsConnection.HttpsConnectionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void result) {
|
||||
}
|
||||
}
|
|
@ -13,11 +13,18 @@
|
|||
* You should have received a copy of the GNU General Public License along with Mastalab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
package fr.gouv.etalab.mastodon.asynctasks;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import fr.gouv.etalab.mastodon.activities.MainActivity;
|
||||
import fr.gouv.etalab.mastodon.client.API;
|
||||
import fr.gouv.etalab.mastodon.client.APIResponse;
|
||||
import fr.gouv.etalab.mastodon.client.PeertubeAPI;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrievePeertubeInterface;
|
||||
|
||||
|
||||
|
@ -49,8 +56,20 @@ public class RetrievePeertubeSingleAsyncTask extends AsyncTask<Void, Void, Void>
|
|||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
API api = new API(this.contextReference.get());
|
||||
apiResponse = api.getSinglePeertube(this.instanceName, videoId);
|
||||
if( MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON) {
|
||||
API api = new API(this.contextReference.get());
|
||||
apiResponse = api.getSinglePeertube(this.instanceName, videoId);
|
||||
}else if( MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE){
|
||||
PeertubeAPI peertubeAPI = new PeertubeAPI(this.contextReference.get());
|
||||
SharedPreferences sharedpreferences = contextReference.get().getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
String token = sharedpreferences.getString(Helper.PREF_KEY_OAUTH_TOKEN, null);
|
||||
apiResponse = peertubeAPI.getSinglePeertube(this.instanceName, videoId, token);
|
||||
if (apiResponse.getPeertubes() != null && apiResponse.getPeertubes().size() > 0 && apiResponse.getPeertubes().get(0) != null) {
|
||||
String rate = new PeertubeAPI(this.contextReference.get()).getRating(videoId);
|
||||
if( rate != null)
|
||||
apiResponse.getPeertubes().get(0).setMyRating(rate);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,9 +16,14 @@ package fr.gouv.etalab.mastodon.asynctasks;
|
|||
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import fr.gouv.etalab.mastodon.activities.MainActivity;
|
||||
import fr.gouv.etalab.mastodon.client.API;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Error;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Relationship;
|
||||
import fr.gouv.etalab.mastodon.client.PeertubeAPI;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveRelationshipInterface;
|
||||
|
||||
/**
|
||||
|
@ -32,7 +37,7 @@ public class RetrieveRelationshipAsyncTask extends AsyncTask<Void, Void, Void> {
|
|||
private String accountId;
|
||||
private Relationship relationship;
|
||||
private OnRetrieveRelationshipInterface listener;
|
||||
private API api;
|
||||
private Error error;
|
||||
private WeakReference<Context> contextReference;
|
||||
|
||||
public RetrieveRelationshipAsyncTask(Context context, String accountId, OnRetrieveRelationshipInterface onRetrieveRelationshipInterface){
|
||||
|
@ -43,14 +48,23 @@ public class RetrieveRelationshipAsyncTask extends AsyncTask<Void, Void, Void> {
|
|||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
api = new API(this.contextReference.get());
|
||||
relationship = api.getRelationship(accountId);
|
||||
|
||||
if(MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON) {
|
||||
API api = new API(this.contextReference.get());
|
||||
relationship = api.getRelationship(accountId);
|
||||
error = api.getError();
|
||||
}else {
|
||||
PeertubeAPI api = new PeertubeAPI(this.contextReference.get());
|
||||
relationship = new Relationship();
|
||||
relationship.setFollowing(api.isFollowing(accountId));
|
||||
error = api.getError();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void result) {
|
||||
listener.onRetrieveRelationship(relationship, api.getError());
|
||||
listener.onRetrieveRelationship(relationship, error);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,13 +24,16 @@ import android.os.AsyncTask;
|
|||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.HashMap;
|
||||
|
||||
import fr.gouv.etalab.mastodon.activities.MainActivity;
|
||||
import fr.gouv.etalab.mastodon.client.API;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
import fr.gouv.etalab.mastodon.client.HttpsConnection;
|
||||
import fr.gouv.etalab.mastodon.client.PeertubeAPI;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||
import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
|
||||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||
|
||||
/**
|
||||
* Created by Thomas on 23/04/2017.
|
||||
|
@ -39,19 +42,49 @@ import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
|
|||
|
||||
public class UpdateAccountInfoAsyncTask extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
private String token;
|
||||
private String token, client_id, client_secret, refresh_token;
|
||||
private String instance;
|
||||
private WeakReference<Context> contextReference;
|
||||
private SOCIAL social;
|
||||
|
||||
public UpdateAccountInfoAsyncTask(Context context, String token, String instance){
|
||||
public enum SOCIAL{
|
||||
MASTODON,
|
||||
PEERTUBE,
|
||||
PIXELFED
|
||||
}
|
||||
public UpdateAccountInfoAsyncTask(Context context, String token, String client_id, String client_secret, String refresh_token, String instance, SOCIAL social){
|
||||
this.contextReference = new WeakReference<>(context);
|
||||
this.token = token;
|
||||
this.instance = instance;
|
||||
this.social = social;
|
||||
this.client_id = client_id;
|
||||
this.client_secret = client_secret;
|
||||
this.refresh_token = refresh_token;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
Account account = new API(this.contextReference.get(), instance, null).verifyCredentials();
|
||||
Account account = null;
|
||||
if( social == SOCIAL.MASTODON) {
|
||||
account = new API(this.contextReference.get(), instance, null).verifyCredentials();
|
||||
account.setSocial("MASTODON");
|
||||
}else if( social == SOCIAL.PEERTUBE) {
|
||||
try {
|
||||
account = new PeertubeAPI(this.contextReference.get(), instance, null).verifyCredentials();
|
||||
account.setSocial("PEERTUBE");
|
||||
}catch (HttpsConnection.HttpsConnectionException exception){
|
||||
if(exception.getStatusCode() == 401){
|
||||
HashMap<String, String> values = new PeertubeAPI(this.contextReference.get(), instance, null).refreshToken(client_id, client_secret, refresh_token);
|
||||
if( values.get("access_token") != null)
|
||||
this.token = values.get("access_token");
|
||||
if( values.get("refresh_token") != null)
|
||||
this.refresh_token = values.get("refresh_token");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( account == null)
|
||||
return null;
|
||||
try {
|
||||
//At the state the instance can be encoded
|
||||
instance = URLDecoder.decode(instance, "utf-8");
|
||||
|
@ -60,9 +93,12 @@ public class UpdateAccountInfoAsyncTask extends AsyncTask<Void, Void, Void> {
|
|||
if( token == null) {
|
||||
token = sharedpreferences.getString(Helper.PREF_KEY_OAUTH_TOKEN, null);
|
||||
}
|
||||
|
||||
account.setToken(token);
|
||||
account.setClient_id(client_id);
|
||||
account.setClient_secret(client_secret);
|
||||
account.setRefresh_token(refresh_token);
|
||||
account.setInstance(instance);
|
||||
|
||||
SQLiteDatabase db = Sqlite.getInstance(this.contextReference.get(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
boolean userExists = new AccountDAO(this.contextReference.get(), db).userExist(account);
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
|
|
|
@ -20,11 +20,14 @@ import android.database.sqlite.SQLiteDatabase;
|
|||
import android.os.AsyncTask;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.HashMap;
|
||||
|
||||
import fr.gouv.etalab.mastodon.client.API;
|
||||
import fr.gouv.etalab.mastodon.client.APIResponse;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Emojis;
|
||||
import fr.gouv.etalab.mastodon.client.HttpsConnection;
|
||||
import fr.gouv.etalab.mastodon.client.PeertubeAPI;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnUpdateAccountInfoInterface;
|
||||
import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
|
||||
|
@ -41,10 +44,12 @@ public class UpdateAccountInfoByIDAsyncTask extends AsyncTask<Void, Void, Void>
|
|||
|
||||
private OnUpdateAccountInfoInterface listener;
|
||||
private WeakReference<Context> contextReference;
|
||||
private UpdateAccountInfoAsyncTask.SOCIAL social;
|
||||
|
||||
public UpdateAccountInfoByIDAsyncTask(Context context, OnUpdateAccountInfoInterface onUpdateAccountInfoInterface){
|
||||
public UpdateAccountInfoByIDAsyncTask(Context context, UpdateAccountInfoAsyncTask.SOCIAL social, OnUpdateAccountInfoInterface onUpdateAccountInfoInterface){
|
||||
this.contextReference = new WeakReference<>(context);
|
||||
this.listener = onUpdateAccountInfoInterface;
|
||||
this.social = social;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -52,7 +57,35 @@ public class UpdateAccountInfoByIDAsyncTask extends AsyncTask<Void, Void, Void>
|
|||
|
||||
SharedPreferences sharedpreferences = this.contextReference.get().getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
Account account = new API(this.contextReference.get()).getAccount(userId);
|
||||
Account account = null;
|
||||
if( social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON)
|
||||
account = new API(this.contextReference.get()).getAccount(userId);
|
||||
else if( social == UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE) {
|
||||
|
||||
try {
|
||||
account = new PeertubeAPI(this.contextReference.get()).verifyCredentials();
|
||||
account.setSocial("PEERTUBE");
|
||||
}catch (HttpsConnection.HttpsConnectionException exception){
|
||||
if(exception.getStatusCode() == 401){
|
||||
SQLiteDatabase db = Sqlite.getInstance(this.contextReference.get(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
String token = sharedpreferences.getString(Helper.PREF_KEY_OAUTH_TOKEN, null);
|
||||
account = new AccountDAO(this.contextReference.get(), db).getAccountByToken(token);
|
||||
HashMap<String, String> values = new PeertubeAPI(this.contextReference.get()).refreshToken(account.getClient_id(), account.getClient_secret(), account.getRefresh_token());
|
||||
if( values != null) {
|
||||
String newtoken = values.get("access_token");
|
||||
String refresh_token = values.get("refresh_token");
|
||||
if (newtoken != null)
|
||||
account.setToken(newtoken);
|
||||
if (refresh_token != null)
|
||||
account.setRefresh_token(refresh_token);
|
||||
new AccountDAO(this.contextReference.get(), db).updateAccount(account);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if( account == null)
|
||||
return null;
|
||||
account.setInstance(Helper.getLiveInstance(contextReference.get()));
|
||||
SQLiteDatabase db = Sqlite.getInstance(this.contextReference.get(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
boolean userExists = new AccountDAO(this.contextReference.get(), db).userExist(account);
|
||||
|
@ -64,15 +97,18 @@ public class UpdateAccountInfoByIDAsyncTask extends AsyncTask<Void, Void, Void>
|
|||
new AccountDAO(this.contextReference.get(), db).updateAccount(account);
|
||||
}
|
||||
}
|
||||
try {
|
||||
APIResponse response = new API(contextReference.get()).getCustomEmoji();
|
||||
if( response != null && response.getEmojis() != null && response.getEmojis().size() > 0){
|
||||
new CustomEmojiDAO(contextReference.get(), db).removeAll();
|
||||
for(Emojis emojis: response.getEmojis()){
|
||||
new CustomEmojiDAO(contextReference.get(), db).insertEmoji(emojis);
|
||||
if( social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON) {
|
||||
try {
|
||||
APIResponse response = new API(contextReference.get()).getCustomEmoji();
|
||||
if (response != null && response.getEmojis() != null && response.getEmojis().size() > 0) {
|
||||
new CustomEmojiDAO(contextReference.get(), db).removeAll();
|
||||
for (Emojis emojis : response.getEmojis()) {
|
||||
new CustomEmojiDAO(contextReference.get(), db).insertEmoji(emojis);
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}catch (Exception ignored){}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,11 @@ package fr.gouv.etalab.mastodon.client;
|
|||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
|
@ -53,9 +57,13 @@ import fr.gouv.etalab.mastodon.client.Entities.Notification;
|
|||
import fr.gouv.etalab.mastodon.client.Entities.Peertube;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Relationship;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Results;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Schedule;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Status;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.StoredStatus;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Tag;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
|
||||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -107,7 +115,14 @@ public class API {
|
|||
UNENDORSE,
|
||||
SHOW_BOOST,
|
||||
HIDE_BOOST,
|
||||
BLOCK_DOMAIN
|
||||
BLOCK_DOMAIN,
|
||||
RATEVIDEO,
|
||||
PEERTUBECOMMENT,
|
||||
PEERTUBEREPLY,
|
||||
PEERTUBEDELETECOMMENT,
|
||||
PEERTUBEDELETEVIDEO,
|
||||
UPDATESERVERSCHEDULE,
|
||||
DELETESCHEDULED
|
||||
|
||||
}
|
||||
public enum accountPrivacy {
|
||||
|
@ -120,8 +135,19 @@ public class API {
|
|||
tootPerPage = sharedpreferences.getInt(Helper.SET_TOOTS_PER_PAGE, 40);
|
||||
accountPerPage = sharedpreferences.getInt(Helper.SET_ACCOUNTS_PER_PAGE, 40);
|
||||
notificationPerPage = sharedpreferences.getInt(Helper.SET_NOTIFICATIONS_PER_PAGE, 15);
|
||||
this.instance = Helper.getLiveInstance(context);
|
||||
this.prefKeyOauthTokenT = sharedpreferences.getString(Helper.PREF_KEY_OAUTH_TOKEN, null);
|
||||
if( Helper.getLiveInstance(context) != null)
|
||||
this.instance = Helper.getLiveInstance(context);
|
||||
else {
|
||||
SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
Account account = new AccountDAO(context, db).getAccountByToken(this.prefKeyOauthTokenT);
|
||||
if( account == null) {
|
||||
APIError = new Error();
|
||||
APIError.setError(context.getString(R.string.toast_error));
|
||||
return;
|
||||
}
|
||||
this.instance = account.getInstance().trim();
|
||||
}
|
||||
apiResponse = new APIResponse();
|
||||
APIError = null;
|
||||
}
|
||||
|
@ -793,6 +819,38 @@ public class API {
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves public pixelfed timeline for the account *synchronously*
|
||||
* @param max_id String id max
|
||||
* @return APIResponse
|
||||
*/
|
||||
public APIResponse getPixelfedTimeline(String remoteInstance, String max_id) {
|
||||
|
||||
HashMap<String, String> params = new HashMap<>();
|
||||
if (max_id != null)
|
||||
params.put("page", max_id);
|
||||
statuses = new ArrayList<>();
|
||||
try {
|
||||
HttpsConnection httpsConnection = new HttpsConnection(context);
|
||||
String response = httpsConnection.get(getAbsoluteUrlRemote(remoteInstance, "/timelines/public/"), 60, params, prefKeyOauthTokenT);
|
||||
apiResponse.setSince_id(httpsConnection.getSince_id());
|
||||
apiResponse.setMax_id(httpsConnection.getMax_id());
|
||||
statuses = parseStatuses(context, new JSONArray(response));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (KeyManagementException e) {
|
||||
e.printStackTrace();
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
} catch (HttpsConnection.HttpsConnectionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
apiResponse.setStatuses(statuses);
|
||||
return apiResponse;
|
||||
}
|
||||
/**
|
||||
* Retrieves Peertube videos from an instance *synchronously*
|
||||
* @return APIResponse
|
||||
|
@ -997,6 +1055,50 @@ public class API {
|
|||
apiResponse.setHowToVideos(howToVideos);
|
||||
return apiResponse;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves Peertube videos from an instance *synchronously*
|
||||
* @return APIResponse
|
||||
*/
|
||||
public APIResponse getMisskey(String instance, String max_id) {
|
||||
|
||||
JSONObject params = new JSONObject();
|
||||
try {
|
||||
params.put("file", false);
|
||||
if( max_id != null)
|
||||
params.put("untilId",max_id);
|
||||
params.put("local",true);
|
||||
params.put("poll",false);
|
||||
params.put("renote",false);
|
||||
params.put("reply",false);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
statuses = new ArrayList<>();
|
||||
HttpsConnection httpsConnection = new HttpsConnection(context);
|
||||
String response = httpsConnection.postMisskey("https://"+instance+"/api/notes", 60, params, null);
|
||||
statuses = parseNotes(context, instance, new JSONArray(response));
|
||||
if( statuses != null && statuses.size() > 0){
|
||||
apiResponse.setSince_id(statuses.get(0).getId());
|
||||
apiResponse.setMax_id(statuses.get(statuses.size() -1).getId());
|
||||
}
|
||||
} catch (HttpsConnection.HttpsConnectionException e) {
|
||||
setError(e.getStatusCode(), e);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (KeyManagementException e) {
|
||||
e.printStackTrace();
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
apiResponse.setStatuses(statuses);
|
||||
return apiResponse;
|
||||
}
|
||||
/**
|
||||
* Retrieves public timeline for the account *synchronously*
|
||||
* @param local boolean only local timeline
|
||||
|
@ -1085,13 +1187,77 @@ public class API {
|
|||
}
|
||||
|
||||
|
||||
|
||||
public APIResponse getCustomArtTimeline(boolean local, String tag, String max_id){
|
||||
return getArtTimeline(local, tag, max_id);
|
||||
/**
|
||||
* Retrieves discover timeline for the account *synchronously*
|
||||
* @param local boolean only local timeline
|
||||
* @param max_id String id max
|
||||
* @return APIResponse
|
||||
*/
|
||||
public APIResponse getDiscoverTimeline(boolean local, String max_id){
|
||||
return getDiscoverTimeline(local, max_id, null, tootPerPage);
|
||||
}
|
||||
|
||||
public APIResponse getArtTimeline(boolean local, String max_id){
|
||||
return getArtTimeline(local, null, max_id);
|
||||
|
||||
/**
|
||||
* Retrieves discover timeline for the account *synchronously*
|
||||
* @param local boolean only local timeline
|
||||
* @param max_id String id max
|
||||
* @param since_id String since the id
|
||||
* @param limit int limit - max value 40
|
||||
* @return APIResponse
|
||||
*/
|
||||
private APIResponse getDiscoverTimeline(boolean local, String max_id, String since_id, int limit){
|
||||
|
||||
HashMap<String, String> params = new HashMap<>();
|
||||
if( local)
|
||||
params.put("local", Boolean.toString(true));
|
||||
if( max_id != null )
|
||||
params.put("max_id", max_id);
|
||||
if( since_id != null )
|
||||
params.put("since_id", since_id);
|
||||
if( 0 > limit || limit > 40)
|
||||
limit = 40;
|
||||
params.put("limit",String.valueOf(limit));
|
||||
statuses = new ArrayList<>();
|
||||
try {
|
||||
HttpsConnection httpsConnection = new HttpsConnection(context);
|
||||
String url;
|
||||
url = getAbsoluteUr2l("/discover/posts");
|
||||
String response = httpsConnection.get(url, 60, params, prefKeyOauthTokenT);
|
||||
apiResponse.setSince_id(httpsConnection.getSince_id());
|
||||
apiResponse.setMax_id(httpsConnection.getMax_id());
|
||||
statuses = parseStatuses(context, new JSONArray(response));
|
||||
} catch (HttpsConnection.HttpsConnectionException e) {
|
||||
setError(e.getStatusCode(), e);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (KeyManagementException e) {
|
||||
e.printStackTrace();
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
apiResponse.setStatuses(statuses);
|
||||
return apiResponse;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public APIResponse getCustomArtTimeline(boolean local, String tag, String max_id, List<String> any, List<String> all, List<String> none){
|
||||
return getArtTimeline(local, tag, max_id, null, any, all, none);
|
||||
}
|
||||
|
||||
public APIResponse getArtTimeline(boolean local, String max_id, List<String> any, List<String> all, List<String> none){
|
||||
return getArtTimeline(local, null, max_id, null, any, all, none);
|
||||
}
|
||||
|
||||
public APIResponse getCustomArtTimelineSinceId(boolean local, String tag, String since_id, List<String> any, List<String> all, List<String> none){
|
||||
return getArtTimeline(local, tag, null, since_id, any, all, none);
|
||||
}
|
||||
|
||||
public APIResponse getArtTimelineSinceId(boolean local, String since_id, List<String> any, List<String> all, List<String> none){
|
||||
return getArtTimeline(local, null, null, since_id, any, all, none);
|
||||
}
|
||||
/**
|
||||
* Retrieves art timeline
|
||||
|
@ -1099,11 +1265,10 @@ public class API {
|
|||
* @param max_id String id max
|
||||
* @return APIResponse
|
||||
*/
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
private APIResponse getArtTimeline(boolean local, String tag, String max_id){
|
||||
private APIResponse getArtTimeline(boolean local, String tag, String max_id, String since_id, List<String> any, List<String> all, List<String> none){
|
||||
if( tag == null)
|
||||
tag = "mastoart";
|
||||
APIResponse apiResponse = getPublicTimelineTag(tag, local, true, max_id, null, tootPerPage);
|
||||
APIResponse apiResponse = getPublicTimelineTag(tag, local, true, max_id, since_id, tootPerPage, any, all, none);
|
||||
APIResponse apiResponseReply = new APIResponse();
|
||||
if( apiResponse != null){
|
||||
apiResponseReply.setMax_id(apiResponse.getMax_id());
|
||||
|
@ -1112,19 +1277,13 @@ public class API {
|
|||
if( apiResponse.getStatuses() != null && apiResponse.getStatuses().size() > 0){
|
||||
for( Status status: apiResponse.getStatuses()){
|
||||
if( status.getMedia_attachments() != null ) {
|
||||
if (status.getMedia_attachments().size() > 1) {
|
||||
String statusSerialized = Helper.statusToStringStorage(status);
|
||||
for (Attachment attachment : status.getMedia_attachments()) {
|
||||
ArrayList<Attachment> attachments = new ArrayList<>();
|
||||
attachments.add(attachment);
|
||||
Status newStatus = Helper.restoreStatusFromString(statusSerialized);
|
||||
if (newStatus == null)
|
||||
break;
|
||||
newStatus.setMedia_attachments(attachments);
|
||||
apiResponseReply.getStatuses().add(newStatus);
|
||||
}
|
||||
} else if (status.getMedia_attachments().size() == 1) {
|
||||
apiResponseReply.getStatuses().add(status);
|
||||
String statusSerialized = Helper.statusToStringStorage(status);
|
||||
for (Attachment attachment : status.getMedia_attachments()) {
|
||||
Status newStatus = Helper.restoreStatusFromString(statusSerialized);
|
||||
if (newStatus == null)
|
||||
break;
|
||||
newStatus.setArt_attachment(attachment);
|
||||
apiResponseReply.getStatuses().add(newStatus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1141,8 +1300,20 @@ public class API {
|
|||
* @return APIResponse
|
||||
*/
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
public APIResponse getPublicTimelineTag(String tag, boolean local, String max_id){
|
||||
return getPublicTimelineTag(tag, local, false, max_id, null, tootPerPage);
|
||||
public APIResponse getPublicTimelineTag(String tag, boolean local, String max_id, List<String> any, List<String> all, List<String> none){
|
||||
return getPublicTimelineTag(tag, local, false, max_id, null, tootPerPage, any, all, none);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves public tag timeline *synchronously*
|
||||
* @param tag String
|
||||
* @param local boolean only local timeline
|
||||
* @param since_id String since id
|
||||
* @return APIResponse
|
||||
*/
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
public APIResponse getPublicTimelineTagSinceId(String tag, boolean local, String since_id, List<String> any, List<String> all, List<String> none){
|
||||
return getPublicTimelineTag(tag, local, false, null, since_id, tootPerPage, any, all, none);
|
||||
}
|
||||
/**
|
||||
* Retrieves public tag timeline *synchronously*
|
||||
|
@ -1154,7 +1325,7 @@ public class API {
|
|||
* @return APIResponse
|
||||
*/
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
private APIResponse getPublicTimelineTag(String tag, boolean local, boolean onlymedia, String max_id, String since_id, int limit){
|
||||
private APIResponse getPublicTimelineTag(String tag, boolean local, boolean onlymedia, String max_id, String since_id, int limit, List<String> any, List<String> all, List<String> none){
|
||||
|
||||
HashMap<String, String> params = new HashMap<>();
|
||||
if( local)
|
||||
|
@ -1165,6 +1336,30 @@ public class API {
|
|||
params.put("since_id", since_id);
|
||||
if( 0 > limit || limit > 40)
|
||||
limit = 40;
|
||||
if( onlymedia)
|
||||
params.put("only_media", Boolean.toString(true));
|
||||
|
||||
if( any != null && any.size() > 0) {
|
||||
StringBuilder parameters = new StringBuilder();
|
||||
for (String a : any)
|
||||
parameters.append("any[]=").append(a).append("&");
|
||||
parameters = new StringBuilder(parameters.substring(0, parameters.length() - 1).substring(6));
|
||||
params.put("any[]", parameters.toString());
|
||||
}
|
||||
if( all != null && all.size() > 0) {
|
||||
StringBuilder parameters = new StringBuilder();
|
||||
for (String a : all)
|
||||
parameters.append("all[]=").append(a).append("&");
|
||||
parameters = new StringBuilder(parameters.substring(0, parameters.length() - 1).substring(6));
|
||||
params.put("all[]", parameters.toString());
|
||||
}
|
||||
if( none != null && none.size() > 0) {
|
||||
StringBuilder parameters = new StringBuilder();
|
||||
for (String a : none)
|
||||
parameters.append("none[]=").append(a).append("&");
|
||||
parameters = new StringBuilder(parameters.substring(0, parameters.length() - 1).substring(7));
|
||||
params.put("none[]", parameters.toString());
|
||||
}
|
||||
params.put("limit",String.valueOf(limit));
|
||||
statuses = new ArrayList<>();
|
||||
if( tag == null)
|
||||
|
@ -1588,6 +1783,8 @@ public class API {
|
|||
} catch (UnsupportedEncodingException e) {
|
||||
params.put("status", status.getContent());
|
||||
}
|
||||
if( status.getScheduled_at() != null)
|
||||
params.put("scheduled_at", status.getScheduled_at());
|
||||
if( status.getIn_reply_to_id() != null)
|
||||
params.put("in_reply_to_id", status.getIn_reply_to_id());
|
||||
if( status.getMedia_attachments() != null && status.getMedia_attachments().size() > 0 ) {
|
||||
|
@ -1606,16 +1803,26 @@ public class API {
|
|||
params.put("spoiler_text", status.getSpoiler_text());
|
||||
}
|
||||
params.put("visibility", status.getVisibility());
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
if(statusAction != StatusAction.UNSTATUS ) {
|
||||
|
||||
try {
|
||||
HttpsConnection httpsConnection = new HttpsConnection(context);
|
||||
httpsConnection.post(getAbsoluteUrl(action), 60, params, prefKeyOauthTokenT);
|
||||
String resp = httpsConnection.post(getAbsoluteUrl(action), 60, params, prefKeyOauthTokenT);
|
||||
actionCode = httpsConnection.getActionCode();
|
||||
if( statusAction == StatusAction.REBLOG || statusAction == StatusAction.UNREBLOG || statusAction == StatusAction.FAVOURITE || statusAction == StatusAction.UNFAVOURITE) {
|
||||
Bundle b = new Bundle();
|
||||
try {
|
||||
Status status1 = parseStatuses(context, new JSONObject(resp));
|
||||
b.putParcelable("status", status1);
|
||||
b.putSerializable("action", statusAction);
|
||||
} catch (JSONException ignored) {}
|
||||
Intent intentBC = new Intent(Helper.RECEIVE_ACTION);
|
||||
intentBC.putExtras(b);
|
||||
LocalBroadcastManager.getInstance(context).sendBroadcast(intentBC);
|
||||
}
|
||||
} catch (HttpsConnection.HttpsConnectionException e) {
|
||||
setError(e.getStatusCode(), e);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
|
@ -1644,6 +1851,88 @@ public class API {
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* scheduled action for a status
|
||||
* @param status Status object related to the status
|
||||
* @return APIResponse
|
||||
*/
|
||||
public APIResponse scheduledAction(String call, Status status, String max_id, String targetedId){
|
||||
|
||||
HashMap<String, String> params = new HashMap<>();
|
||||
if( call.equals("PUT")){
|
||||
if( status.getScheduled_at() != null)
|
||||
params.put("scheduled_at", status.getScheduled_at());
|
||||
}else if(call.equals("GET")){
|
||||
if( max_id != null )
|
||||
params.put("max_id", max_id);
|
||||
}
|
||||
List<StoredStatus> storedStatus = new ArrayList<>();
|
||||
try {
|
||||
HttpsConnection httpsConnection = new HttpsConnection(context);
|
||||
String response = null;
|
||||
int responseCode = -1;
|
||||
if( call.equals("GET"))
|
||||
response = httpsConnection.get(getAbsoluteUrl("/scheduled_statuses/"), 60, null, prefKeyOauthTokenT);
|
||||
else if( call.equals("PUT"))
|
||||
response = httpsConnection.put(getAbsoluteUrl(String.format("/scheduled_statuses/%s", targetedId)), 60, params, prefKeyOauthTokenT);
|
||||
else if( call.equals("DELETE"))
|
||||
responseCode = httpsConnection.delete(getAbsoluteUrl(String.format("/scheduled_statuses/%s",targetedId)), 60, null, prefKeyOauthTokenT);
|
||||
if(call.equals("GET")) {
|
||||
apiResponse.setSince_id(httpsConnection.getSince_id());
|
||||
apiResponse.setMax_id(httpsConnection.getMax_id());
|
||||
}
|
||||
if (response != null && call.equals("PUT")) {
|
||||
Schedule schedule = parseSimpleSchedule(context, new JSONObject(response));
|
||||
StoredStatus st = new StoredStatus();
|
||||
st.setCreation_date(status.getCreated_at());
|
||||
st.setId(-1);
|
||||
st.setJobId(-1);
|
||||
st.setScheduled_date(schedule.getScheduled_at());
|
||||
st.setStatusReply(null);
|
||||
st.setSent_date(null);
|
||||
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
st.setUserId(userId);
|
||||
st.setStatus(schedule.getStatus());
|
||||
storedStatus.add(st);
|
||||
}else if (response != null && call.equals("GET")) {
|
||||
List<Schedule> scheduleList = parseSchedule(context, new JSONArray(response));
|
||||
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
for(Schedule schedule: scheduleList){
|
||||
StoredStatus st = new StoredStatus();
|
||||
st.setCreation_date(null);
|
||||
st.setScheduledServerdId(schedule.getId());
|
||||
st.setJobId(-1);
|
||||
st.setScheduled_date(schedule.getScheduled_at());
|
||||
st.setStatusReply(null);
|
||||
st.setSent_date(null);
|
||||
st.setUserId(userId);
|
||||
st.setStatus(schedule.getStatus());
|
||||
storedStatus.add(st);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (HttpsConnection.HttpsConnectionException e) {
|
||||
setError(e.getStatusCode(), e);
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (KeyManagementException e) {
|
||||
e.printStackTrace();
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
apiResponse.setStoredStatuses(storedStatus);
|
||||
return apiResponse;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Posts a status
|
||||
* @param status Status object related to the status
|
||||
|
@ -1666,6 +1955,8 @@ public class API {
|
|||
parameters = new StringBuilder(parameters.substring(0, parameters.length() - 1).substring(12));
|
||||
params.put("media_ids[]", parameters.toString());
|
||||
}
|
||||
if( status.getScheduled_at() != null)
|
||||
params.put("scheduled_at", status.getScheduled_at());
|
||||
if( status.isSensitive())
|
||||
params.put("sensitive", Boolean.toString(status.isSensitive()));
|
||||
if( status.getSpoiler_text() != null)
|
||||
|
@ -1676,7 +1967,6 @@ public class API {
|
|||
}
|
||||
params.put("visibility", status.getVisibility());
|
||||
statuses = new ArrayList<>();
|
||||
|
||||
try {
|
||||
HttpsConnection httpsConnection = new HttpsConnection(context);
|
||||
String response = httpsConnection.post(getAbsoluteUrl("/statuses"), 60, params, prefKeyOauthTokenT);
|
||||
|
@ -1833,6 +2123,7 @@ public class API {
|
|||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Changes media description
|
||||
* @param mediaId String
|
||||
|
@ -1869,16 +2160,12 @@ public class API {
|
|||
* Retrieves Accounts and feeds when searching *synchronously*
|
||||
*
|
||||
* @param query String search
|
||||
* @return List<Account>
|
||||
* @return Results
|
||||
*/
|
||||
public Results search(String query) {
|
||||
|
||||
HashMap<String, String> params = new HashMap<>();
|
||||
try {
|
||||
params.put("q", URLEncoder.encode(query, "UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
params.put("q", query);
|
||||
}
|
||||
params.put("q", query);
|
||||
try {
|
||||
HttpsConnection httpsConnection = new HttpsConnection(context);
|
||||
String response = httpsConnection.get(getAbsoluteUrl("/search"), 60, params, prefKeyOauthTokenT);
|
||||
|
@ -2889,12 +3176,68 @@ public class API {
|
|||
}catch (JSONException ignored) {}
|
||||
return conversation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse json response for several scheduled toots
|
||||
* @param jsonObject JSONObject
|
||||
* @return List<Status>
|
||||
*/
|
||||
private static Schedule parseSimpleSchedule(Context context, JSONObject jsonObject){
|
||||
Schedule schedule = new Schedule();
|
||||
try {
|
||||
JSONObject resobj = jsonObject.getJSONObject("params");
|
||||
Status status = parseSchedule(context, resobj);
|
||||
List<Attachment> attachements = parseAttachmentResponse(jsonObject.getJSONArray("media_attachments"));
|
||||
status.setMedia_attachments((ArrayList<Attachment>) attachements);
|
||||
schedule.setStatus(status);
|
||||
schedule.setAttachmentList(attachements);
|
||||
schedule.setId(jsonObject.get("id").toString());
|
||||
schedule.setScheduled_at(Helper.mstStringToDate(context, jsonObject.get("scheduled_at").toString()));
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return schedule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse json response for several scheduled toots
|
||||
* @param jsonArray JSONArray
|
||||
* @return List<Status>
|
||||
*/
|
||||
private static List<Schedule> parseSchedule(Context context, JSONArray jsonArray){
|
||||
|
||||
List<Schedule> schedules = new ArrayList<>();
|
||||
try {
|
||||
int i = 0;
|
||||
while (i < jsonArray.length() ){
|
||||
Schedule schedule = new Schedule();
|
||||
JSONObject resobj = jsonArray.getJSONObject(i).getJSONObject("params");
|
||||
Status status = parseSchedule(context, resobj);
|
||||
List<Attachment> attachements = parseAttachmentResponse(jsonArray.getJSONObject(i).getJSONArray("media_attachments"));
|
||||
status.setMedia_attachments((ArrayList<Attachment>) attachements);
|
||||
schedule.setStatus(status);
|
||||
schedule.setAttachmentList(attachements);
|
||||
schedules.add(schedule);
|
||||
schedule.setId(jsonArray.getJSONObject(i).get("id").toString());
|
||||
schedule.setScheduled_at(Helper.mstStringToDate(context, jsonArray.getJSONObject(i).get("scheduled_at").toString()));
|
||||
i++;
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return schedules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse json response for several status
|
||||
* @param jsonArray JSONArray
|
||||
* @return List<Status>
|
||||
*/
|
||||
public static List<Status> parseStatuses(Context context, JSONArray jsonArray){
|
||||
private static List<Status> parseStatuses(Context context, JSONArray jsonArray){
|
||||
|
||||
List<Status> statuses = new ArrayList<>();
|
||||
try {
|
||||
|
@ -2934,9 +3277,6 @@ public class API {
|
|||
}catch (Exception e){status.setVisibility("public");}
|
||||
status.setLanguage(resobj.get("language").toString());
|
||||
status.setUrl(resobj.get("url").toString());
|
||||
//TODO: replace by the value
|
||||
status.setApplication(new Application());
|
||||
|
||||
//Retrieves attachments
|
||||
JSONArray arrayAttachement = resobj.getJSONArray("media_attachments");
|
||||
ArrayList<Attachment> attachments = new ArrayList<>();
|
||||
|
@ -3020,7 +3360,6 @@ public class API {
|
|||
}
|
||||
status.setApplication(application);
|
||||
|
||||
|
||||
status.setAccount(parseAccountResponse(context, resobj.getJSONObject("account")));
|
||||
status.setContent(resobj.get("content").toString());
|
||||
status.setFavourites_count(Integer.valueOf(resobj.get("favourites_count").toString()));
|
||||
|
@ -3059,6 +3398,170 @@ public class API {
|
|||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse json response for unique schedule
|
||||
* @param resobj JSONObject
|
||||
* @return Status
|
||||
*/
|
||||
@SuppressWarnings("InfiniteRecursion")
|
||||
private static Status parseSchedule(Context context, JSONObject resobj){
|
||||
Status status = new Status();
|
||||
try {
|
||||
status.setIn_reply_to_id(resobj.get("in_reply_to_id").toString());
|
||||
status.setSensitive(Boolean.parseBoolean(resobj.get("sensitive").toString()));
|
||||
status.setSpoiler_text(resobj.get("spoiler_text").toString());
|
||||
try {
|
||||
status.setVisibility(resobj.get("visibility").toString());
|
||||
}catch (Exception e){status.setVisibility("public");}
|
||||
status.setContent(resobj.get("text").toString());
|
||||
} catch (JSONException ignored) {}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse json response for several notes (Misskey)
|
||||
* @param jsonArray JSONArray
|
||||
* @return List<Status>
|
||||
*/
|
||||
public static List<Status> parseNotes(Context context, String instance, JSONArray jsonArray){
|
||||
|
||||
List<Status> statuses = new ArrayList<>();
|
||||
try {
|
||||
int i = 0;
|
||||
while (i < jsonArray.length() ){
|
||||
|
||||
JSONObject resobj = jsonArray.getJSONObject(i);
|
||||
Status status = parseNotes(context, instance, resobj);
|
||||
i++;
|
||||
statuses.add(status);
|
||||
}
|
||||
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return statuses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse json response for unique note (misskey)
|
||||
* @param resobj JSONObject
|
||||
* @return Status
|
||||
*/
|
||||
@SuppressWarnings("InfiniteRecursion")
|
||||
public static Status parseNotes(Context context, String instance, JSONObject resobj){
|
||||
Status status = new Status();
|
||||
try {
|
||||
status.setId(resobj.get("id").toString());
|
||||
status.setUri("https://" + instance + "/notes/" + resobj.get("id").toString());
|
||||
status.setCreated_at(Helper.mstStringToDate(context, resobj.get("createdAt").toString()));
|
||||
status.setIn_reply_to_id(resobj.get("replyId").toString());
|
||||
status.setSensitive(false);
|
||||
if(resobj.get("cw") != null && !resobj.get("cw").toString().equals("null"))
|
||||
status.setSpoiler_text(resobj.get("cw").toString());
|
||||
try {
|
||||
status.setVisibility(resobj.get("visibility").toString());
|
||||
}catch (Exception e){status.setVisibility("public"); e.printStackTrace();}
|
||||
status.setUrl("https://" + instance + "/notes/" + resobj.get("id").toString());
|
||||
//Retrieves attachments
|
||||
JSONArray arrayAttachement = resobj.getJSONArray("media");
|
||||
ArrayList<Attachment> attachments = new ArrayList<>();
|
||||
if( arrayAttachement != null){
|
||||
for(int j = 0 ; j < arrayAttachement.length() ; j++){
|
||||
JSONObject attObj = arrayAttachement.getJSONObject(j);
|
||||
Attachment attachment = new Attachment();
|
||||
attachment.setId(attObj.get("id").toString());
|
||||
attachment.setPreview_url(attObj.get("thumbnailUrl").toString());
|
||||
attachment.setRemote_url(attObj.get("url").toString());
|
||||
if( attObj.get("type").toString().contains("/")){
|
||||
attachment.setType(attObj.get("type").toString().split("/")[0]);
|
||||
}else
|
||||
attachment.setType(attObj.get("type").toString());
|
||||
attachment.setText_url(attObj.get("url").toString());
|
||||
attachment.setUrl(attObj.get("url").toString());
|
||||
if(attObj.get("isSensitive").toString().equals("true")){
|
||||
status.setSensitive(true);
|
||||
}
|
||||
try {
|
||||
attachment.setDescription(attObj.get("comment").toString());
|
||||
}catch (JSONException ignore){ignore.printStackTrace();}
|
||||
attachments.add(attachment);
|
||||
}
|
||||
}
|
||||
try {
|
||||
status.setCard(parseCardResponse(resobj.getJSONObject("card")));
|
||||
}catch (Exception e){status.setCard(null);}
|
||||
|
||||
status.setMedia_attachments(attachments);
|
||||
//Retrieves mentions
|
||||
List<Mention> mentions = new ArrayList<>();
|
||||
|
||||
status.setAccount(parseMisskeyAccountResponse(context, instance, resobj.getJSONObject("user")));
|
||||
status.setContent(resobj.get("text").toString());
|
||||
try{
|
||||
status.setReplies_count(Integer.valueOf(resobj.get("repliesCount").toString()));
|
||||
}catch (Exception e){
|
||||
status.setReplies_count(-1);
|
||||
}
|
||||
try {
|
||||
status.setFavourited(Boolean.valueOf(resobj.get("isFavorited").toString()));
|
||||
}catch (Exception e){
|
||||
status.setFavourited(false);
|
||||
}
|
||||
try{
|
||||
if(resobj.getJSONObject("renoteId") != null && !resobj.getJSONObject("renoteId").toString().equals("null"))
|
||||
status.setReblog(parseStatuses(context, resobj.getJSONObject("renote")));
|
||||
}catch (Exception ignored){}
|
||||
|
||||
status.setMentions(mentions);
|
||||
//Retrieves tags
|
||||
List<Tag> tags = new ArrayList<>();
|
||||
JSONArray arrayTag = resobj.getJSONArray("tags");
|
||||
if( arrayTag != null){
|
||||
for(int j = 0 ; j < arrayTag.length() ; j++){
|
||||
JSONObject tagObj = arrayTag.getJSONObject(j);
|
||||
Tag tag = new Tag();
|
||||
tag.setName(tagObj.get("name").toString());
|
||||
tag.setUrl(tagObj.get("url").toString());
|
||||
tags.add(tag);
|
||||
}
|
||||
}
|
||||
status.setTags(tags);
|
||||
|
||||
//Retrieves emjis
|
||||
List<Emojis> emojiList = new ArrayList<>();
|
||||
try {
|
||||
JSONArray emojisTag = resobj.getJSONArray("emojis");
|
||||
if( emojisTag != null){
|
||||
for(int j = 0 ; j < emojisTag.length() ; j++){
|
||||
JSONObject emojisObj = emojisTag.getJSONObject(j);
|
||||
Emojis emojis = parseMisskeyEmojis(emojisObj);
|
||||
emojiList.add(emojis);
|
||||
}
|
||||
}
|
||||
status.setEmojis(emojiList);
|
||||
}catch (Exception e){
|
||||
status.setEmojis(new ArrayList<>());
|
||||
}
|
||||
|
||||
//Retrieve Application
|
||||
Application application = new Application();
|
||||
try {
|
||||
if(resobj.getJSONObject("application") != null){
|
||||
application.setName(resobj.getJSONObject("application").getString("name"));
|
||||
application.setWebsite(resobj.getJSONObject("application").getString("website"));
|
||||
}
|
||||
}catch (Exception e){
|
||||
application = new Application();
|
||||
}
|
||||
status.setApplication(application);
|
||||
|
||||
|
||||
} catch (JSONException ignored) {} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return status;
|
||||
}
|
||||
/**
|
||||
* Parse json response an unique instance
|
||||
* @param resobj JSONObject
|
||||
|
@ -3119,6 +3622,43 @@ public class API {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse emojis
|
||||
* @param jsonArray JSONArray
|
||||
* @return List<Emojis> of emojis
|
||||
*/
|
||||
private List<Emojis> parseMisskeyEmojis(JSONArray jsonArray){
|
||||
List<Emojis> emojis = new ArrayList<>();
|
||||
try {
|
||||
int i = 0;
|
||||
while (i < jsonArray.length() ) {
|
||||
JSONObject resobj = jsonArray.getJSONObject(i);
|
||||
Emojis emojis1 = parseMisskeyEmojis(resobj);
|
||||
emojis.add(emojis1);
|
||||
i++;
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
setDefaultError(e);
|
||||
}
|
||||
return emojis;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse json response for emoji
|
||||
* @param resobj JSONObject
|
||||
* @return Emojis
|
||||
*/
|
||||
private static Emojis parseMisskeyEmojis(JSONObject resobj){
|
||||
Emojis emojis = new Emojis();
|
||||
try {
|
||||
emojis.setShortcode(resobj.get("name").toString());
|
||||
emojis.setStatic_url(resobj.get("url").toString());
|
||||
emojis.setUrl(resobj.get("url").toString());
|
||||
}catch (Exception ignored){}
|
||||
return emojis;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse Filters
|
||||
|
@ -3262,6 +3802,7 @@ public class API {
|
|||
else
|
||||
account.setNote("");
|
||||
account.setUrl(resobj.get("url").toString());
|
||||
account.setSocial("PEERTUBE");
|
||||
if( resobj.has("avatar") && !resobj.get("avatar").toString().equals("null")){
|
||||
account.setAvatar("https://" + instance + resobj.getJSONObject("avatar").get("path"));
|
||||
}else
|
||||
|
@ -3284,6 +3825,7 @@ public class API {
|
|||
Account account = new Account();
|
||||
try {
|
||||
account.setId(resobj.get("id").toString());
|
||||
account.setUuid(resobj.get("id").toString());
|
||||
account.setUsername(resobj.get("username").toString());
|
||||
account.setAcct(resobj.get("acct").toString());
|
||||
account.setDisplay_name(resobj.get("display_name").toString());
|
||||
|
@ -3293,6 +3835,11 @@ public class API {
|
|||
account.setFollowing_count(Integer.valueOf(resobj.get("following_count").toString()));
|
||||
account.setStatuses_count(Integer.valueOf(resobj.get("statuses_count").toString()));
|
||||
account.setNote(resobj.get("note").toString());
|
||||
try {
|
||||
account.setBot(Boolean.parseBoolean(resobj.get("bot").toString()));
|
||||
}catch (Exception e){
|
||||
account.setBot(false);
|
||||
}
|
||||
try{
|
||||
account.setMoved_to_account(parseAccountResponse(context, resobj.getJSONObject("moved")));
|
||||
}catch (Exception ignored){account.setMoved_to_account(null);}
|
||||
|
@ -3301,6 +3848,12 @@ public class API {
|
|||
account.setAvatar_static(resobj.get("avatar_static").toString());
|
||||
account.setHeader(resobj.get("header").toString());
|
||||
account.setHeader_static(resobj.get("header_static").toString());
|
||||
|
||||
try{
|
||||
account.setSocial(resobj.get("software").toString().toUpperCase());
|
||||
}catch (Exception ignored){
|
||||
account.setSocial("MASTODON");
|
||||
}
|
||||
try {
|
||||
JSONArray fields = resobj.getJSONArray("fields");
|
||||
LinkedHashMap<String, String> fieldsMap = new LinkedHashMap<>();
|
||||
|
@ -3341,6 +3894,55 @@ public class API {
|
|||
return account;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse json response an unique account
|
||||
* @param resobj JSONObject
|
||||
* @return Account
|
||||
*/
|
||||
@SuppressWarnings("InfiniteRecursion")
|
||||
private static Account parseMisskeyAccountResponse(Context context, String instance, JSONObject resobj){
|
||||
|
||||
Account account = new Account();
|
||||
try {
|
||||
account.setId(resobj.get("id").toString());
|
||||
account.setUsername(resobj.get("username").toString());
|
||||
String host = resobj.get("host").toString();
|
||||
String acct;
|
||||
if( host == null || host.equals("null"))
|
||||
acct = resobj.get("username").toString();
|
||||
else
|
||||
acct = resobj.get("username").toString() + "@" + host;
|
||||
account.setAcct(acct);
|
||||
account.setDisplay_name(resobj.get("name").toString());
|
||||
account.setCreated_at(new Date());
|
||||
|
||||
account.setUrl("https://" + instance + "/@"+account.getUsername());
|
||||
account.setAvatar(resobj.get("avatarUrl").toString());
|
||||
account.setAvatar_static(resobj.get("avatarUrl").toString());
|
||||
try {
|
||||
account.setBot(Boolean.parseBoolean(resobj.get("isBot").toString()));
|
||||
}catch (Exception e){
|
||||
account.setBot(false);
|
||||
}
|
||||
//Retrieves emjis
|
||||
List<Emojis> emojiList = new ArrayList<>();
|
||||
try {
|
||||
JSONArray emojisTag = resobj.getJSONArray("emojis");
|
||||
if( emojisTag != null){
|
||||
for(int j = 0 ; j < emojisTag.length() ; j++){
|
||||
JSONObject emojisObj = emojisTag.getJSONObject(j);
|
||||
Emojis emojis = parseEmojis(emojisObj);
|
||||
emojiList.add(emojis);
|
||||
}
|
||||
}
|
||||
account.setEmojis(emojiList);
|
||||
}catch (Exception e){
|
||||
account.setEmojis(new ArrayList<>());
|
||||
}
|
||||
} catch (JSONException ignored) {}
|
||||
return account;
|
||||
}
|
||||
/**
|
||||
* Parse json response for list of accounts
|
||||
* @param jsonArray JSONArray
|
||||
|
@ -3440,6 +4042,27 @@ public class API {
|
|||
return context;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Parse json response for list of relationship
|
||||
* @param jsonArray JSONArray
|
||||
* @return List<Relationship>
|
||||
*/
|
||||
private static List<Attachment> parseAttachmentResponse(JSONArray jsonArray){
|
||||
|
||||
List<Attachment> attachments = new ArrayList<>();
|
||||
try {
|
||||
int i = 0;
|
||||
while (i < jsonArray.length() ) {
|
||||
JSONObject resobj = jsonArray.getJSONObject(i);
|
||||
Attachment attachment = parseAttachmentResponse(resobj);
|
||||
attachments.add(attachment);
|
||||
i++;
|
||||
}
|
||||
} catch (JSONException ignored) { }
|
||||
return attachments;
|
||||
}
|
||||
/**
|
||||
* Parse json response an unique attachment
|
||||
* @param resobj JSONObject
|
||||
|
@ -3565,7 +4188,12 @@ public class API {
|
|||
private String getAbsoluteUrl(String action) {
|
||||
return Helper.instanceWithProtocol(this.instance) + "/api/v1" + action;
|
||||
}
|
||||
|
||||
private String getAbsoluteUr2l(String action) {
|
||||
return Helper.instanceWithProtocol(this.instance) + "/api/v2" + action;
|
||||
}
|
||||
private String getAbsoluteUrlRemote(String remote, String action) {
|
||||
return "https://" + remote + "/api/v1" + action;
|
||||
}
|
||||
|
||||
private String getAbsoluteUrlRemoteInstance(String instanceName) {
|
||||
return "https://" + instanceName + "/api/v1/timelines/public?local=true";
|
||||
|
|
|
@ -13,10 +13,23 @@ package fr.gouv.etalab.mastodon.client;
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License along with Mastalab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.util.List;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.*;
|
||||
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Conversation;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Emojis;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Error;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Filters;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.HowToVideo;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Instance;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Notification;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Peertube;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Relationship;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Status;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.StoredStatus;
|
||||
|
||||
/**
|
||||
* Created by Thomas on 03/06/2017.
|
||||
|
@ -40,7 +53,7 @@ public class APIResponse {
|
|||
private fr.gouv.etalab.mastodon.client.Entities.Error error = null;
|
||||
private String since_id, max_id;
|
||||
private Instance instance;
|
||||
|
||||
private List<StoredStatus> storedStatuses;
|
||||
public List<Account> getAccounts() {
|
||||
return accounts;
|
||||
}
|
||||
|
@ -168,4 +181,12 @@ public class APIResponse {
|
|||
public void setConversations(List<Conversation> conversations) {
|
||||
this.conversations = conversations;
|
||||
}
|
||||
|
||||
public List<StoredStatus> getStoredStatuses() {
|
||||
return storedStatuses;
|
||||
}
|
||||
|
||||
public void setStoredStatuses(List<StoredStatus> storedStatuses) {
|
||||
this.storedStatuses = storedStatuses;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,12 +17,15 @@ package fr.gouv.etalab.mastodon.client.Entities;
|
|||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.text.Html;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
|
@ -31,7 +34,10 @@ import android.text.TextPaint;
|
|||
import android.text.TextUtils;
|
||||
import android.text.style.ClickableSpan;
|
||||
import android.text.style.ImageSpan;
|
||||
import android.text.style.URLSpan;
|
||||
import android.util.Patterns;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.request.target.SimpleTarget;
|
||||
|
@ -42,13 +48,18 @@ import java.util.Iterator;
|
|||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import es.dmoral.toasty.Toasty;
|
||||
import fr.gouv.etalab.mastodon.R;
|
||||
import fr.gouv.etalab.mastodon.activities.ShowAccountActivity;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveEmojiAccountInterface;
|
||||
|
||||
import static android.support.v4.text.HtmlCompat.FROM_HTML_MODE_LEGACY;
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.THEME_BLACK;
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.THEME_DARK;
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.THEME_LIGHT;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -59,10 +70,11 @@ import static android.support.v4.text.HtmlCompat.FROM_HTML_MODE_LEGACY;
|
|||
public class Account implements Parcelable {
|
||||
|
||||
private String id;
|
||||
private String uuid;
|
||||
private String username;
|
||||
private SpannableString displayNameSpan;
|
||||
private String acct;
|
||||
private String display_name;
|
||||
private String display_name, stored_displayname;
|
||||
private boolean locked;
|
||||
private Date created_at;
|
||||
private int followers_count;
|
||||
|
@ -91,90 +103,127 @@ public class Account implements Parcelable {
|
|||
private LinkedHashMap<String, Boolean> fieldsVerified;
|
||||
private LinkedHashMap<SpannableString, SpannableString> fieldsSpan;
|
||||
private List<Emojis> emojis;
|
||||
private Account account;
|
||||
private String host;
|
||||
private boolean isBot;
|
||||
private String social;
|
||||
private String client_id;
|
||||
private String client_secret;
|
||||
private String refresh_token;
|
||||
|
||||
|
||||
protected Account(Parcel in) {
|
||||
id = in.readString();
|
||||
username = in.readString();
|
||||
emojis = in.readArrayList(Emojis.class.getClassLoader());
|
||||
acct = in.readString();
|
||||
display_name = in.readString();
|
||||
host = in.readString();
|
||||
displayNameSpan = (SpannableString) TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
|
||||
noteSpan = (SpannableString) TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
|
||||
locked = in.readByte() != 0;
|
||||
followers_count = in.readInt();
|
||||
following_count = in.readInt();
|
||||
statuses_count = in.readInt();
|
||||
note = in.readString();
|
||||
url = in.readString();
|
||||
avatar = in.readString();
|
||||
avatar_static = in.readString();
|
||||
header = in.readString();
|
||||
header_static = in.readString();
|
||||
token = in.readString();
|
||||
instance = in.readString();
|
||||
metaDataSize = in.readInt();
|
||||
for(int i = 0; i < metaDataSize; i++){
|
||||
if( fields == null)
|
||||
fields = new LinkedHashMap<>();
|
||||
String key = in.readString();
|
||||
String value = in.readString();
|
||||
fields.put(key,value);
|
||||
}
|
||||
metaDataSizeVerified = in.readInt();
|
||||
for(int i = 0; i < metaDataSizeVerified; i++){
|
||||
if( fieldsVerified == null)
|
||||
fieldsVerified = new LinkedHashMap<>();
|
||||
String key = in.readString();
|
||||
Boolean value = in.readByte() != 0;
|
||||
fieldsVerified.put(key,value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(id);
|
||||
dest.writeString(username);
|
||||
dest.writeList(emojis);
|
||||
dest.writeString(acct);
|
||||
dest.writeString(display_name);
|
||||
dest.writeString(host);
|
||||
TextUtils.writeToParcel(displayNameSpan, dest, flags);
|
||||
TextUtils.writeToParcel(noteSpan, dest, flags);
|
||||
dest.writeByte((byte) (locked ? 1 : 0));
|
||||
dest.writeInt(followers_count);
|
||||
dest.writeInt(following_count);
|
||||
dest.writeInt(statuses_count);
|
||||
dest.writeString(note);
|
||||
dest.writeString(url);
|
||||
dest.writeString(avatar);
|
||||
dest.writeString(avatar_static);
|
||||
dest.writeString(header);
|
||||
dest.writeString(header_static);
|
||||
dest.writeString(token);
|
||||
dest.writeString(instance);
|
||||
if( fields != null) {
|
||||
metaDataSize = fields.size();
|
||||
dest.writeInt(metaDataSize);
|
||||
for (Map.Entry<String, String> entry : fields.entrySet()) {
|
||||
dest.writeString(entry.getKey());
|
||||
dest.writeString(entry.getValue());
|
||||
}
|
||||
}
|
||||
if( fieldsVerified != null) {
|
||||
metaDataSizeVerified = fieldsVerified.size();
|
||||
dest.writeInt(metaDataSizeVerified);
|
||||
for (Map.Entry<String, Boolean> entry : fieldsVerified.entrySet()) {
|
||||
dest.writeString(entry.getKey());
|
||||
dest.writeByte((byte) (entry.getValue() ? 1 : 0));
|
||||
}
|
||||
}
|
||||
dest.writeString(this.id);
|
||||
dest.writeString(this.uuid);
|
||||
dest.writeString(this.username);
|
||||
TextUtils.writeToParcel(this.displayNameSpan, dest, flags);
|
||||
dest.writeString(this.acct);
|
||||
dest.writeString(this.display_name);
|
||||
dest.writeString(this.stored_displayname);
|
||||
dest.writeByte(this.locked ? (byte) 1 : (byte) 0);
|
||||
dest.writeLong(this.created_at != null ? this.created_at.getTime() : -1);
|
||||
dest.writeInt(this.followers_count);
|
||||
dest.writeInt(this.following_count);
|
||||
dest.writeInt(this.statuses_count);
|
||||
dest.writeString(this.followers_count_str);
|
||||
dest.writeString(this.following_count_str);
|
||||
dest.writeString(this.statuses_count_str);
|
||||
dest.writeString(this.note);
|
||||
TextUtils.writeToParcel(this.noteSpan, dest, flags);
|
||||
dest.writeString(this.url);
|
||||
dest.writeString(this.avatar);
|
||||
dest.writeString(this.avatar_static);
|
||||
dest.writeString(this.header);
|
||||
dest.writeString(this.header_static);
|
||||
dest.writeString(this.token);
|
||||
dest.writeString(this.instance);
|
||||
dest.writeByte(this.isFollowing ? (byte) 1 : (byte) 0);
|
||||
dest.writeInt(this.followType == null ? -1 : this.followType.ordinal());
|
||||
dest.writeByte(this.isMakingAction ? (byte) 1 : (byte) 0);
|
||||
dest.writeParcelable(this.moved_to_account, flags);
|
||||
dest.writeByte(this.muting_notifications ? (byte) 1 : (byte) 0);
|
||||
dest.writeInt(this.metaDataSize);
|
||||
dest.writeInt(this.metaDataSizeVerified);
|
||||
dest.writeSerializable(this.fields);
|
||||
dest.writeSerializable(this.fieldsVerified);
|
||||
dest.writeSerializable(this.fieldsSpan);
|
||||
dest.writeTypedList(this.emojis);
|
||||
dest.writeString(this.host);
|
||||
dest.writeByte(this.isBot ? (byte) 1 : (byte) 0);
|
||||
dest.writeString(this.social);
|
||||
dest.writeString(this.client_id);
|
||||
dest.writeString(this.client_secret);
|
||||
dest.writeString(this.refresh_token);
|
||||
}
|
||||
|
||||
public Account() {
|
||||
}
|
||||
|
||||
protected Account(Parcel in) {
|
||||
this.id = in.readString();
|
||||
this.uuid = in.readString();
|
||||
this.username = in.readString();
|
||||
this.displayNameSpan = (SpannableString) TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
|
||||
this.acct = in.readString();
|
||||
this.display_name = in.readString();
|
||||
this.stored_displayname = in.readString();
|
||||
this.locked = in.readByte() != 0;
|
||||
long tmpCreated_at = in.readLong();
|
||||
this.created_at = tmpCreated_at == -1 ? null : new Date(tmpCreated_at);
|
||||
this.followers_count = in.readInt();
|
||||
this.following_count = in.readInt();
|
||||
this.statuses_count = in.readInt();
|
||||
this.followers_count_str = in.readString();
|
||||
this.following_count_str = in.readString();
|
||||
this.statuses_count_str = in.readString();
|
||||
this.note = in.readString();
|
||||
this.noteSpan = (SpannableString) TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
|
||||
this.url = in.readString();
|
||||
this.avatar = in.readString();
|
||||
this.avatar_static = in.readString();
|
||||
this.header = in.readString();
|
||||
this.header_static = in.readString();
|
||||
this.token = in.readString();
|
||||
this.instance = in.readString();
|
||||
this.isFollowing = in.readByte() != 0;
|
||||
int tmpFollowType = in.readInt();
|
||||
this.followType = tmpFollowType == -1 ? null : followAction.values()[tmpFollowType];
|
||||
this.isMakingAction = in.readByte() != 0;
|
||||
this.moved_to_account = in.readParcelable(Account.class.getClassLoader());
|
||||
this.muting_notifications = in.readByte() != 0;
|
||||
this.metaDataSize = in.readInt();
|
||||
this.metaDataSizeVerified = in.readInt();
|
||||
this.fields = (LinkedHashMap<String, String>) in.readSerializable();
|
||||
this.fieldsVerified = (LinkedHashMap<String, Boolean>) in.readSerializable();
|
||||
this.fieldsSpan = (LinkedHashMap<SpannableString, SpannableString>) in.readSerializable();
|
||||
this.emojis = in.createTypedArrayList(Emojis.CREATOR);
|
||||
this.host = in.readString();
|
||||
this.isBot = in.readByte() != 0;
|
||||
this.social = in.readString();
|
||||
this.client_id = in.readString();
|
||||
this.client_secret = in.readString();
|
||||
this.refresh_token = in.readString();
|
||||
}
|
||||
|
||||
public static final Creator<Account> CREATOR = new Creator<Account>() {
|
||||
@Override
|
||||
public Account createFromParcel(Parcel source) {
|
||||
return new Account(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Account[] newArray(int size) {
|
||||
return new Account[size];
|
||||
}
|
||||
};
|
||||
|
||||
public followAction getFollowType() {
|
||||
return followType;
|
||||
}
|
||||
|
@ -240,6 +289,62 @@ public class Account implements Parcelable {
|
|||
this.host = host;
|
||||
}
|
||||
|
||||
public boolean isBot() {
|
||||
return isBot;
|
||||
}
|
||||
|
||||
public void setBot(boolean bot) {
|
||||
isBot = bot;
|
||||
}
|
||||
|
||||
public String getStored_displayname() {
|
||||
return stored_displayname;
|
||||
}
|
||||
|
||||
public void setStored_displayname(String stored_displayname) {
|
||||
this.stored_displayname = stored_displayname;
|
||||
}
|
||||
|
||||
public String getSocial() {
|
||||
return social;
|
||||
}
|
||||
|
||||
public void setSocial(String social) {
|
||||
this.social = social;
|
||||
}
|
||||
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public void setUuid(String uuid) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
public String getClient_id() {
|
||||
return client_id;
|
||||
}
|
||||
|
||||
public void setClient_id(String client_id) {
|
||||
this.client_id = client_id;
|
||||
}
|
||||
|
||||
public String getClient_secret() {
|
||||
return client_secret;
|
||||
}
|
||||
|
||||
public void setClient_secret(String client_secret) {
|
||||
this.client_secret = client_secret;
|
||||
}
|
||||
|
||||
public String getRefresh_token() {
|
||||
return refresh_token;
|
||||
}
|
||||
|
||||
public void setRefresh_token(String refresh_token) {
|
||||
this.refresh_token = refresh_token;
|
||||
}
|
||||
|
||||
|
||||
public enum followAction{
|
||||
FOLLOW,
|
||||
|
@ -251,24 +356,6 @@ public class Account implements Parcelable {
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public Account(){
|
||||
this.account = this;
|
||||
}
|
||||
|
||||
public static final Creator<Account> CREATOR = new Creator<Account>() {
|
||||
@Override
|
||||
public Account createFromParcel(Parcel in) {
|
||||
return new Account(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Account[] newArray(int size) {
|
||||
return new Account[size];
|
||||
}
|
||||
};
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
@ -429,12 +516,6 @@ public class Account implements Parcelable {
|
|||
this.emojis = emojis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean isFollowing() {
|
||||
return isFollowing;
|
||||
|
@ -479,14 +560,14 @@ public class Account implements Parcelable {
|
|||
spannableString = new SpannableString(context.getString(R.string.account_moved_to, this.getAcct(), "@"+this.getMoved_to_account().getAcct()));
|
||||
int startPositionTar = spannableString.toString().indexOf("@"+this.getMoved_to_account().getAcct());
|
||||
int endPositionTar = startPositionTar + ("@"+this.getMoved_to_account().getAcct()).length();
|
||||
final String idTar = this.getMoved_to_account().getId();
|
||||
final Account idTar = this.getMoved_to_account();
|
||||
if( endPositionTar <= spannableString.toString().length() && endPositionTar >= startPositionTar)
|
||||
spannableString.setSpan(new ClickableSpan() {
|
||||
@Override
|
||||
public void onClick(View textView) {
|
||||
Intent intent = new Intent(context, ShowAccountActivity.class);
|
||||
Bundle b = new Bundle();
|
||||
b.putString("accountId", idTar);
|
||||
b.putParcelable("account", idTar);
|
||||
intent.putExtras(b);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
@ -501,7 +582,7 @@ public class Account implements Parcelable {
|
|||
return spannableString;
|
||||
}
|
||||
|
||||
public void makeEmojisAccountProfile(final Context context, final OnRetrieveEmojiAccountInterface listener){
|
||||
public void makeEmojisAccountProfile(final Context context, final OnRetrieveEmojiAccountInterface listener, Account account){
|
||||
if( ((Activity)context).isFinishing() )
|
||||
return;
|
||||
if( fields == null)
|
||||
|
@ -524,6 +605,135 @@ public class Account implements Parcelable {
|
|||
}
|
||||
account.setFieldsSpan(fieldsSpan);
|
||||
}
|
||||
Iterator it = fieldsSpan.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Map.Entry pair = (Map.Entry) it.next();
|
||||
SpannableString fieldSpan = (SpannableString) pair.getValue();
|
||||
SpannableString keySpan = (SpannableString) pair.getKey();
|
||||
Matcher matcher = Helper.xmppPattern.matcher(fieldSpan);
|
||||
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
|
||||
while (matcher.find()){
|
||||
URLSpan[] urls = fieldSpan.getSpans(0, fieldSpan.length(), URLSpan.class);
|
||||
for(URLSpan span : urls)
|
||||
fieldSpan.removeSpan(span);
|
||||
int matchStart = matcher.start(0);
|
||||
int matchEnd = matcher.end();
|
||||
final String url = fieldSpan.toString().substring(matchStart, matchEnd);
|
||||
if( matchEnd <= fieldSpan.toString().length() && matchEnd >= matchStart) {
|
||||
fieldSpan.setSpan(new ClickableSpan() {
|
||||
@Override
|
||||
public void onClick(View textView) {
|
||||
try {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
||||
context.startActivity(intent);
|
||||
}catch (Exception e){
|
||||
Toasty.error(context, context.getString(R.string.toast_no_apps), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void updateDrawState(TextPaint ds) {
|
||||
super.updateDrawState(ds);
|
||||
ds.setUnderlineText(false);
|
||||
if (theme == THEME_DARK)
|
||||
ds.setColor(ContextCompat.getColor(context, R.color.dark_link_toot));
|
||||
else if (theme == THEME_BLACK)
|
||||
ds.setColor(ContextCompat.getColor(context, R.color.black_link_toot));
|
||||
else if (theme == THEME_LIGHT)
|
||||
ds.setColor(ContextCompat.getColor(context, R.color.light_link_toot));
|
||||
}
|
||||
}, matchStart, matchEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
fieldsSpan.put(keySpan, fieldSpan);
|
||||
}
|
||||
|
||||
}
|
||||
matcher = android.util.Patterns.EMAIL_ADDRESS.matcher(fieldSpan);
|
||||
while (matcher.find()){
|
||||
URLSpan[] urls = fieldSpan.getSpans(0, fieldSpan.length(), URLSpan.class);
|
||||
for(URLSpan span : urls)
|
||||
fieldSpan.removeSpan(span);
|
||||
int matchStart = matcher.start(0);
|
||||
int matchEnd = matcher.end();
|
||||
final String email = fieldSpan.toString().substring(matchStart, matchEnd);
|
||||
if( matchEnd <= fieldSpan.toString().length() && matchEnd >= matchStart) {
|
||||
fieldSpan.setSpan(new ClickableSpan() {
|
||||
@Override
|
||||
public void onClick(View textView) {
|
||||
try {
|
||||
final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
|
||||
emailIntent.setType("plain/text");
|
||||
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{email});
|
||||
context.startActivity(Intent.createChooser(emailIntent, context.getString(R.string.send_email)));
|
||||
}catch (Exception e){
|
||||
Toasty.error(context, context.getString(R.string.toast_no_apps), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void updateDrawState(TextPaint ds) {
|
||||
super.updateDrawState(ds);
|
||||
ds.setUnderlineText(false);
|
||||
if (theme == THEME_DARK)
|
||||
ds.setColor(ContextCompat.getColor(context, R.color.dark_link_toot));
|
||||
else if (theme == THEME_BLACK)
|
||||
ds.setColor(ContextCompat.getColor(context, R.color.black_link_toot));
|
||||
else if (theme == THEME_LIGHT)
|
||||
ds.setColor(ContextCompat.getColor(context, R.color.light_link_toot));
|
||||
}
|
||||
}, matchStart, matchEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
fieldsSpan.put(keySpan, fieldSpan);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
it = fieldsSpan.entrySet().iterator();
|
||||
fieldsVerified = account.getFieldsVerified();
|
||||
while (it.hasNext()) {
|
||||
Map.Entry pair = (Map.Entry) it.next();
|
||||
SpannableString fieldSpan = (SpannableString) pair.getValue();
|
||||
SpannableString keySpan = (SpannableString) pair.getKey();
|
||||
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
Matcher matcher;
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT)
|
||||
matcher = Patterns.WEB_URL.matcher(fieldSpan);
|
||||
else
|
||||
matcher = Helper.urlPattern.matcher(fieldSpan);
|
||||
while (matcher.find()){
|
||||
URLSpan[] urls = fieldSpan.getSpans(0, fieldSpan.length(), URLSpan.class);
|
||||
for(URLSpan span : urls)
|
||||
fieldSpan.removeSpan(span);
|
||||
int matchStart = matcher.start(0);
|
||||
int matchEnd = matcher.end();
|
||||
final String url = fieldSpan.toString().substring(matchStart, matchEnd);
|
||||
if( matchEnd <= fieldSpan.toString().length() && matchEnd >= matchStart) {
|
||||
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
|
||||
fieldSpan.setSpan(new ClickableSpan() {
|
||||
@Override
|
||||
public void onClick(View textView) {
|
||||
Helper.openBrowser(context, url);
|
||||
}
|
||||
@Override
|
||||
public void updateDrawState(TextPaint ds) {
|
||||
super.updateDrawState(ds);
|
||||
ds.setUnderlineText(false);
|
||||
|
||||
if (theme == THEME_DARK)
|
||||
ds.setColor(ContextCompat.getColor(context, R.color.dark_link_toot));
|
||||
else if (theme == THEME_BLACK)
|
||||
ds.setColor(ContextCompat.getColor(context, R.color.black_link_toot));
|
||||
else if (theme == THEME_LIGHT)
|
||||
ds.setColor(ContextCompat.getColor(context, R.color.light_link_toot));
|
||||
|
||||
}
|
||||
}, matchStart, matchEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
fieldsSpan.put(keySpan, fieldSpan);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
final List<Emojis> emojis = account.getEmojis();
|
||||
if( emojis != null && emojis.size() > 0 ) {
|
||||
|
||||
|
@ -597,40 +807,23 @@ public class Account implements Parcelable {
|
|||
}catch (Exception ignored){}
|
||||
|
||||
}
|
||||
}else {
|
||||
if (listener != null)
|
||||
listener.onRetrieveEmojiAccount(account);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void makeEmojisAccount(final Context context, final OnRetrieveEmojiAccountInterface listener, Account account){
|
||||
public void makeAccountNameEmoji(final Context context, final OnRetrieveEmojiAccountInterface listener, Account account){
|
||||
if( ((Activity)context).isFinishing() )
|
||||
return;
|
||||
|
||||
fields = new LinkedHashMap<>();
|
||||
fieldsVerified = new LinkedHashMap<>();
|
||||
fieldsSpan = new LinkedHashMap<>();
|
||||
noteSpan = account.getNoteSpan();
|
||||
if( account.getDisplay_name() != null)
|
||||
displayNameSpan = new SpannableString(account.getDisplay_name());
|
||||
if( account.getFields() != null && account.getFields().size() > 0) {
|
||||
Iterator it = account.getFields().entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Map.Entry pair = (Map.Entry) it.next();
|
||||
SpannableString fieldSpan;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||
fieldSpan = new SpannableString(Html.fromHtml((String)pair.getValue(), FROM_HTML_MODE_LEGACY));
|
||||
else
|
||||
//noinspection deprecation
|
||||
fieldSpan = new SpannableString(Html.fromHtml((String)pair.getValue()));
|
||||
fieldsSpan.put(new SpannableString((String)pair.getKey()), fieldSpan);
|
||||
}
|
||||
account.setFieldsSpan(fieldsSpan);
|
||||
}
|
||||
final List<Emojis> emojis = account.getEmojis();
|
||||
if( emojis != null && emojis.size() > 0 ) {
|
||||
|
||||
final int[] i = {0};
|
||||
for (final Emojis emoji : emojis) {
|
||||
fields = account.getFields();
|
||||
try {
|
||||
Glide.with(context)
|
||||
.asBitmap()
|
||||
|
@ -653,8 +846,6 @@ public class Account implements Parcelable {
|
|||
}
|
||||
i[0]++;
|
||||
if (i[0] == (emojis.size())) {
|
||||
if (noteSpan != null)
|
||||
account.setNoteSpan(noteSpan);
|
||||
if (listener != null)
|
||||
listener.onRetrieveEmojiAccount(account);
|
||||
}
|
||||
|
@ -666,4 +857,6 @@ public class Account implements Parcelable {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -15,10 +15,30 @@
|
|||
package fr.gouv.etalab.mastodon.client.Entities;
|
||||
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.style.ImageSpan;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.DataSource;
|
||||
import com.bumptech.glide.load.engine.GlideException;
|
||||
import com.bumptech.glide.request.RequestListener;
|
||||
import com.bumptech.glide.request.target.SimpleTarget;
|
||||
import com.bumptech.glide.request.target.Target;
|
||||
import com.bumptech.glide.request.transition.Transition;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveEmojiInterface;
|
||||
|
||||
/**
|
||||
* Created by Thomas on 23/04/2017.
|
||||
|
@ -110,4 +130,101 @@ public class Notification implements Parcelable {
|
|||
public boolean equals(Object otherNotifications) {
|
||||
return otherNotifications != null && (otherNotifications == this || otherNotifications instanceof Notification && this.getId().equals(((Notification) otherNotifications).getId()));
|
||||
}
|
||||
|
||||
|
||||
public static void makeEmojis(final Context context, final OnRetrieveEmojiInterface listener, Notification notification){
|
||||
|
||||
if( ((Activity)context).isFinishing() )
|
||||
return;
|
||||
Status status = notification.getStatus();
|
||||
if (status == null)
|
||||
return;
|
||||
if( status.getReblog() == null && status.getEmojis() == null)
|
||||
return;
|
||||
final java.util.List<Emojis> emojis = status.getReblog() != null ? status.getReblog().getEmojis() : status.getEmojis();
|
||||
final List<Emojis> emojisAccounts = status.getReblog() != null ?status.getReblog().getAccount().getEmojis():status.getAccount().getEmojis();
|
||||
|
||||
status.getAccount().makeAccountNameEmoji(context, null, status.getAccount());
|
||||
|
||||
// SpannableString displayNameSpan = status.getDisplayNameSpan();
|
||||
SpannableString contentSpan = status.getContentSpan();
|
||||
SpannableString contentSpanCW = status.getContentSpanCW();
|
||||
if( emojisAccounts != null)
|
||||
emojis.addAll(emojisAccounts);
|
||||
if( emojis != null && emojis.size() > 0 ) {
|
||||
final int[] i = {0};
|
||||
for (final Emojis emoji : emojis) {
|
||||
Glide.with(context)
|
||||
.asBitmap()
|
||||
.load(emoji.getUrl())
|
||||
.listener(new RequestListener<Bitmap>() {
|
||||
@Override
|
||||
public boolean onResourceReady(Bitmap resource, Object model, Target<Bitmap> target, DataSource dataSource, boolean isFirstResource) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
|
||||
i[0]++;
|
||||
if( i[0] == (emojis.size())) {
|
||||
listener.onRetrieveEmoji(status,false);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.into(new SimpleTarget<Bitmap>() {
|
||||
@Override
|
||||
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
|
||||
final String targetedEmoji = ":" + emoji.getShortcode() + ":";
|
||||
if (contentSpan != null && contentSpan.toString().contains(targetedEmoji)) {
|
||||
//emojis can be used several times so we have to loop
|
||||
for (int startPosition = -1; (startPosition = contentSpan.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) {
|
||||
final int endPosition = startPosition + targetedEmoji.length();
|
||||
if( endPosition <= contentSpan.toString().length() && endPosition >= startPosition)
|
||||
contentSpan.setSpan(
|
||||
new ImageSpan(context,
|
||||
Bitmap.createScaledBitmap(resource, (int) Helper.convertDpToPixel(20, context),
|
||||
(int) Helper.convertDpToPixel(20, context), false)), startPosition,
|
||||
endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
}
|
||||
/*if (displayNameSpan != null && displayNameSpan.toString().contains(targetedEmoji)) {
|
||||
//emojis can be used several times so we have to loop
|
||||
for (int startPosition = -1; (startPosition = displayNameSpan.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) {
|
||||
final int endPosition = startPosition + targetedEmoji.length();
|
||||
if(endPosition <= displayNameSpan.toString().length() && endPosition >= startPosition)
|
||||
displayNameSpan.setSpan(
|
||||
new ImageSpan(context,
|
||||
Bitmap.createScaledBitmap(resource, (int) Helper.convertDpToPixel(20, context),
|
||||
(int) Helper.convertDpToPixel(20, context), false)), startPosition,
|
||||
endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
}
|
||||
status.setDisplayNameSpan(displayNameSpan);*/
|
||||
if (contentSpanCW != null && contentSpanCW.toString().contains(targetedEmoji)) {
|
||||
//emojis can be used several times so we have to loop
|
||||
for (int startPosition = -1; (startPosition = contentSpanCW.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) {
|
||||
final int endPosition = startPosition + targetedEmoji.length();
|
||||
if( endPosition <= contentSpan.toString().length() && endPosition >= startPosition)
|
||||
contentSpanCW.setSpan(
|
||||
new ImageSpan(context,
|
||||
Bitmap.createScaledBitmap(resource, (int) Helper.convertDpToPixel(20, context),
|
||||
(int) Helper.convertDpToPixel(20, context), false)), startPosition,
|
||||
endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
}
|
||||
i[0]++;
|
||||
if( i[0] == (emojis.size())) {
|
||||
status.setContentSpan(contentSpan);
|
||||
status.setContentSpanCW(contentSpanCW);
|
||||
status.setEmojiFound(true);
|
||||
listener.onRetrieveEmoji(notification);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ package fr.gouv.etalab.mastodon.client.Entities;
|
|||
import org.json.JSONObject;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
@ -40,8 +41,20 @@ public class Peertube {
|
|||
private int duration;
|
||||
private String instance;
|
||||
private Account account;
|
||||
private Account channel;
|
||||
private List<String> resolution;
|
||||
private List<String> tags;
|
||||
private boolean commentsEnabled;
|
||||
private boolean sensitive;
|
||||
private HashMap<Integer, String> category;
|
||||
private HashMap<Integer, String> license;
|
||||
private HashMap<String, String> language;
|
||||
private HashMap<Integer, String> privacy;
|
||||
private HashMap<String, String> channelForUpdate;
|
||||
private String myRating = "none";
|
||||
private boolean isUpdate = false; // I allow to set it to true when dealing with API updates
|
||||
private String headerType = null;//For overview timeline
|
||||
private String headerTypeValue = null;//For overview timeline
|
||||
private JSONObject cache;
|
||||
|
||||
public Peertube() {
|
||||
|
@ -170,6 +183,15 @@ public class Peertube {
|
|||
}
|
||||
|
||||
|
||||
public String getTorrentUrl(String resolution) {
|
||||
if( resolution == null)
|
||||
resolution = this.getResolution().get(0);
|
||||
if(resolution == null)
|
||||
return null;
|
||||
return "https://" + this.host + "/static/torrents/" + getUuid()+ "-" + resolution + ".torrent";
|
||||
|
||||
}
|
||||
|
||||
public String getTorrentDownloadUrl(String resolution) {
|
||||
if( resolution == null)
|
||||
resolution = this.getResolution().get(0);
|
||||
|
@ -217,4 +239,104 @@ public class Peertube {
|
|||
public void setCache(JSONObject cache) {
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
public boolean isSensitive() {
|
||||
return sensitive;
|
||||
}
|
||||
|
||||
public void setSensitive(boolean sensitive) {
|
||||
this.sensitive = sensitive;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public String getMyRating() {
|
||||
return myRating;
|
||||
}
|
||||
|
||||
public void setMyRating(String myRating) {
|
||||
this.myRating = myRating;
|
||||
}
|
||||
|
||||
public Account getChannel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
public void setChannel(Account channel) {
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
|
||||
public List<String> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
public void setTags(List<String> tags) {
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
public HashMap<Integer, String> getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
public void setCategory(HashMap<Integer, String> category) {
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public HashMap<Integer, String> getLicense() {
|
||||
return license;
|
||||
}
|
||||
|
||||
public void setLicense(HashMap<Integer, String> license) {
|
||||
this.license = license;
|
||||
}
|
||||
|
||||
public HashMap<String, String> getLanguage() {
|
||||
return language;
|
||||
}
|
||||
|
||||
public void setLanguage(HashMap<String, String> language) {
|
||||
this.language = language;
|
||||
}
|
||||
|
||||
public HashMap<Integer, String> getPrivacy() {
|
||||
return privacy;
|
||||
}
|
||||
|
||||
public void setPrivacy(HashMap<Integer, String> privacy) {
|
||||
this.privacy = privacy;
|
||||
}
|
||||
|
||||
public HashMap<String, String> getChannelForUpdate() {
|
||||
return channelForUpdate;
|
||||
}
|
||||
|
||||
public void setChannelForUpdate(HashMap<String, String> channelForUpdate) {
|
||||
this.channelForUpdate = channelForUpdate;
|
||||
}
|
||||
|
||||
public boolean isUpdate() {
|
||||
return isUpdate;
|
||||
}
|
||||
|
||||
public void setUpdate(boolean update) {
|
||||
isUpdate = update;
|
||||
}
|
||||
|
||||
public String getHeaderType() {
|
||||
return headerType;
|
||||
}
|
||||
|
||||
public void setHeaderType(String headerType) {
|
||||
this.headerType = headerType;
|
||||
}
|
||||
|
||||
public String getHeaderTypeValue() {
|
||||
return headerTypeValue;
|
||||
}
|
||||
|
||||
public void setHeaderTypeValue(String headerTypeValue) {
|
||||
this.headerTypeValue = headerTypeValue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
package fr.gouv.etalab.mastodon.client.Entities;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
/* Copyright 2019 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Mastalab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Mastalab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
|
||||
public class PeertubeInformation {
|
||||
|
||||
|
||||
private LinkedHashMap<Integer, String> categories;
|
||||
private LinkedHashMap<String, String> languages;
|
||||
private LinkedHashMap<Integer, String> licences;
|
||||
private LinkedHashMap<Integer, String> privacies;
|
||||
private LinkedHashMap<String, String> translations;
|
||||
|
||||
public static final LinkedHashMap<String, String> langueMapped;
|
||||
static {
|
||||
LinkedHashMap<String, String> aMap = new LinkedHashMap<>();
|
||||
aMap.put("ca", "ca-ES");
|
||||
aMap.put("de", "de-DE");
|
||||
aMap.put("en", "en-US");
|
||||
aMap.put("es", "es-ES");
|
||||
aMap.put("eo", "eo");
|
||||
aMap.put("eu", "eu-ES");
|
||||
aMap.put("fr", "fr-FR");
|
||||
aMap.put("oc", "oc");
|
||||
aMap.put("pt", "pt-BR");
|
||||
aMap.put("sv", "sv-SE");
|
||||
aMap.put("cs", "cs-CZ");
|
||||
aMap.put("zh-CN", "zh-Hans-CN");
|
||||
aMap.put("zh-TW", "zh-Hans-TW");
|
||||
langueMapped = aMap;
|
||||
}
|
||||
|
||||
|
||||
public LinkedHashMap<String, String> getTranslations() {
|
||||
return translations;
|
||||
}
|
||||
|
||||
public void setTranslations(LinkedHashMap<String, String> translations) {
|
||||
this.translations = translations;
|
||||
}
|
||||
|
||||
public LinkedHashMap<Integer, String> getCategories() {
|
||||
return categories;
|
||||
}
|
||||
|
||||
public void setCategories(LinkedHashMap<Integer, String> categories) {
|
||||
this.categories = categories;
|
||||
}
|
||||
|
||||
public LinkedHashMap<String, String> getLanguages() {
|
||||
return languages;
|
||||
}
|
||||
|
||||
public void setLanguages(LinkedHashMap<String, String> languages) {
|
||||
this.languages = languages;
|
||||
}
|
||||
|
||||
public LinkedHashMap<Integer, String> getLicences() {
|
||||
return licences;
|
||||
}
|
||||
|
||||
public void setLicences(LinkedHashMap<Integer, String> licences) {
|
||||
this.licences = licences;
|
||||
}
|
||||
|
||||
public LinkedHashMap<Integer, String> getPrivacies() {
|
||||
return privacies;
|
||||
}
|
||||
|
||||
public void setPrivacies(LinkedHashMap<Integer, String> privacies) {
|
||||
this.privacies = privacies;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/* Copyright 2017 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Mastalab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Mastalab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
package fr.gouv.etalab.mastodon.client.Entities;
|
||||
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Thomas on 18/01/2019.
|
||||
* Manages scheduled toots
|
||||
*/
|
||||
|
||||
public class Schedule implements Parcelable {
|
||||
|
||||
private String id;
|
||||
private Date scheduled_at;
|
||||
private Status status;
|
||||
private List<Attachment> attachmentList;
|
||||
|
||||
public Schedule(){}
|
||||
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Date getScheduled_at() {
|
||||
return scheduled_at;
|
||||
}
|
||||
|
||||
public void setScheduled_at(Date scheduled_at) {
|
||||
this.scheduled_at = scheduled_at;
|
||||
}
|
||||
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Status status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public List<Attachment> getAttachmentList() {
|
||||
return attachmentList;
|
||||
}
|
||||
|
||||
public void setAttachmentList(List<Attachment> attachmentList) {
|
||||
this.attachmentList = attachmentList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(this.id);
|
||||
dest.writeLong(this.scheduled_at != null ? this.scheduled_at.getTime() : -1);
|
||||
dest.writeParcelable(this.status, flags);
|
||||
dest.writeTypedList(this.attachmentList);
|
||||
}
|
||||
|
||||
protected Schedule(Parcel in) {
|
||||
this.id = in.readString();
|
||||
long tmpScheduled_at = in.readLong();
|
||||
this.scheduled_at = tmpScheduled_at == -1 ? null : new Date(tmpScheduled_at);
|
||||
this.status = in.readParcelable(Status.class.getClassLoader());
|
||||
this.attachmentList = in.createTypedArrayList(Attachment.CREATOR);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<Schedule> CREATOR = new Parcelable.Creator<Schedule>() {
|
||||
@Override
|
||||
public Schedule createFromParcel(Parcel source) {
|
||||
return new Schedule(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Schedule[] newArray(int size) {
|
||||
return new Schedule[size];
|
||||
}
|
||||
};
|
||||
}
|
|
@ -33,6 +33,7 @@ import android.text.Spannable;
|
|||
import android.text.SpannableString;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextPaint;
|
||||
import android.text.TextUtils;
|
||||
import android.text.style.ClickableSpan;
|
||||
import android.text.style.ImageSpan;
|
||||
import android.text.style.URLSpan;
|
||||
|
@ -96,6 +97,7 @@ public class Status implements Parcelable{
|
|||
private boolean attachmentShown = false;
|
||||
private boolean spoilerShown = false;
|
||||
private ArrayList<Attachment> media_attachments;
|
||||
private Attachment art_attachment;
|
||||
private List<Mention> mentions;
|
||||
private List<Emojis> emojis;
|
||||
private List<Tag> tags;
|
||||
|
@ -123,86 +125,121 @@ public class Status implements Parcelable{
|
|||
private String webviewURL = null;
|
||||
|
||||
private boolean isBoostAnimated = false, isFavAnimated = false;
|
||||
protected Status(Parcel in) {
|
||||
id = in.readString();
|
||||
uri = in.readString();
|
||||
url = in.readString();
|
||||
in_reply_to_id = in.readString();
|
||||
conversationId = in.readString();
|
||||
in_reply_to_account_id = in.readString();
|
||||
content = in.readString();
|
||||
contentCW = in.readString();
|
||||
created_at = (java.util.Date) in.readSerializable();
|
||||
visibility = in.readString();
|
||||
media_attachments = in.readArrayList(Attachment.class.getClassLoader());
|
||||
reblog = in.readParcelable(Status.class.getClassLoader());
|
||||
account = in.readParcelable(Account.class.getClassLoader());
|
||||
application = in.readParcelable(Application.class.getClassLoader());
|
||||
mentions = in.readArrayList(Mention.class.getClassLoader());
|
||||
tags = in.readArrayList(Tag.class.getClassLoader());
|
||||
contentTranslated = in.readString();
|
||||
reblogs_count = in.readInt();
|
||||
itemViewType = in.readInt();
|
||||
favourites_count = in.readInt();
|
||||
replies_count = in.readInt();
|
||||
reblogged = in.readByte() != 0;
|
||||
favourited = in.readByte() != 0;
|
||||
muted = in.readByte() != 0;
|
||||
sensitive = in.readByte() != 0;
|
||||
language = in.readString();
|
||||
attachmentShown = in.readByte() != 0;
|
||||
spoilerShown = in.readByte() != 0;
|
||||
isTranslated = in.readByte() != 0;
|
||||
isTranslationShown = in.readByte() != 0;
|
||||
isNew = in.readByte() != 0;
|
||||
pinned = in.readByte() != 0;
|
||||
emojis = in.readArrayList(Emojis.class.getClassLoader());
|
||||
card = in.readParcelable(Card.class.getClassLoader());
|
||||
}
|
||||
private String scheduled_at;
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(id);
|
||||
dest.writeString(uri);
|
||||
dest.writeString(url);
|
||||
dest.writeString(in_reply_to_id);
|
||||
dest.writeString(conversationId);
|
||||
dest.writeString(in_reply_to_account_id);
|
||||
dest.writeString(content);
|
||||
dest.writeString(contentCW);
|
||||
dest.writeSerializable(created_at);
|
||||
dest.writeString(visibility);
|
||||
dest.writeList(media_attachments);
|
||||
dest.writeParcelable(reblog, flags);
|
||||
dest.writeParcelable(account, flags);
|
||||
dest.writeParcelable(application, flags);
|
||||
dest.writeList(mentions);
|
||||
dest.writeList(tags);
|
||||
dest.writeString(contentTranslated);
|
||||
dest.writeInt(reblogs_count);
|
||||
dest.writeInt(itemViewType);
|
||||
dest.writeInt(favourites_count);
|
||||
dest.writeInt(replies_count);
|
||||
dest.writeByte((byte) (reblogged ? 1 : 0));
|
||||
dest.writeByte((byte) (favourited ? 1 : 0));
|
||||
dest.writeByte((byte) (muted ? 1 : 0));
|
||||
dest.writeByte((byte) (sensitive ? 1 : 0));
|
||||
dest.writeString(language);
|
||||
dest.writeByte((byte) (attachmentShown ? 1 : 0));
|
||||
dest.writeByte((byte) (spoilerShown ? 1 : 0));
|
||||
dest.writeByte((byte) (isTranslated ? 1 : 0));
|
||||
dest.writeByte((byte) (isTranslationShown ? 1 : 0));
|
||||
dest.writeByte((byte) (isNew ? 1 : 0));
|
||||
dest.writeByte((byte) (pinned ? 1 : 0));
|
||||
dest.writeList(emojis);
|
||||
dest.writeParcelable(card, flags);
|
||||
dest.writeString(this.id);
|
||||
dest.writeString(this.uri);
|
||||
dest.writeString(this.url);
|
||||
dest.writeParcelable(this.account, flags);
|
||||
dest.writeString(this.in_reply_to_id);
|
||||
dest.writeString(this.in_reply_to_account_id);
|
||||
dest.writeParcelable(this.reblog, flags);
|
||||
dest.writeLong(this.created_at != null ? this.created_at.getTime() : -1);
|
||||
dest.writeInt(this.reblogs_count);
|
||||
dest.writeInt(this.favourites_count);
|
||||
dest.writeInt(this.replies_count);
|
||||
dest.writeByte(this.reblogged ? (byte) 1 : (byte) 0);
|
||||
dest.writeByte(this.favourited ? (byte) 1 : (byte) 0);
|
||||
dest.writeByte(this.muted ? (byte) 1 : (byte) 0);
|
||||
dest.writeByte(this.pinned ? (byte) 1 : (byte) 0);
|
||||
dest.writeByte(this.sensitive ? (byte) 1 : (byte) 0);
|
||||
dest.writeByte(this.bookmarked ? (byte) 1 : (byte) 0);
|
||||
dest.writeString(this.visibility);
|
||||
dest.writeByte(this.attachmentShown ? (byte) 1 : (byte) 0);
|
||||
dest.writeByte(this.spoilerShown ? (byte) 1 : (byte) 0);
|
||||
dest.writeTypedList(this.media_attachments);
|
||||
dest.writeParcelable(this.art_attachment, flags);
|
||||
dest.writeTypedList(this.mentions);
|
||||
dest.writeTypedList(this.emojis);
|
||||
dest.writeTypedList(this.tags);
|
||||
dest.writeParcelable(this.application, flags);
|
||||
dest.writeParcelable(this.card, flags);
|
||||
dest.writeString(this.language);
|
||||
dest.writeByte(this.isTranslated ? (byte) 1 : (byte) 0);
|
||||
dest.writeByte(this.isTranslationShown ? (byte) 1 : (byte) 0);
|
||||
dest.writeByte(this.isNew ? (byte) 1 : (byte) 0);
|
||||
dest.writeByte(this.isVisible ? (byte) 1 : (byte) 0);
|
||||
dest.writeByte(this.fetchMore ? (byte) 1 : (byte) 0);
|
||||
dest.writeString(this.content);
|
||||
dest.writeString(this.contentCW);
|
||||
dest.writeString(this.contentTranslated);
|
||||
TextUtils.writeToParcel(this.contentSpan, dest, flags);
|
||||
TextUtils.writeToParcel(this.displayNameSpan, dest, flags);
|
||||
TextUtils.writeToParcel(this.contentSpanCW, dest, flags);
|
||||
TextUtils.writeToParcel(this.contentSpanTranslated, dest, flags);
|
||||
dest.writeInt(this.type == null ? -1 : this.type.ordinal());
|
||||
dest.writeInt(this.itemViewType);
|
||||
dest.writeString(this.conversationId);
|
||||
dest.writeByte(this.isExpanded ? (byte) 1 : (byte) 0);
|
||||
dest.writeInt(this.numberLines);
|
||||
dest.writeStringList(this.conversationProfilePicture);
|
||||
dest.writeString(this.webviewURL);
|
||||
dest.writeByte(this.isBoostAnimated ? (byte) 1 : (byte) 0);
|
||||
dest.writeByte(this.isFavAnimated ? (byte) 1 : (byte) 0);
|
||||
dest.writeString(this.scheduled_at);
|
||||
}
|
||||
|
||||
protected Status(Parcel in) {
|
||||
this.id = in.readString();
|
||||
this.uri = in.readString();
|
||||
this.url = in.readString();
|
||||
this.account = in.readParcelable(Account.class.getClassLoader());
|
||||
this.in_reply_to_id = in.readString();
|
||||
this.in_reply_to_account_id = in.readString();
|
||||
this.reblog = in.readParcelable(Status.class.getClassLoader());
|
||||
long tmpCreated_at = in.readLong();
|
||||
this.created_at = tmpCreated_at == -1 ? null : new Date(tmpCreated_at);
|
||||
this.reblogs_count = in.readInt();
|
||||
this.favourites_count = in.readInt();
|
||||
this.replies_count = in.readInt();
|
||||
this.reblogged = in.readByte() != 0;
|
||||
this.favourited = in.readByte() != 0;
|
||||
this.muted = in.readByte() != 0;
|
||||
this.pinned = in.readByte() != 0;
|
||||
this.sensitive = in.readByte() != 0;
|
||||
this.bookmarked = in.readByte() != 0;
|
||||
this.visibility = in.readString();
|
||||
this.attachmentShown = in.readByte() != 0;
|
||||
this.spoilerShown = in.readByte() != 0;
|
||||
this.media_attachments = in.createTypedArrayList(Attachment.CREATOR);
|
||||
this.art_attachment = in.readParcelable(Attachment.class.getClassLoader());
|
||||
this.mentions = in.createTypedArrayList(Mention.CREATOR);
|
||||
this.emojis = in.createTypedArrayList(Emojis.CREATOR);
|
||||
this.tags = in.createTypedArrayList(Tag.CREATOR);
|
||||
this.application = in.readParcelable(Application.class.getClassLoader());
|
||||
this.card = in.readParcelable(Card.class.getClassLoader());
|
||||
this.language = in.readString();
|
||||
this.isTranslated = in.readByte() != 0;
|
||||
this.isTranslationShown = in.readByte() != 0;
|
||||
this.isNew = in.readByte() != 0;
|
||||
this.isVisible = in.readByte() != 0;
|
||||
this.fetchMore = in.readByte() != 0;
|
||||
this.content = in.readString();
|
||||
this.contentCW = in.readString();
|
||||
this.contentTranslated = in.readString();
|
||||
this.contentSpan = (SpannableString) TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
|
||||
this.displayNameSpan = (SpannableString) TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
|
||||
this.contentSpanCW = (SpannableString) TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
|
||||
this.contentSpanTranslated = (SpannableString) TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
|
||||
int tmpType = in.readInt();
|
||||
this.type = tmpType == -1 ? null : RetrieveFeedsAsyncTask.Type.values()[tmpType];
|
||||
this.itemViewType = in.readInt();
|
||||
this.conversationId = in.readString();
|
||||
this.isExpanded = in.readByte() != 0;
|
||||
this.numberLines = in.readInt();
|
||||
this.conversationProfilePicture = in.createStringArrayList();
|
||||
this.webviewURL = in.readString();
|
||||
this.isBoostAnimated = in.readByte() != 0;
|
||||
this.isFavAnimated = in.readByte() != 0;
|
||||
this.scheduled_at = in.readString();
|
||||
}
|
||||
|
||||
public static final Creator<Status> CREATOR = new Creator<Status>() {
|
||||
@Override
|
||||
public Status createFromParcel(Parcel in) {
|
||||
return new Status(in);
|
||||
public Status createFromParcel(Parcel source) {
|
||||
return new Status(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -211,6 +248,7 @@ public class Status implements Parcelable{
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
@ -395,11 +433,6 @@ public class Status implements Parcelable{
|
|||
this.attachmentShown = attachmentShown;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public boolean isSpoilerShown() {
|
||||
return spoilerShown;
|
||||
|
@ -545,7 +578,7 @@ public class Status implements Parcelable{
|
|||
final List<Emojis> emojis = status.getReblog() != null ? status.getReblog().getEmojis() : status.getEmojis();
|
||||
final List<Emojis> emojisAccounts = status.getReblog() != null ?status.getReblog().getAccount().getEmojis():status.getAccount().getEmojis();
|
||||
|
||||
status.getAccount().makeEmojisAccount(context, null, status.getAccount());
|
||||
status.getAccount().makeAccountNameEmoji(context, null, status.getAccount());
|
||||
|
||||
SpannableString displayNameSpan = status.getDisplayNameSpan();
|
||||
SpannableString contentSpan = status.getContentSpan();
|
||||
|
@ -1190,4 +1223,26 @@ public class Status implements Parcelable{
|
|||
public void setFavAnimated(boolean favAnimated) {
|
||||
isFavAnimated = favAnimated;
|
||||
}
|
||||
|
||||
public Attachment getArt_attachment() {
|
||||
return art_attachment;
|
||||
}
|
||||
|
||||
public void setArt_attachment(Attachment art_attachment) {
|
||||
this.art_attachment = art_attachment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public String getScheduled_at() {
|
||||
return scheduled_at;
|
||||
}
|
||||
|
||||
public void setScheduled_at(String scheduled_at) {
|
||||
this.scheduled_at = scheduled_at;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package fr.gouv.etalab.mastodon.client.Entities;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
|
@ -8,7 +11,7 @@ import java.util.Date;
|
|||
* Manage Stored status
|
||||
*/
|
||||
|
||||
public class StoredStatus {
|
||||
public class StoredStatus implements Parcelable {
|
||||
|
||||
private int id;
|
||||
private Date creation_date;
|
||||
|
@ -20,6 +23,7 @@ public class StoredStatus {
|
|||
private Status statusReply;
|
||||
private String instance;
|
||||
private String userId;
|
||||
private String scheduledServerdId;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
|
@ -101,4 +105,65 @@ public class StoredStatus {
|
|||
public void setStatusReply(Status statusReply) {
|
||||
this.statusReply = statusReply;
|
||||
}
|
||||
|
||||
|
||||
public String getScheduledServerdId() {
|
||||
return scheduledServerdId;
|
||||
}
|
||||
|
||||
public void setScheduledServerdId(String scheduledServerdId) {
|
||||
this.scheduledServerdId = scheduledServerdId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(this.id);
|
||||
dest.writeLong(this.creation_date != null ? this.creation_date.getTime() : -1);
|
||||
dest.writeLong(this.scheduled_date != null ? this.scheduled_date.getTime() : -1);
|
||||
dest.writeLong(this.sent_date != null ? this.sent_date.getTime() : -1);
|
||||
dest.writeInt(this.jobId);
|
||||
dest.writeByte(this.isSent ? (byte) 1 : (byte) 0);
|
||||
dest.writeParcelable(this.status, flags);
|
||||
dest.writeParcelable(this.statusReply, flags);
|
||||
dest.writeString(this.instance);
|
||||
dest.writeString(this.userId);
|
||||
dest.writeString(this.scheduledServerdId);
|
||||
}
|
||||
|
||||
public StoredStatus() {
|
||||
}
|
||||
|
||||
protected StoredStatus(Parcel in) {
|
||||
this.id = in.readInt();
|
||||
long tmpCreation_date = in.readLong();
|
||||
this.creation_date = tmpCreation_date == -1 ? null : new Date(tmpCreation_date);
|
||||
long tmpScheduled_date = in.readLong();
|
||||
this.scheduled_date = tmpScheduled_date == -1 ? null : new Date(tmpScheduled_date);
|
||||
long tmpSent_date = in.readLong();
|
||||
this.sent_date = tmpSent_date == -1 ? null : new Date(tmpSent_date);
|
||||
this.jobId = in.readInt();
|
||||
this.isSent = in.readByte() != 0;
|
||||
this.status = in.readParcelable(Status.class.getClassLoader());
|
||||
this.statusReply = in.readParcelable(Status.class.getClassLoader());
|
||||
this.instance = in.readString();
|
||||
this.userId = in.readString();
|
||||
this.scheduledServerdId = in.readString();
|
||||
}
|
||||
|
||||
public static final Creator<StoredStatus> CREATOR = new Creator<StoredStatus>() {
|
||||
@Override
|
||||
public StoredStatus createFromParcel(Parcel source) {
|
||||
return new StoredStatus(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StoredStatus[] newArray(int size) {
|
||||
return new StoredStatus[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
* see <http://www.gnu.org/licenses>. */
|
||||
package fr.gouv.etalab.mastodon.client.Entities;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Thomas on 15/12/2018.
|
||||
* Manage Tags timeline settings
|
||||
|
@ -22,10 +24,12 @@ package fr.gouv.etalab.mastodon.client.Entities;
|
|||
public class TagTimeline {
|
||||
|
||||
private String name;
|
||||
private String displayname;
|
||||
private boolean isART;
|
||||
private boolean isNSFW;
|
||||
|
||||
|
||||
private List<String> any;
|
||||
private List<String> all;
|
||||
private List<String> none;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
|
@ -50,4 +54,36 @@ public class TagTimeline {
|
|||
public void setNSFW(boolean NSFW) {
|
||||
isNSFW = NSFW;
|
||||
}
|
||||
|
||||
public List<String> getAny() {
|
||||
return any;
|
||||
}
|
||||
|
||||
public void setAny(List<String> any) {
|
||||
this.any = any;
|
||||
}
|
||||
|
||||
public List<String> getAll() {
|
||||
return all;
|
||||
}
|
||||
|
||||
public void setAll(List<String> all) {
|
||||
this.all = all;
|
||||
}
|
||||
|
||||
public List<String> getNone() {
|
||||
return none;
|
||||
}
|
||||
|
||||
public void setNone(List<String> none) {
|
||||
this.none = none;
|
||||
}
|
||||
|
||||
public String getDisplayname() {
|
||||
return displayname;
|
||||
}
|
||||
|
||||
public void setDisplayname(String displayname) {
|
||||
this.displayname = displayname;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ package fr.gouv.etalab.mastodon.client;
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License along with Mastalab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
|
@ -21,7 +22,9 @@ import android.text.Html;
|
|||
import android.text.SpannableString;
|
||||
|
||||
import com.google.common.io.ByteStreams;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
@ -49,7 +52,9 @@ import java.util.Map;
|
|||
import java.util.Scanner;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
|
||||
import fr.gouv.etalab.mastodon.R;
|
||||
import fr.gouv.etalab.mastodon.activities.MediaActivity;
|
||||
import fr.gouv.etalab.mastodon.activities.TootActivity;
|
||||
|
@ -411,6 +416,50 @@ public class HttpsConnection {
|
|||
|
||||
}
|
||||
|
||||
public String postMisskey(String urlConnection, int timeout, JSONObject paramaters, String token) throws IOException, NoSuchAlgorithmException, KeyManagementException, HttpsConnectionException {
|
||||
URL url = new URL(urlConnection);
|
||||
byte[] postDataBytes = paramaters.toString().getBytes("UTF-8");
|
||||
|
||||
if (proxy != null)
|
||||
httpsURLConnection = (HttpsURLConnection) url.openConnection(proxy);
|
||||
else
|
||||
httpsURLConnection = (HttpsURLConnection) url.openConnection();
|
||||
httpsURLConnection.setRequestProperty("User-Agent", Helper.USER_AGENT);
|
||||
httpsURLConnection.setConnectTimeout(timeout * 1000);
|
||||
httpsURLConnection.setDoOutput(true);
|
||||
httpsURLConnection.setSSLSocketFactory(new TLSSocketFactory());
|
||||
httpsURLConnection.setRequestMethod("POST");
|
||||
if (token != null)
|
||||
httpsURLConnection.setRequestProperty("Authorization", "Bearer " + token);
|
||||
httpsURLConnection.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
|
||||
|
||||
|
||||
httpsURLConnection.getOutputStream().write(postDataBytes);
|
||||
String response;
|
||||
if (httpsURLConnection.getResponseCode() >= 200 && httpsURLConnection.getResponseCode() < 400) {
|
||||
getSinceMaxId();
|
||||
response = converToString(httpsURLConnection.getInputStream());
|
||||
} else {
|
||||
String error = null;
|
||||
if( httpsURLConnection.getErrorStream() != null) {
|
||||
InputStream stream = httpsURLConnection.getErrorStream();
|
||||
if (stream == null) {
|
||||
stream = httpsURLConnection.getInputStream();
|
||||
}
|
||||
try (Scanner scanner = new Scanner(stream)) {
|
||||
scanner.useDelimiter("\\Z");
|
||||
error = scanner.next();
|
||||
}catch (Exception e){e.printStackTrace();}
|
||||
}
|
||||
int responseCode = httpsURLConnection.getResponseCode();
|
||||
throw new HttpsConnectionException(responseCode, error);
|
||||
}
|
||||
getSinceMaxId();
|
||||
httpsURLConnection.getInputStream().close();
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
* Download method which works for http and https connections
|
||||
* @param downloadUrl String download url
|
||||
|
@ -1511,7 +1560,6 @@ public class HttpsConnection {
|
|||
httpsURLConnection.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
|
||||
|
||||
httpsURLConnection.getOutputStream().write(postDataBytes);
|
||||
|
||||
if (httpsURLConnection.getResponseCode() >= 200 && httpsURLConnection.getResponseCode() < 400) {
|
||||
getSinceMaxId();
|
||||
httpsURLConnection.getInputStream().close();
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -144,7 +144,7 @@ public class AccountSearchDevAdapter extends BaseAdapter implements OnPostAction
|
|||
public void onClick(View v) {
|
||||
Intent intent = new Intent(context, ShowAccountActivity.class);
|
||||
Bundle b = new Bundle();
|
||||
b.putString("accountId", account.getId());
|
||||
b.putParcelable("account", account);
|
||||
intent.putExtras(b);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
|
|
@ -86,13 +86,13 @@ public class AccountsFollowRequestAdapter extends RecyclerView.Adapter implement
|
|||
holder.account_pp.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
openAccountDetails(account.getId());
|
||||
openAccountDetails(account);
|
||||
}
|
||||
});
|
||||
holder.account_un.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
openAccountDetails(account.getId());
|
||||
openAccountDetails(account);
|
||||
}
|
||||
});
|
||||
holder.btn_authorize.setOnClickListener(new View.OnClickListener() {
|
||||
|
@ -125,10 +125,10 @@ public class AccountsFollowRequestAdapter extends RecyclerView.Adapter implement
|
|||
return accounts.size();
|
||||
}
|
||||
|
||||
private void openAccountDetails(String userId){
|
||||
private void openAccountDetails(Account account){
|
||||
Intent intent = new Intent(context, ShowAccountActivity.class);
|
||||
Bundle b = new Bundle();
|
||||
b.putString("accountId", userId);
|
||||
b.putParcelable("account", account);
|
||||
intent.putExtras(b);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
|
|
@ -116,7 +116,7 @@ public class AccountsInAListAdapter extends RecyclerView.Adapter implements OnLi
|
|||
public void onClick(View v) {
|
||||
Intent intent = new Intent(context, ShowAccountActivity.class);
|
||||
Bundle b = new Bundle();
|
||||
b.putString("accountId", account.getId());
|
||||
b.putParcelable("account", account);
|
||||
intent.putExtras(b);
|
||||
context.startActivity(intent);
|
||||
|
||||
|
|
|
@ -16,12 +16,14 @@ package fr.gouv.etalab.mastodon.drawers;
|
|||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.text.Html;
|
||||
import android.text.util.Linkify;
|
||||
|
@ -38,9 +40,11 @@ import java.util.List;
|
|||
|
||||
import es.dmoral.toasty.Toasty;
|
||||
import fr.gouv.etalab.mastodon.R;
|
||||
import fr.gouv.etalab.mastodon.activities.MainActivity;
|
||||
import fr.gouv.etalab.mastodon.activities.ShowAccountActivity;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.PostActionAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrieveAccountsAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.UpdateAccountInfoAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.client.API;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Error;
|
||||
|
@ -92,80 +96,86 @@ public class AccountsListAdapter extends RecyclerView.Adapter implements OnPostA
|
|||
final Account account = accounts.get(position);
|
||||
|
||||
|
||||
if( action == RetrieveAccountsAsyncTask.Type.BLOCKED)
|
||||
account.setFollowType(Account.followAction.BLOCK);
|
||||
else if( action == RetrieveAccountsAsyncTask.Type.MUTED)
|
||||
account.setFollowType(Account.followAction.MUTE);
|
||||
if(MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON) {
|
||||
if (action == RetrieveAccountsAsyncTask.Type.BLOCKED)
|
||||
account.setFollowType(Account.followAction.BLOCK);
|
||||
else if (action == RetrieveAccountsAsyncTask.Type.MUTED)
|
||||
account.setFollowType(Account.followAction.MUTE);
|
||||
|
||||
if( action == RetrieveAccountsAsyncTask.Type.CHANNELS)
|
||||
account.setFollowType(Account.followAction.NOT_FOLLOW);
|
||||
if (action == RetrieveAccountsAsyncTask.Type.CHANNELS)
|
||||
account.setFollowType(Account.followAction.NOT_FOLLOW);
|
||||
holder.account_follow.setBackgroundTintList(ColorStateList.valueOf( ContextCompat.getColor(context, R.color.mastodonC4)));
|
||||
if (account.getFollowType() == Account.followAction.NOTHING) {
|
||||
holder.account_follow.hide();
|
||||
holder.account_follow_request.setVisibility(View.GONE);
|
||||
doAction = null;
|
||||
} else if (account.getFollowType() == Account.followAction.REQUEST_SENT) {
|
||||
holder.account_follow.hide();
|
||||
holder.account_follow_request.setVisibility(View.VISIBLE);
|
||||
doAction = null;
|
||||
} else if (account.getFollowType() == Account.followAction.FOLLOW) {
|
||||
holder.account_follow.setBackgroundTintList(ColorStateList.valueOf( ContextCompat.getColor(context, R.color.unfollow)));
|
||||
holder.account_follow.setImageResource(R.drawable.ic_user_times);
|
||||
doAction = API.StatusAction.UNFOLLOW;
|
||||
holder.account_follow.show();
|
||||
holder.account_follow_request.setVisibility(View.GONE);
|
||||
} else if (account.getFollowType() == Account.followAction.NOT_FOLLOW) {
|
||||
holder.account_follow.setImageResource(R.drawable.ic_user_plus);
|
||||
doAction = API.StatusAction.FOLLOW;
|
||||
holder.account_follow.show();
|
||||
holder.account_follow_request.setVisibility(View.GONE);
|
||||
} else if (account.getFollowType() == Account.followAction.BLOCK) {
|
||||
holder.account_follow.setImageResource(R.drawable.ic_lock_open);
|
||||
doAction = API.StatusAction.UNBLOCK;
|
||||
holder.account_follow.show();
|
||||
holder.account_follow_request.setVisibility(View.GONE);
|
||||
} else if (account.getFollowType() == Account.followAction.MUTE) {
|
||||
|
||||
if (account.getFollowType() == Account.followAction.NOTHING){
|
||||
if (account.isMuting_notifications())
|
||||
holder.account_mute_notification.setImageResource(R.drawable.ic_notifications_active);
|
||||
else
|
||||
holder.account_mute_notification.setImageResource(R.drawable.ic_notifications_off);
|
||||
|
||||
holder.account_mute_notification.show();
|
||||
holder.account_follow.setImageResource(R.drawable.ic_volume_up);
|
||||
doAction = API.StatusAction.UNMUTE;
|
||||
holder.account_follow.show();
|
||||
holder.account_follow_request.setVisibility(View.GONE);
|
||||
final int positionFinal = position;
|
||||
holder.account_mute_notification.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
account.setMuting_notifications(!account.isMuting_notifications());
|
||||
new PostActionAsyncTask(context, API.StatusAction.MUTE_NOTIFICATIONS, account.getId(), account.isMuting_notifications(), AccountsListAdapter.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
accountsListAdapter.notifyItemChanged(positionFinal);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (action != RetrieveAccountsAsyncTask.Type.CHANNELS) {
|
||||
holder.account_container.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (holder.account_info.getVisibility() == View.VISIBLE)
|
||||
holder.account_info.setVisibility(View.GONE);
|
||||
else
|
||||
holder.account_info.setVisibility(View.VISIBLE);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
holder.account_container.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}else {
|
||||
holder.account_follow.hide();
|
||||
holder.account_follow_request.setVisibility(View.GONE);
|
||||
doAction = null;
|
||||
}else if( account.getFollowType() == Account.followAction.REQUEST_SENT){
|
||||
holder.account_follow.hide();
|
||||
holder.account_follow_request.setVisibility(View.VISIBLE);
|
||||
doAction = null;
|
||||
}else if( account.getFollowType() == Account.followAction.FOLLOW){
|
||||
holder.account_follow.setImageResource(R.drawable.ic_user_times);
|
||||
doAction = API.StatusAction.UNFOLLOW;
|
||||
holder.account_follow.show();
|
||||
holder.account_follow_request.setVisibility(View.GONE);
|
||||
}else if( account.getFollowType() == Account.followAction.NOT_FOLLOW){
|
||||
holder.account_follow.setImageResource(R.drawable.ic_user_plus);
|
||||
doAction = API.StatusAction.FOLLOW;
|
||||
holder.account_follow.show();
|
||||
holder.account_follow_request.setVisibility(View.GONE);
|
||||
}else if( account.getFollowType() == Account.followAction.BLOCK){
|
||||
holder.account_follow.setImageResource(R.drawable.ic_lock_open);
|
||||
doAction = API.StatusAction.UNBLOCK;
|
||||
holder.account_follow.show();
|
||||
holder.account_follow_request.setVisibility(View.GONE);
|
||||
}else if( account.getFollowType() == Account.followAction.MUTE){
|
||||
|
||||
if(account.isMuting_notifications())
|
||||
holder.account_mute_notification.setImageResource(R.drawable.ic_notifications_active);
|
||||
else
|
||||
holder.account_mute_notification.setImageResource(R.drawable.ic_notifications_off);
|
||||
|
||||
holder.account_mute_notification.show();
|
||||
holder.account_follow.setImageResource(R.drawable.ic_volume_up);
|
||||
doAction = API.StatusAction.UNMUTE;
|
||||
holder.account_follow.show();
|
||||
holder.account_follow_request.setVisibility(View.GONE);
|
||||
final int positionFinal = position;
|
||||
holder.account_mute_notification.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
account.setMuting_notifications(!account.isMuting_notifications());
|
||||
new PostActionAsyncTask(context, API.StatusAction.MUTE_NOTIFICATIONS, account.getId(), account.isMuting_notifications(), AccountsListAdapter.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
accountsListAdapter.notifyItemChanged(positionFinal);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if( action != RetrieveAccountsAsyncTask.Type.CHANNELS){
|
||||
holder.account_container.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if( holder.account_info.getVisibility() == View.VISIBLE)
|
||||
holder.account_info.setVisibility(View.GONE);
|
||||
else
|
||||
holder.account_info.setVisibility(View.VISIBLE);
|
||||
}
|
||||
});
|
||||
}else{
|
||||
holder.account_container.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
account.makeEmojisAccount(context, AccountsListAdapter.this, account);
|
||||
account.makeAccountNameEmoji(context, AccountsListAdapter.this, account);
|
||||
if( account.getdisplayNameSpan() == null || account.getdisplayNameSpan().toString().trim().equals("")) {
|
||||
if( account.getDisplay_name() != null && !account.getDisplay_name().trim().equals(""))
|
||||
holder.account_dn.setText(Helper.shortnameToUnicode(account.getDisplay_name(), true));
|
||||
|
@ -212,12 +222,17 @@ public class AccountsListAdapter extends RecyclerView.Adapter implements OnPostA
|
|||
holder.account_pp.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if(action != RetrieveAccountsAsyncTask.Type.CHANNELS) {
|
||||
if(MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE || action != RetrieveAccountsAsyncTask.Type.CHANNELS) {
|
||||
//Avoid to reopen details about the current account
|
||||
if (targetedId == null || !targetedId.equals(account.getId())) {
|
||||
Intent intent = new Intent(context, ShowAccountActivity.class);
|
||||
Bundle b = new Bundle();
|
||||
b.putString("accountId", account.getId());
|
||||
if(MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE) {
|
||||
b.putBoolean("peertubeaccount", true);
|
||||
b.putBoolean("ischannel", true);
|
||||
b.putString("targetedid", account.getAcct());
|
||||
}
|
||||
b.putParcelable("account", account);
|
||||
intent.putExtras(b);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,378 @@
|
|||
package fr.gouv.etalab.mastodon.drawers;
|
||||
/* Copyright 2019 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Mastalab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Mastalab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.resource.bitmap.FitCenter;
|
||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import es.dmoral.toasty.Toasty;
|
||||
import fr.gouv.etalab.mastodon.R;
|
||||
import fr.gouv.etalab.mastodon.activities.MediaActivity;
|
||||
import fr.gouv.etalab.mastodon.activities.ShowAccountActivity;
|
||||
import fr.gouv.etalab.mastodon.activities.ShowConversationActivity;
|
||||
import fr.gouv.etalab.mastodon.client.API;
|
||||
import fr.gouv.etalab.mastodon.client.APIResponse;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Attachment;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Emojis;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Error;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Notification;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Status;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnPostActionInterface;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveEmojiInterface;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveRepliesInterface;
|
||||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||
import fr.gouv.etalab.mastodon.sqlite.StatusCacheDAO;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Created by Thomas on 14/01/2019.
|
||||
* Adapter for art drawer
|
||||
*/
|
||||
public class ArtListAdapter extends RecyclerView.Adapter implements OnPostActionInterface, OnRetrieveEmojiInterface, OnRetrieveRepliesInterface {
|
||||
|
||||
private Context context;
|
||||
private List<Status> statuses;
|
||||
private LayoutInflater layoutInflater;
|
||||
private ArtListAdapter statusListAdapter;
|
||||
private final int HIDDEN_STATUS = 0;
|
||||
private static final int DISPLAYED_STATUS = 1;
|
||||
private List<String> timedMute;
|
||||
|
||||
|
||||
public ArtListAdapter(Context context, List<Status> statuses){
|
||||
this.context = context;
|
||||
this.statuses = statuses;
|
||||
layoutInflater = LayoutInflater.from(this.context);
|
||||
statusListAdapter = this;
|
||||
}
|
||||
|
||||
public void updateMuted(List<String> timedMute){
|
||||
this.timedMute = timedMute;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return statuses.size();
|
||||
}
|
||||
|
||||
private Status getItemAt(int position){
|
||||
if( statuses.size() > position)
|
||||
return statuses.get(position);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRetrieveReplies(APIResponse apiResponse) {
|
||||
if( apiResponse.getError() != null || apiResponse.getStatuses() == null || apiResponse.getStatuses().size() == 0){
|
||||
return;
|
||||
}
|
||||
List<Status> modifiedStatus = apiResponse.getStatuses();
|
||||
notifyStatusChanged(modifiedStatus.get(0));
|
||||
}
|
||||
|
||||
|
||||
private class ViewHolderEmpty extends RecyclerView.ViewHolder{
|
||||
ViewHolderEmpty(View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewAttachedToWindow(@NonNull RecyclerView.ViewHolder holder) {
|
||||
super.onViewAttachedToWindow(holder);
|
||||
}
|
||||
|
||||
|
||||
private class ViewHolderArt extends RecyclerView.ViewHolder{
|
||||
ImageView art_media, art_pp;
|
||||
TextView art_username, art_acct;
|
||||
LinearLayout art_author;
|
||||
RelativeLayout status_show_more;
|
||||
ImageView show_more_button_art;
|
||||
ViewHolderArt(View itemView) {
|
||||
super(itemView);
|
||||
art_media = itemView.findViewById(R.id.art_media);
|
||||
art_pp = itemView.findViewById(R.id.art_pp);
|
||||
art_username = itemView.findViewById(R.id.art_username);
|
||||
art_acct = itemView.findViewById(R.id.art_acct);
|
||||
art_author = itemView.findViewById(R.id.art_author);
|
||||
status_show_more = itemView.findViewById(R.id.status_show_more);
|
||||
show_more_button_art = itemView.findViewById(R.id.show_more_button_art);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public Status getItem(int position){
|
||||
if( statuses.size() > position && position >= 0)
|
||||
return statuses.get(position);
|
||||
else return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
|
||||
if( !Helper.filterToots(context, statuses.get(position), timedMute, null))
|
||||
return HIDDEN_STATUS;
|
||||
else
|
||||
return DISPLAYED_STATUS;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
if( viewType != HIDDEN_STATUS)
|
||||
return new ViewHolderArt(layoutInflater.inflate(R.layout.drawer_art, parent, false));
|
||||
else
|
||||
return new ViewHolderEmpty(layoutInflater.inflate(R.layout.drawer_empty, parent, false));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@SuppressLint("SetJavaScriptEnabled")
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder viewHolder, int i) {
|
||||
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
final String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
if( viewHolder.getItemViewType() != HIDDEN_STATUS ) {
|
||||
final ViewHolderArt holder = (ViewHolderArt) viewHolder;
|
||||
final Status status = statuses.get(viewHolder.getAdapterPosition());
|
||||
if (!status.isClickable())
|
||||
Status.transform(context, status);
|
||||
if (!status.isEmojiFound())
|
||||
Status.makeEmojis(context, this, status);
|
||||
|
||||
if (status.getAccount() != null && status.getAccount().getAvatar() != null)
|
||||
Glide.with(context)
|
||||
.load(status.getAccount().getAvatar())
|
||||
.apply(new RequestOptions().transforms(new FitCenter(), new RoundedCorners(10)))
|
||||
.into(holder.art_pp);
|
||||
|
||||
if (status.getArt_attachment() != null)
|
||||
Glide.with(context)
|
||||
.load(status.getArt_attachment().getPreview_url())
|
||||
.into(holder.art_media);
|
||||
holder.art_pp.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(context, ShowAccountActivity.class);
|
||||
Bundle b = new Bundle();
|
||||
b.putParcelable("account", status.getAccount());
|
||||
intent.putExtras(b);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
});
|
||||
|
||||
holder.art_media.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(context, MediaActivity.class);
|
||||
Bundle b = new Bundle();
|
||||
ArrayList<Attachment> attachments = new ArrayList<>();
|
||||
if (status.getArt_attachment() != null)
|
||||
attachments.add(status.getArt_attachment());
|
||||
else if (status.getMedia_attachments() != null && status.getMedia_attachments().size() > 0)
|
||||
attachments.add(status.getMedia_attachments().get(0));
|
||||
intent.putParcelableArrayListExtra("mediaArray", attachments);
|
||||
b.putInt("position", 0);
|
||||
intent.putExtras(b);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
});
|
||||
holder.art_author.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(context, ShowConversationActivity.class);
|
||||
Bundle b = new Bundle();
|
||||
b.putParcelable("status", status);
|
||||
intent.putExtras(b);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
});
|
||||
|
||||
if (status.getDisplayNameSpan() != null && status.getDisplayNameSpan().toString().trim().length() > 0)
|
||||
holder.art_username.setText(status.getDisplayNameSpan(), TextView.BufferType.SPANNABLE);
|
||||
else
|
||||
holder.art_username.setText(status.getAccount().getUsername());
|
||||
|
||||
holder.art_acct.setText(String.format("@%s", status.getAccount().getAcct()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onPostAction(int statusCode, API.StatusAction statusAction, String targetedId, Error error) {
|
||||
|
||||
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
if( error != null){
|
||||
Toasty.error(context, error.getError(),Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
Helper.manageMessageStatusCode(context, statusCode, statusAction);
|
||||
//When muting or blocking an account, its status are removed from the list
|
||||
List<Status> statusesToRemove = new ArrayList<>();
|
||||
if( statusAction == API.StatusAction.MUTE || statusAction == API.StatusAction.BLOCK){
|
||||
for(Status status: statuses){
|
||||
if( status.getAccount().getId().equals(targetedId))
|
||||
statusesToRemove.add(status);
|
||||
}
|
||||
statuses.removeAll(statusesToRemove);
|
||||
statusListAdapter.notifyDataSetChanged();
|
||||
}else if( statusAction == API.StatusAction.UNSTATUS ){
|
||||
int position = 0;
|
||||
for(Status status: statuses){
|
||||
if( status.getId().equals(targetedId)) {
|
||||
statuses.remove(status);
|
||||
statusListAdapter.notifyItemRemoved(position);
|
||||
SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
//Remove the status from cache also
|
||||
try {
|
||||
new StatusCacheDAO(context, db).remove(StatusCacheDAO.ARCHIVE_CACHE,status);
|
||||
}catch (Exception ignored){}
|
||||
break;
|
||||
}
|
||||
position++;
|
||||
}
|
||||
}
|
||||
else if ( statusAction == API.StatusAction.PIN || statusAction == API.StatusAction.UNPIN ) {
|
||||
int position = 0;
|
||||
for (Status status: statuses) {
|
||||
if (status.getId().equals(targetedId)) {
|
||||
if (statusAction == API.StatusAction.PIN)
|
||||
status.setPinned(true);
|
||||
else
|
||||
status.setPinned(false);
|
||||
statusListAdapter.notifyItemChanged(position);
|
||||
break;
|
||||
}
|
||||
position++;
|
||||
}
|
||||
}
|
||||
if( statusAction == API.StatusAction.PEERTUBEDELETECOMMENT){
|
||||
int position = 0;
|
||||
for(Status status: statuses){
|
||||
if( status.getId().equals(targetedId)) {
|
||||
statuses.remove(status);
|
||||
statusListAdapter.notifyItemRemoved(position);
|
||||
break;
|
||||
}
|
||||
position++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyStatusChanged(Status status){
|
||||
for (int i = 0; i < statusListAdapter.getItemCount(); i++) {
|
||||
//noinspection ConstantConditions
|
||||
if (statusListAdapter.getItemAt(i) != null && statusListAdapter.getItemAt(i).getId().equals(status.getId())) {
|
||||
try {
|
||||
statusListAdapter.notifyItemChanged(i);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyStatusWithActionChanged(API.StatusAction statusAction, Status status){
|
||||
for (int i = 0; i < statusListAdapter.getItemCount(); i++) {
|
||||
//noinspection ConstantConditions
|
||||
if (statusListAdapter.getItemAt(i) != null && statusListAdapter.getItemAt(i).getId().equals(status.getId())) {
|
||||
try {
|
||||
int favCount = statuses.get(i).getFavourites_count();
|
||||
int boostCount = statuses.get(i).getReblogs_count();
|
||||
if( statusAction == API.StatusAction.REBLOG)
|
||||
boostCount++;
|
||||
else if( statusAction == API.StatusAction.UNREBLOG)
|
||||
boostCount--;
|
||||
else if( statusAction == API.StatusAction.FAVOURITE)
|
||||
favCount++;
|
||||
else if( statusAction == API.StatusAction.UNFAVOURITE)
|
||||
favCount--;
|
||||
if( boostCount < 0 )
|
||||
boostCount = 0;
|
||||
if( favCount < 0 )
|
||||
favCount = 0;
|
||||
statuses.get(i).setFavourited(status.isFavourited());
|
||||
statuses.get(i).setFavourites_count(favCount);
|
||||
statuses.get(i).setReblogged(status.isReblogged());
|
||||
statuses.get(i).setReblogs_count(boostCount);
|
||||
statusListAdapter.notifyItemChanged(i);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onRetrieveEmoji(Status status, boolean fromTranslation) {
|
||||
if( status != null) {
|
||||
if( !fromTranslation) {
|
||||
status.setEmojiFound(true);
|
||||
}else {
|
||||
status.setEmojiTranslateFound(true);
|
||||
}
|
||||
notifyStatusChanged(status);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRetrieveEmoji(Notification notification) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRetrieveSearchEmoji(List<Emojis> emojis) {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -159,6 +159,7 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On
|
|||
style = R.style.Dialog;
|
||||
}
|
||||
Drawable imgH = null;
|
||||
holder.status_date.setVisibility(View.VISIBLE);
|
||||
switch (type){
|
||||
case "mention":
|
||||
holder.status_action_container.setVisibility(View.VISIBLE);
|
||||
|
@ -222,6 +223,7 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On
|
|||
break;
|
||||
case "follow":
|
||||
holder.status_action_container.setVisibility(View.GONE);
|
||||
holder.status_date.setVisibility(View.GONE);
|
||||
if( notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0)
|
||||
typeString = String.format("%s %s", Helper.shortnameToUnicode(notification.getAccount().getDisplay_name(), true),context.getString(R.string.notif_follow));
|
||||
else
|
||||
|
@ -253,10 +255,11 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On
|
|||
|
||||
if( notification.getAccount().getdisplayNameSpan() == null) {
|
||||
holder.notification_type.setText(typeString);
|
||||
notification.getAccount().setStored_displayname(notification.getAccount().getDisplay_name());
|
||||
notification.getAccount().setDisplay_name(typeString);
|
||||
}else
|
||||
holder.notification_type.setText(notification.getAccount().getdisplayNameSpan(), TextView.BufferType.SPANNABLE);
|
||||
notification.getAccount().makeEmojisAccount(context, NotificationsListAdapter.this, notification.getAccount());
|
||||
notification.getAccount().makeAccountNameEmoji(context, NotificationsListAdapter.this, notification.getAccount());
|
||||
if( imgH != null) {
|
||||
holder.notification_type.setCompoundDrawablePadding((int)Helper.convertDpToPixel(5, context));
|
||||
imgH.setBounds(0, 0, (int) (20 * iconSizePercent / 100 * scale + 0.5f), (int) (20 * iconSizePercent / 100 * scale + 0.5f));
|
||||
|
@ -338,7 +341,7 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On
|
|||
if( !status.isClickable())
|
||||
Status.transform(context, status);
|
||||
if( !status.isEmojiFound())
|
||||
Status.makeEmojis(context, NotificationsListAdapter.this, status);
|
||||
Notification.makeEmojis(context, NotificationsListAdapter.this, notification);
|
||||
holder.notification_status_content.setText(status.getContentSpan(), TextView.BufferType.SPANNABLE);
|
||||
holder.status_spoiler.setText(status.getContentSpanCW(), TextView.BufferType.SPANNABLE);
|
||||
holder.status_spoiler.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
|
@ -642,7 +645,8 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On
|
|||
public void onClick(View v) {
|
||||
Intent intent = new Intent(context, ShowAccountActivity.class);
|
||||
Bundle b = new Bundle();
|
||||
b.putString("accountId", notification.getAccount().getId());
|
||||
notification.getAccount().setDisplay_name(notification.getAccount().getStored_displayname());
|
||||
b.putParcelable("account", notification.getAccount());
|
||||
intent.putExtras(b);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
@ -851,6 +855,39 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public void notifyNotificationWithActionChanged(API.StatusAction statusAction, Status status){
|
||||
for (int i = 0; i < notificationsListAdapter.getItemCount(); i++) {
|
||||
if (notificationsListAdapter.getItemAt(i) != null && notificationsListAdapter.getItemAt(i).getType().toLowerCase().equals("mention") && notificationsListAdapter.getItemAt(i).getStatus() != null && notificationsListAdapter.getItemAt(i).getStatus().getId().equals(status.getId())) {
|
||||
try {
|
||||
if( notifications.get(i).getStatus() != null){
|
||||
int favCount = notifications.get(i).getStatus().getFavourites_count();
|
||||
int boostCount = notifications.get(i).getStatus().getReblogs_count();
|
||||
if( statusAction == API.StatusAction.REBLOG)
|
||||
boostCount++;
|
||||
else if( statusAction == API.StatusAction.UNREBLOG)
|
||||
boostCount--;
|
||||
else if( statusAction == API.StatusAction.FAVOURITE)
|
||||
favCount++;
|
||||
else if( statusAction == API.StatusAction.UNFAVOURITE)
|
||||
favCount--;
|
||||
if( boostCount < 0 )
|
||||
boostCount = 0;
|
||||
if( favCount < 0 )
|
||||
favCount = 0;
|
||||
notifications.get(i).getStatus().setFavourited(status.isFavourited());
|
||||
notifications.get(i).getStatus().setFavourites_count(favCount);
|
||||
notifications.get(i).getStatus().setReblogged(status.isReblogged());
|
||||
notifications.get(i).getStatus().setReblogs_count(boostCount);
|
||||
break;
|
||||
}
|
||||
notificationsListAdapter.notifyItemChanged(i);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
|
@ -919,57 +956,12 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On
|
|||
List<Notification> notificationsToRemove = new ArrayList<>();
|
||||
if( statusAction == API.StatusAction.MUTE || statusAction == API.StatusAction.BLOCK){
|
||||
for(Notification notification: notifications){
|
||||
if( notification.getType().equals("mention") && notification.getAccount().getId().equals(targetedId))
|
||||
if( notification.getType().toLowerCase().equals("mention") && notification.getAccount().getId().equals(targetedId))
|
||||
notificationsToRemove.add(notification);
|
||||
}
|
||||
notifications.removeAll(notificationsToRemove);
|
||||
notificationsListAdapter.notifyDataSetChanged();
|
||||
}
|
||||
if( targetedId != null ) {
|
||||
if (statusAction == API.StatusAction.REBLOG) {
|
||||
int position = 0;
|
||||
for (Notification notification : notifications) {
|
||||
if (notification.getStatus() != null && notification.getStatus().getId().equals(targetedId)) {
|
||||
notification.getStatus().setReblogs_count(notification.getStatus().getReblogs_count() + 1);
|
||||
notificationsListAdapter.notifyItemChanged(position);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
} else if (statusAction == API.StatusAction.UNREBLOG) {
|
||||
int position = 0;
|
||||
for (Notification notification : notifications) {
|
||||
if (notification.getStatus() != null && notification.getStatus().getId().equals(targetedId)) {
|
||||
if (notification.getStatus().getReblogs_count() - 1 >= 0)
|
||||
notification.getStatus().setReblogs_count(notification.getStatus().getReblogs_count() - 1);
|
||||
notificationsListAdapter.notifyItemChanged(position);
|
||||
break;
|
||||
}
|
||||
position++;
|
||||
}
|
||||
} else if (statusAction == API.StatusAction.FAVOURITE) {
|
||||
int position = 0;
|
||||
for (Notification notification : notifications) {
|
||||
if (notification.getStatus() != null && notification.getStatus().getId().equals(targetedId)) {
|
||||
notification.getStatus().setFavourites_count(notification.getStatus().getFavourites_count() + 1);
|
||||
notificationsListAdapter.notifyItemChanged(position);
|
||||
break;
|
||||
}
|
||||
position++;
|
||||
}
|
||||
} else if (statusAction == API.StatusAction.UNFAVOURITE) {
|
||||
int position = 0;
|
||||
for (Notification notification : notifications) {
|
||||
if (notification.getStatus() != null && notification.getStatus().getId().equals(targetedId)) {
|
||||
if (notification.getStatus().getFavourites_count() - 1 >= 0)
|
||||
notification.getStatus().setFavourites_count(notification.getStatus().getFavourites_count() - 1);
|
||||
notificationsListAdapter.notifyItemChanged(position);
|
||||
break;
|
||||
}
|
||||
position++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1031,25 +1023,25 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On
|
|||
ImageView imageView;
|
||||
if( i == 0) {
|
||||
imageView = holder.status_prev1;
|
||||
if( attachment.getType().equals("image"))
|
||||
if( attachment.getType().toLowerCase().equals("image"))
|
||||
holder.status_prev1_play.setVisibility(View.GONE);
|
||||
else
|
||||
holder.status_prev1_play.setVisibility(View.VISIBLE);
|
||||
}else if( i == 1) {
|
||||
imageView = holder.status_prev2;
|
||||
if( attachment.getType().equals("image"))
|
||||
if( attachment.getType().toLowerCase().equals("image"))
|
||||
holder.status_prev2_play.setVisibility(View.GONE);
|
||||
else
|
||||
holder.status_prev2_play.setVisibility(View.VISIBLE);
|
||||
}else if(i == 2) {
|
||||
imageView = holder.status_prev3;
|
||||
if( attachment.getType().equals("image"))
|
||||
if( attachment.getType().toLowerCase().equals("image"))
|
||||
holder.status_prev3_play.setVisibility(View.GONE);
|
||||
else
|
||||
holder.status_prev3_play.setVisibility(View.VISIBLE);
|
||||
}else {
|
||||
imageView = holder.status_prev4;
|
||||
if( attachment.getType().equals("image"))
|
||||
if( attachment.getType().toLowerCase().equals("image"))
|
||||
holder.status_prev4_play.setVisibility(View.GONE);
|
||||
else
|
||||
holder.status_prev4_play.setVisibility(View.VISIBLE);
|
||||
|
@ -1085,18 +1077,14 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On
|
|||
|
||||
@Override
|
||||
public void onRetrieveEmoji(Status status, boolean fromTranslation) {
|
||||
if( !status.isEmojiFound()) {
|
||||
for (int i = 0; i < notificationsListAdapter.getItemCount(); i++) {
|
||||
if (notificationsListAdapter.getItemAt(i) != null && notificationsListAdapter.getItemAt(i).getStatus() != null && notificationsListAdapter.getItemAt(i).getStatus().getId().equals(status.getId())) {
|
||||
if( notificationsListAdapter.getItemAt(i).getStatus() != null) {
|
||||
notificationsListAdapter.getItemAt(i).getStatus().setEmojiFound(true);
|
||||
try {
|
||||
notificationsListAdapter.notifyItemChanged(i);
|
||||
}catch (Exception ignored){}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRetrieveEmoji(Notification notification) {
|
||||
if( notification != null && notification.getStatus() != null) {
|
||||
notification.getStatus().setEmojiFound(true);
|
||||
notifyNotificationChanged(notification);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,8 +35,12 @@ import java.util.regex.Matcher;
|
|||
import java.util.regex.Pattern;
|
||||
|
||||
import fr.gouv.etalab.mastodon.R;
|
||||
import fr.gouv.etalab.mastodon.activities.MainActivity;
|
||||
import fr.gouv.etalab.mastodon.activities.PeertubeActivity;
|
||||
import fr.gouv.etalab.mastodon.activities.PeertubeEditUploadActivity;
|
||||
import fr.gouv.etalab.mastodon.activities.ShowAccountActivity;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.ManageListsAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.UpdateAccountInfoAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.client.APIResponse;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Peertube;
|
||||
|
@ -56,15 +60,25 @@ public class PeertubeAdapter extends RecyclerView.Adapter implements OnListActio
|
|||
private LayoutInflater layoutInflater;
|
||||
private Context context;
|
||||
private String instance;
|
||||
private boolean ownVideos;
|
||||
|
||||
public PeertubeAdapter(Context context, String instance, List<Peertube> peertubes){
|
||||
this.peertubes = peertubes;
|
||||
layoutInflater = LayoutInflater.from(context);
|
||||
this.context = context;
|
||||
this.instance = instance;
|
||||
this.ownVideos = false;
|
||||
|
||||
}
|
||||
|
||||
public PeertubeAdapter(Context context, String instance, boolean ownVideos, List<Peertube> peertubes){
|
||||
this.peertubes = peertubes;
|
||||
layoutInflater = LayoutInflater.from(context);
|
||||
this.context = context;
|
||||
this.instance = instance;
|
||||
this.ownVideos = ownVideos;
|
||||
}
|
||||
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
|
@ -78,6 +92,8 @@ public class PeertubeAdapter extends RecyclerView.Adapter implements OnListActio
|
|||
|
||||
final PeertubeAdapter.ViewHolder holder = (PeertubeAdapter.ViewHolder) viewHolder;
|
||||
final Peertube peertube = peertubes.get(position);
|
||||
if( peertube.getInstance() == null)
|
||||
peertube.setInstance(Helper.getLiveInstance(context));
|
||||
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
|
||||
if( theme == Helper.THEME_LIGHT){
|
||||
|
@ -96,34 +112,80 @@ public class PeertubeAdapter extends RecyclerView.Adapter implements OnListActio
|
|||
holder.peertube_date.setText(String.format(" - %s", Helper.dateDiff(context, peertube.getCreated_at())));
|
||||
holder.peertube_views.setText(context.getString(R.string.number_view_video, Helper.withSuffix(peertube.getView())));
|
||||
|
||||
holder.peertube_profile.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
CrossActions.doCrossProfile(context, account);
|
||||
}
|
||||
});
|
||||
|
||||
Glide.with(holder.peertube_video_image.getContext())
|
||||
.load("https://" + peertube.getInstance() + peertube.getThumbnailPath())
|
||||
.into(holder.peertube_video_image);
|
||||
if (account.getAvatar() != null && !account.getAvatar().equals("null") && !account.getAvatar().startsWith("http"))
|
||||
account.setAvatar("https://" + peertube.getInstance() + account.getAvatar());
|
||||
Helper.loadGiF(context, account.getAvatar(), holder.peertube_profile);
|
||||
holder.main_container.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(context, PeertubeActivity.class);
|
||||
Bundle b = new Bundle();
|
||||
String finalUrl = "https://" + instance + peertube.getEmbedPath();
|
||||
Pattern link = Pattern.compile("(https?:\\/\\/[\\da-z\\.-]+\\.[a-z\\.]{2,10})\\/videos\\/embed\\/(\\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12})$");
|
||||
Matcher matcherLink = link.matcher(finalUrl);
|
||||
if( matcherLink.find()) {
|
||||
String url = matcherLink.group(1) + "/videos/watch/" + matcherLink.group(2);
|
||||
b.putString("peertubeLinkToFetch", url);
|
||||
b.putString("peertube_instance", matcherLink.group(1).replace("https://","").replace("http://",""));
|
||||
b.putString("video_id", matcherLink.group(2));
|
||||
}
|
||||
intent.putExtras(b);
|
||||
context.startActivity(intent);
|
||||
|
||||
|
||||
if( peertube.getHeaderType() != null && peertube.getHeaderTypeValue() != null) {
|
||||
String type = peertube.getHeaderType();
|
||||
switch (type){
|
||||
case "tags":
|
||||
holder.header_title.setText(String.format("#%s", peertube.getHeaderTypeValue()));
|
||||
break;
|
||||
default:
|
||||
holder.header_title.setText(peertube.getHeaderTypeValue());
|
||||
break;
|
||||
}
|
||||
});
|
||||
holder.header_title.setVisibility(View.VISIBLE);
|
||||
}else {
|
||||
holder.header_title.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if( !this.ownVideos) {
|
||||
holder.peertube_profile.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
//For remote peertube instance
|
||||
if (!peertube.getInstance().equals(Helper.getLiveInstance(context)))
|
||||
CrossActions.doCrossProfile(context, account);
|
||||
else {
|
||||
Intent intent = new Intent(context, ShowAccountActivity.class);
|
||||
Bundle b = new Bundle();
|
||||
b.putBoolean("peertubeaccount", true);
|
||||
b.putParcelable("account", peertube.getAccount());
|
||||
|
||||
intent.putExtras(b);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
}
|
||||
});
|
||||
holder.main_container.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(context, PeertubeActivity.class);
|
||||
Bundle b = new Bundle();
|
||||
if ((instance == null || instance.trim().length() == 0) && MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE)
|
||||
instance = Helper.getLiveInstance(context);
|
||||
String finalUrl = "https://" + instance + peertube.getEmbedPath();
|
||||
Pattern link = Pattern.compile("(https?:\\/\\/[\\da-z\\.-]+\\.[a-z\\.]{2,10})\\/videos\\/embed\\/(\\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12})$");
|
||||
Matcher matcherLink = link.matcher(finalUrl);
|
||||
if (matcherLink.find()) {
|
||||
String url = matcherLink.group(1) + "/videos/watch/" + matcherLink.group(2);
|
||||
b.putString("peertubeLinkToFetch", url);
|
||||
b.putString("peertube_instance", matcherLink.group(1).replace("https://", "").replace("http://", ""));
|
||||
b.putString("video_id", matcherLink.group(2));
|
||||
}
|
||||
intent.putExtras(b);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
});
|
||||
}else{
|
||||
holder.main_container.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(context, PeertubeEditUploadActivity.class);
|
||||
Bundle b = new Bundle();
|
||||
b.putString("video_id",peertube.getUuid());
|
||||
intent.putExtras(b);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -147,7 +209,7 @@ public class PeertubeAdapter extends RecyclerView.Adapter implements OnListActio
|
|||
LinearLayout main_container;
|
||||
ImageView peertube_profile, peertube_video_image;
|
||||
TextView peertube_account_name, peertube_views, peertube_duration;
|
||||
TextView peertube_title, peertube_date;
|
||||
TextView peertube_title, peertube_date, header_title;
|
||||
|
||||
public ViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
|
@ -159,6 +221,7 @@ public class PeertubeAdapter extends RecyclerView.Adapter implements OnListActio
|
|||
peertube_views = itemView.findViewById(R.id.peertube_views);
|
||||
peertube_duration = itemView.findViewById(R.id.peertube_duration);
|
||||
main_container = itemView.findViewById(R.id.main_container);
|
||||
header_title = itemView.findViewById(R.id.header_title);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,516 @@
|
|||
package fr.gouv.etalab.mastodon.drawers;
|
||||
/* Copyright 2019 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Mastalab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Mastalab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.widget.CardView;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.DataSource;
|
||||
import com.bumptech.glide.load.engine.GlideException;
|
||||
import com.bumptech.glide.load.resource.bitmap.FitCenter;
|
||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
||||
import com.bumptech.glide.request.RequestListener;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.bumptech.glide.request.target.Target;
|
||||
import com.varunest.sparkbutton.SparkButton;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import es.dmoral.toasty.Toasty;
|
||||
import fr.gouv.etalab.mastodon.R;
|
||||
import fr.gouv.etalab.mastodon.activities.MainActivity;
|
||||
import fr.gouv.etalab.mastodon.activities.MediaActivity;
|
||||
import fr.gouv.etalab.mastodon.activities.ShowAccountActivity;
|
||||
import fr.gouv.etalab.mastodon.activities.ShowConversationActivity;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrieveFeedsAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.UpdateAccountInfoAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.client.API;
|
||||
import fr.gouv.etalab.mastodon.client.APIResponse;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Attachment;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Emojis;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Error;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Notification;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Status;
|
||||
import fr.gouv.etalab.mastodon.client.Glide.GlideApp;
|
||||
import fr.gouv.etalab.mastodon.helper.CrossActions;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnPostActionInterface;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveEmojiInterface;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveRepliesInterface;
|
||||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||
import fr.gouv.etalab.mastodon.sqlite.StatusCacheDAO;
|
||||
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.changeDrawableColor;
|
||||
|
||||
|
||||
/**
|
||||
* Created by Thomas on 14/01/2019.
|
||||
* Adapter for pixelfed drawer
|
||||
*/
|
||||
public class PixelfedListAdapter extends RecyclerView.Adapter implements OnPostActionInterface, OnRetrieveEmojiInterface, OnRetrieveRepliesInterface {
|
||||
|
||||
private Context context;
|
||||
private List<Status> statuses;
|
||||
private LayoutInflater layoutInflater;
|
||||
private PixelfedListAdapter pixelfedListAdapter;
|
||||
private final int HIDDEN_STATUS = 0;
|
||||
private static final int DISPLAYED_STATUS = 1;
|
||||
private List<String> timedMute;
|
||||
private RetrieveFeedsAsyncTask.Type type;
|
||||
|
||||
public PixelfedListAdapter(Context context, RetrieveFeedsAsyncTask.Type type, List<Status> statuses){
|
||||
super();
|
||||
this.context = context;
|
||||
this.statuses = statuses;
|
||||
this.type = type;
|
||||
layoutInflater = LayoutInflater.from(this.context);
|
||||
pixelfedListAdapter = this;
|
||||
}
|
||||
|
||||
|
||||
public void updateMuted(List<String> timedMute){
|
||||
this.timedMute = timedMute;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return statuses.size();
|
||||
}
|
||||
|
||||
private Status getItemAt(int position){
|
||||
if( statuses.size() > position)
|
||||
return statuses.get(position);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRetrieveReplies(APIResponse apiResponse) {
|
||||
if( apiResponse.getError() != null || apiResponse.getStatuses() == null || apiResponse.getStatuses().size() == 0){
|
||||
return;
|
||||
}
|
||||
List<Status> modifiedStatus = apiResponse.getStatuses();
|
||||
notifyStatusChanged(modifiedStatus.get(0));
|
||||
}
|
||||
|
||||
|
||||
private class ViewHolderEmpty extends RecyclerView.ViewHolder{
|
||||
ViewHolderEmpty(View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewAttachedToWindow(@NonNull RecyclerView.ViewHolder holder) {
|
||||
super.onViewAttachedToWindow(holder);
|
||||
}
|
||||
|
||||
|
||||
private class ViewHolderPixelfed extends RecyclerView.ViewHolder{
|
||||
ImageView art_media, pf_pp, pf_comment;
|
||||
SparkButton pf_fav, pf_share;
|
||||
TextView pf_username, pf_likes, pf_description, pf_date;
|
||||
CardView pf_cardview;
|
||||
LinearLayout pf_bottom_container;
|
||||
ViewHolderPixelfed(View itemView) {
|
||||
super(itemView);
|
||||
art_media = itemView.findViewById(R.id.art_media);
|
||||
pf_pp = itemView.findViewById(R.id.pf_pp);
|
||||
pf_username = itemView.findViewById(R.id.pf_username);
|
||||
pf_likes = itemView.findViewById(R.id.pf_likes);
|
||||
pf_description = itemView.findViewById(R.id.pf_description);
|
||||
pf_date = itemView.findViewById(R.id.pf_date);
|
||||
pf_fav = itemView.findViewById(R.id.pf_fav);
|
||||
pf_comment = itemView.findViewById(R.id.pf_comment);
|
||||
pf_share = itemView.findViewById(R.id.pf_share);
|
||||
pf_cardview = itemView.findViewById(R.id.pf_cardview);
|
||||
pf_bottom_container = itemView.findViewById(R.id.pf_bottom_container);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public Status getItem(int position){
|
||||
if( statuses.size() > position && position >= 0)
|
||||
return statuses.get(position);
|
||||
else return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
|
||||
if( !Helper.filterToots(context, statuses.get(position), timedMute, null))
|
||||
return HIDDEN_STATUS;
|
||||
else
|
||||
return DISPLAYED_STATUS;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
if( viewType == DISPLAYED_STATUS)
|
||||
return new ViewHolderPixelfed(layoutInflater.inflate(R.layout.drawer_pixelfed, parent, false));
|
||||
else
|
||||
return new ViewHolderEmpty(layoutInflater.inflate(R.layout.drawer_empty, parent, false));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@SuppressLint("SetJavaScriptEnabled")
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder viewHolder, int i) {
|
||||
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
final String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
if( viewHolder.getItemViewType() != HIDDEN_STATUS ) {
|
||||
final ViewHolderPixelfed holder = (ViewHolderPixelfed) viewHolder;
|
||||
final Status status = statuses.get(viewHolder.getAdapterPosition());
|
||||
if (!status.isClickable())
|
||||
Status.transform(context, status);
|
||||
if (!status.isEmojiFound())
|
||||
Status.makeEmojis(context, this, status);
|
||||
|
||||
if (status.getAccount() != null && status.getAccount().getAvatar() != null)
|
||||
Glide.with(context)
|
||||
.load(status.getAccount().getAvatar())
|
||||
.apply(new RequestOptions().transforms(new FitCenter(), new RoundedCorners(270)))
|
||||
.into(holder.pf_pp);
|
||||
|
||||
boolean expand_media = sharedpreferences.getBoolean(Helper.SET_EXPAND_MEDIA, false);
|
||||
if (status.getMedia_attachments() != null && status.getMedia_attachments().size() > 0)
|
||||
GlideApp.with(context)
|
||||
.asBitmap()
|
||||
.load(status.getMedia_attachments().get(0).getPreview_url())
|
||||
.listener(new RequestListener<Bitmap>() {
|
||||
@Override
|
||||
public boolean onResourceReady(Bitmap resource, Object model, Target<Bitmap> target, DataSource dataSource, boolean isFirstResource) {
|
||||
if (status.isSensitive())
|
||||
notifyStatusChanged(status);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.into(holder.art_media);
|
||||
|
||||
holder.pf_likes.setText(context.getResources().getQuantityString(R.plurals.likes, status.getFavourites_count(), status.getFavourites_count()));
|
||||
holder.pf_pp.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (MainActivity.social != UpdateAccountInfoAsyncTask.SOCIAL.PIXELFED) {
|
||||
CrossActions.doCrossProfile(context, status.getAccount());
|
||||
} else {
|
||||
Intent intent = new Intent(context, ShowAccountActivity.class);
|
||||
Bundle b = new Bundle();
|
||||
b.putParcelable("account", status.getAccount());
|
||||
intent.putExtras(b);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
holder.art_media.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(context, MediaActivity.class);
|
||||
Bundle b = new Bundle();
|
||||
ArrayList<Attachment> attachments = new ArrayList<>();
|
||||
if (status.getArt_attachment() != null)
|
||||
attachments.add(status.getArt_attachment());
|
||||
else if (status.getMedia_attachments() != null && status.getMedia_attachments().size() > 0)
|
||||
attachments.add(status.getMedia_attachments().get(0));
|
||||
intent.putParcelableArrayListExtra("mediaArray", attachments);
|
||||
b.putInt("position", 0);
|
||||
intent.putExtras(b);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
});
|
||||
holder.pf_description.setText(status.getContentSpan(), TextView.BufferType.SPANNABLE);
|
||||
holder.pf_date.setText(Helper.dateToString(status.getCreated_at()));
|
||||
holder.pf_comment.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (MainActivity.social != UpdateAccountInfoAsyncTask.SOCIAL.PIXELFED) {
|
||||
CrossActions.doCrossConversation(context, status);
|
||||
} else {
|
||||
Intent intent = new Intent(context, ShowConversationActivity.class);
|
||||
Bundle b = new Bundle();
|
||||
b.putParcelable("status", status);
|
||||
intent.putExtras(b);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
if (status.getDisplayNameSpan() != null && status.getDisplayNameSpan().toString().trim().length() > 0)
|
||||
holder.pf_username.setText(status.getDisplayNameSpan(), TextView.BufferType.SPANNABLE);
|
||||
else
|
||||
holder.pf_username.setText(status.getAccount().getUsername());
|
||||
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
|
||||
|
||||
|
||||
|
||||
if (theme == Helper.THEME_BLACK) {
|
||||
holder.pf_fav.setInActiveImageTint(R.color.action_black);
|
||||
holder.pf_share.setInActiveImageTint(R.color.action_black);
|
||||
changeDrawableColor(context, R.drawable.ic_pixelfed_favorite_border, R.color.action_black);
|
||||
changeDrawableColor(context, holder.pf_comment, R.color.action_black);
|
||||
holder.pf_cardview.setCardBackgroundColor(ContextCompat.getColor(context, R.color.black_3));
|
||||
} else if (theme == Helper.THEME_DARK) {
|
||||
holder.pf_fav.setInActiveImageTint(R.color.action_dark);
|
||||
holder.pf_share.setInActiveImageTint(R.color.action_dark);
|
||||
changeDrawableColor(context, holder.pf_comment, R.color.action_dark);
|
||||
changeDrawableColor(context, R.drawable.ic_pixelfed_favorite_border, R.color.action_dark);
|
||||
holder.pf_cardview.setCardBackgroundColor(ContextCompat.getColor(context, R.color.mastodonC1_));
|
||||
} else {
|
||||
holder.pf_fav.setInActiveImageTint(R.color.action_light);
|
||||
holder.pf_share.setInActiveImageTint(R.color.action_light);
|
||||
changeDrawableColor(context, holder.pf_comment, R.color.action_light);
|
||||
changeDrawableColor(context, R.drawable.ic_pixelfed_favorite_border, R.color.action_light);
|
||||
holder.pf_cardview.setCardBackgroundColor(ContextCompat.getColor(context, R.color.white));
|
||||
}
|
||||
|
||||
|
||||
holder.pf_fav.pressOnTouch(false);
|
||||
holder.pf_fav.setActiveImage(R.drawable.ic_pixelfed_favorite);
|
||||
holder.pf_fav.setInactiveImage(R.drawable.ic_pixelfed_favorite_border);
|
||||
holder.pf_fav.setDisableCircle(true);
|
||||
holder.pf_fav.setActiveImageTint(R.color.pixelfed_like);
|
||||
holder.pf_fav.setColors(R.color.pixelfed_like, R.color.pixelfed_like);
|
||||
|
||||
holder.pf_share.pressOnTouch(false);
|
||||
holder.pf_share.setActiveImage(R.drawable.ic_pixelfed_share);
|
||||
holder.pf_share.setInactiveImage(R.drawable.ic_pixelfed_share);
|
||||
holder.pf_share.setDisableCircle(true);
|
||||
holder.pf_share.setActiveImageTint(R.color.boost_icon);
|
||||
holder.pf_share.setColors(R.color.boost_icon, R.color.boost_icon);
|
||||
|
||||
if (!status.isFavAnimated()) {
|
||||
if (status.isFavourited() || (status.getReblog() != null && status.getReblog().isFavourited())) {
|
||||
holder.pf_fav.setChecked(true);
|
||||
} else {
|
||||
holder.pf_fav.setChecked(false);
|
||||
}
|
||||
} else {
|
||||
status.setFavAnimated(false);
|
||||
holder.pf_fav.setChecked(true);
|
||||
holder.pf_fav.setAnimationSpeed(1.0f);
|
||||
holder.pf_fav.playAnimation();
|
||||
}
|
||||
|
||||
if (!status.isBoostAnimated()) {
|
||||
if (status.isReblogged() || (status.getReblog() != null && status.getReblog().isReblogged())) {
|
||||
holder.pf_share.setChecked(true);
|
||||
} else {
|
||||
holder.pf_share.setChecked(false);
|
||||
}
|
||||
} else {
|
||||
status.setBoostAnimated(false);
|
||||
holder.pf_share.setChecked(true);
|
||||
holder.pf_share.setAnimationSpeed(1.0f);
|
||||
holder.pf_share.playAnimation();
|
||||
}
|
||||
boolean confirmFav = sharedpreferences.getBoolean(Helper.SET_NOTIF_VALIDATION_FAV, false);
|
||||
holder.pf_fav.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (!status.isFavourited() && confirmFav)
|
||||
status.setFavAnimated(true);
|
||||
if (!status.isFavourited() && !confirmFav) {
|
||||
status.setFavAnimated(true);
|
||||
notifyStatusChanged(status);
|
||||
}
|
||||
CrossActions.doCrossAction(context, type, status, null, (status.isFavourited() || (status.getReblog() != null && status.getReblog().isFavourited())) ? API.StatusAction.UNFAVOURITE : API.StatusAction.FAVOURITE, pixelfedListAdapter, PixelfedListAdapter.this, true);
|
||||
}
|
||||
});
|
||||
boolean confirmBoost = sharedpreferences.getBoolean(Helper.SET_NOTIF_VALIDATION, false);
|
||||
holder.pf_share.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (!status.isReblogged() && confirmBoost)
|
||||
status.setBoostAnimated(true);
|
||||
if (!status.isReblogged() && !confirmBoost) {
|
||||
status.setBoostAnimated(true);
|
||||
notifyStatusChanged(status);
|
||||
}
|
||||
CrossActions.doCrossAction(context, type, status, null, (status.isReblogged() || (status.getReblog() != null && status.getReblog().isReblogged())) ? API.StatusAction.UNREBLOG : API.StatusAction.REBLOG, pixelfedListAdapter, PixelfedListAdapter.this, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onPostAction(int statusCode, API.StatusAction statusAction, String targetedId, Error error) {
|
||||
|
||||
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
if( error != null){
|
||||
Toasty.error(context, error.getError(),Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
Helper.manageMessageStatusCode(context, statusCode, statusAction);
|
||||
//When muting or blocking an account, its status are removed from the list
|
||||
List<Status> statusesToRemove = new ArrayList<>();
|
||||
if( statusAction == API.StatusAction.MUTE || statusAction == API.StatusAction.BLOCK){
|
||||
for(Status status: statuses){
|
||||
if( status.getAccount().getId().equals(targetedId))
|
||||
statusesToRemove.add(status);
|
||||
}
|
||||
statuses.removeAll(statusesToRemove);
|
||||
pixelfedListAdapter.notifyDataSetChanged();
|
||||
}else if( statusAction == API.StatusAction.UNSTATUS ){
|
||||
int position = 0;
|
||||
for(Status status: statuses){
|
||||
if( status.getId().equals(targetedId)) {
|
||||
statuses.remove(status);
|
||||
pixelfedListAdapter.notifyItemRemoved(position);
|
||||
SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
//Remove the status from cache also
|
||||
try {
|
||||
new StatusCacheDAO(context, db).remove(StatusCacheDAO.ARCHIVE_CACHE,status);
|
||||
}catch (Exception ignored){}
|
||||
break;
|
||||
}
|
||||
position++;
|
||||
}
|
||||
}
|
||||
else if ( statusAction == API.StatusAction.PIN || statusAction == API.StatusAction.UNPIN ) {
|
||||
int position = 0;
|
||||
for (Status status: statuses) {
|
||||
if (status.getId().equals(targetedId)) {
|
||||
if (statusAction == API.StatusAction.PIN)
|
||||
status.setPinned(true);
|
||||
else
|
||||
status.setPinned(false);
|
||||
pixelfedListAdapter.notifyItemChanged(position);
|
||||
break;
|
||||
}
|
||||
position++;
|
||||
}
|
||||
}
|
||||
if( statusAction == API.StatusAction.PEERTUBEDELETECOMMENT){
|
||||
int position = 0;
|
||||
for(Status status: statuses){
|
||||
if( status.getId().equals(targetedId)) {
|
||||
statuses.remove(status);
|
||||
pixelfedListAdapter.notifyItemRemoved(position);
|
||||
break;
|
||||
}
|
||||
position++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyStatusChanged(Status status){
|
||||
for (int i = 0; i < pixelfedListAdapter.getItemCount(); i++) {
|
||||
//noinspection ConstantConditions
|
||||
if (pixelfedListAdapter.getItemAt(i) != null && pixelfedListAdapter.getItemAt(i).getId().equals(status.getId())) {
|
||||
try {
|
||||
pixelfedListAdapter.notifyItemChanged(i);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyStatusWithActionChanged(API.StatusAction statusAction, Status status){
|
||||
for (int i = 0; i < pixelfedListAdapter.getItemCount(); i++) {
|
||||
//noinspection ConstantConditions
|
||||
if (pixelfedListAdapter.getItemAt(i) != null && pixelfedListAdapter.getItemAt(i).getId().equals(status.getId())) {
|
||||
try {
|
||||
int favCount = statuses.get(i).getFavourites_count();
|
||||
int boostCount = statuses.get(i).getReblogs_count();
|
||||
if( statusAction == API.StatusAction.REBLOG)
|
||||
boostCount++;
|
||||
else if( statusAction == API.StatusAction.UNREBLOG)
|
||||
boostCount--;
|
||||
else if( statusAction == API.StatusAction.FAVOURITE)
|
||||
favCount++;
|
||||
else if( statusAction == API.StatusAction.UNFAVOURITE)
|
||||
favCount--;
|
||||
if( boostCount < 0 )
|
||||
boostCount = 0;
|
||||
if( favCount < 0 )
|
||||
favCount = 0;
|
||||
statuses.get(i).setFavourited(status.isFavourited());
|
||||
statuses.get(i).setFavourites_count(favCount);
|
||||
statuses.get(i).setReblogged(status.isReblogged());
|
||||
statuses.get(i).setReblogs_count(boostCount);
|
||||
pixelfedListAdapter.notifyItemChanged(i);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onRetrieveEmoji(Status status, boolean fromTranslation) {
|
||||
if( status != null) {
|
||||
if( !fromTranslation) {
|
||||
status.setEmojiFound(true);
|
||||
}else {
|
||||
status.setEmojiTranslateFound(true);
|
||||
}
|
||||
notifyStatusChanged(status);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRetrieveEmoji(Notification notification) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRetrieveSearchEmoji(List<Emojis> emojis) {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -20,6 +20,7 @@ import android.content.DialogInterface;
|
|||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
|
@ -43,16 +44,21 @@ import java.util.Calendar;
|
|||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import es.dmoral.toasty.Toasty;
|
||||
import fr.gouv.etalab.mastodon.R;
|
||||
import fr.gouv.etalab.mastodon.activities.MainActivity;
|
||||
import fr.gouv.etalab.mastodon.activities.ShowConversationActivity;
|
||||
import fr.gouv.etalab.mastodon.activities.TootActivity;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.PostActionAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.client.API;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Error;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Status;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.StoredStatus;
|
||||
import fr.gouv.etalab.mastodon.fragments.DisplayScheduledTootsFragment;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnPostActionInterface;
|
||||
import fr.gouv.etalab.mastodon.jobs.ApplicationJob;
|
||||
import fr.gouv.etalab.mastodon.jobs.ScheduledBoostsSyncJob;
|
||||
import fr.gouv.etalab.mastodon.jobs.ScheduledTootsSyncJob;
|
||||
|
@ -67,7 +73,7 @@ import static fr.gouv.etalab.mastodon.helper.Helper.changeDrawableColor;
|
|||
* Created by Thomas on 16/07/2017.
|
||||
* Adapter for scheduled toots
|
||||
*/
|
||||
public class ScheduledTootsListAdapter extends BaseAdapter {
|
||||
public class ScheduledTootsListAdapter extends BaseAdapter implements OnPostActionInterface {
|
||||
|
||||
private Context context;
|
||||
private List<StoredStatus> storedStatuses;
|
||||
|
@ -93,7 +99,7 @@ public class ScheduledTootsListAdapter extends BaseAdapter {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Object getItem(int position) {
|
||||
public StoredStatus getItem(int position) {
|
||||
return storedStatuses.get(position);
|
||||
}
|
||||
|
||||
|
@ -107,6 +113,7 @@ public class ScheduledTootsListAdapter extends BaseAdapter {
|
|||
public View getView(final int position, View convertView, ViewGroup parent) {
|
||||
|
||||
final StoredStatus storedStatus = storedStatuses.get(position);
|
||||
final Status status = storedStatuses.get(position).getStatus();
|
||||
final ViewHolder holder;
|
||||
if (convertView == null) {
|
||||
convertView = layoutInflater.inflate(R.layout.drawer_scheduled_toot, parent, false);
|
||||
|
@ -148,8 +155,6 @@ public class ScheduledTootsListAdapter extends BaseAdapter {
|
|||
changeDrawableColor(context, R.drawable.ic_mail_outline,R.color.action_light);
|
||||
}
|
||||
|
||||
final Status status = storedStatus.getStatus();
|
||||
|
||||
switch (status.getVisibility()) {
|
||||
case "public":
|
||||
holder.scheduled_toot_privacy.setImageResource(R.drawable.ic_public);
|
||||
|
@ -196,18 +201,27 @@ public class ScheduledTootsListAdapter extends BaseAdapter {
|
|||
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if( type == DisplayScheduledTootsFragment.typeOfSchedule.TOOT)
|
||||
new StatusStoredDAO(context, db).remove(storedStatus.getId());
|
||||
else if (type == DisplayScheduledTootsFragment.typeOfSchedule.BOOST)
|
||||
new BoostScheduleDAO(context, db).remove(storedStatus.getId());
|
||||
storedStatuses.remove(storedStatus);
|
||||
scheduledTootsListAdapter.notifyDataSetChanged();
|
||||
if( storedStatuses.size() == 0 && textviewNoAction != null && textviewNoAction.getVisibility() == View.GONE)
|
||||
if( type != DisplayScheduledTootsFragment.typeOfSchedule.SERVER) {
|
||||
if (type == DisplayScheduledTootsFragment.typeOfSchedule.TOOT)
|
||||
new StatusStoredDAO(context, db).remove(storedStatus.getId());
|
||||
else if (type == DisplayScheduledTootsFragment.typeOfSchedule.BOOST)
|
||||
new BoostScheduleDAO(context, db).remove(storedStatus.getId());
|
||||
storedStatuses.remove(storedStatus);
|
||||
scheduledTootsListAdapter.notifyDataSetChanged();
|
||||
if (storedStatuses.size() == 0 && textviewNoAction != null && textviewNoAction.getVisibility() == View.GONE)
|
||||
textviewNoAction.setVisibility(View.VISIBLE);
|
||||
try {
|
||||
//Cancel the job
|
||||
ApplicationJob.cancelJob(storedStatus.getJobId());
|
||||
}catch (Exception ignored){}
|
||||
try {
|
||||
//Cancel the job
|
||||
ApplicationJob.cancelJob(storedStatus.getJobId());
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}else{
|
||||
new PostActionAsyncTask(context, API.StatusAction.DELETESCHEDULED, storedStatus, ScheduledTootsListAdapter.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
storedStatuses.remove(storedStatus);
|
||||
scheduledTootsListAdapter.notifyDataSetChanged();
|
||||
if (storedStatuses.size() == 0 && textviewNoAction != null && textviewNoAction.getVisibility() == View.GONE)
|
||||
textviewNoAction.setVisibility(View.VISIBLE);
|
||||
}
|
||||
dialog.dismiss();
|
||||
}
|
||||
})
|
||||
|
@ -222,10 +236,12 @@ public class ScheduledTootsListAdapter extends BaseAdapter {
|
|||
}
|
||||
});
|
||||
|
||||
if (storedStatus.getJobId() > 0) {
|
||||
holder.scheduled_toot_failed.setVisibility(View.GONE);
|
||||
}else {
|
||||
holder.scheduled_toot_failed.setVisibility(View.VISIBLE);
|
||||
if( type != DisplayScheduledTootsFragment.typeOfSchedule.SERVER) {
|
||||
if (storedStatus.getJobId() > 0) {
|
||||
holder.scheduled_toot_failed.setVisibility(View.GONE);
|
||||
} else {
|
||||
holder.scheduled_toot_failed.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
holder.scheduled_toot_media_count.setText(context.getString(R.string.media_count, status.getMedia_attachments().size()));
|
||||
holder.scheduled_toot_date_creation.setText(Helper.dateToString(storedStatus.getCreation_date()));
|
||||
|
@ -320,28 +336,38 @@ public class ScheduledTootsListAdapter extends BaseAdapter {
|
|||
Toasty.error(context, context.getString(R.string.toot_scheduled_date), Toast.LENGTH_LONG).show();
|
||||
}else {
|
||||
//Schedules the toot to the new date
|
||||
try {
|
||||
//Removes the job
|
||||
ApplicationJob.cancelJob(storedStatus.getJobId());
|
||||
//Replace it by the new one
|
||||
StoredStatus storedStatusnew = null;
|
||||
if( type == DisplayScheduledTootsFragment.typeOfSchedule.TOOT) {
|
||||
ScheduledTootsSyncJob.schedule(context, storedStatus.getId(), time);
|
||||
storedStatusnew = new StatusStoredDAO(context, db).getStatus(storedStatus.getId());
|
||||
}else if(type == DisplayScheduledTootsFragment.typeOfSchedule.BOOST){
|
||||
ScheduledBoostsSyncJob.scheduleUpdate(context, storedStatus.getId(), time);
|
||||
storedStatusnew = new BoostScheduleDAO(context, db).getStatus(storedStatus.getId());
|
||||
if( type != DisplayScheduledTootsFragment.typeOfSchedule.SERVER) {
|
||||
try {
|
||||
//Removes the job
|
||||
ApplicationJob.cancelJob(storedStatus.getJobId());
|
||||
//Replace it by the new one
|
||||
StoredStatus storedStatusnew = null;
|
||||
if (type == DisplayScheduledTootsFragment.typeOfSchedule.TOOT) {
|
||||
ScheduledTootsSyncJob.schedule(context, storedStatus.getId(), time);
|
||||
storedStatusnew = new StatusStoredDAO(context, db).getStatus(storedStatus.getId());
|
||||
} else if (type == DisplayScheduledTootsFragment.typeOfSchedule.BOOST) {
|
||||
ScheduledBoostsSyncJob.scheduleUpdate(context, storedStatus.getId(), time);
|
||||
storedStatusnew = new BoostScheduleDAO(context, db).getStatus(storedStatus.getId());
|
||||
}
|
||||
//Date displayed is changed
|
||||
assert storedStatusnew != null;
|
||||
storedStatus.setScheduled_date(storedStatusnew.getScheduled_date());
|
||||
scheduledTootsListAdapter.notifyDataSetChanged();
|
||||
//Notifiy all is ok
|
||||
if (type == DisplayScheduledTootsFragment.typeOfSchedule.TOOT)
|
||||
Toasty.success(context, context.getString(R.string.toot_scheduled), Toast.LENGTH_LONG).show();
|
||||
else
|
||||
Toasty.success(context, context.getString(R.string.boost_scheduled), Toast.LENGTH_LONG).show();
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
//Date displayed is changed
|
||||
assert storedStatusnew != null;
|
||||
storedStatus.setScheduled_date(storedStatusnew.getScheduled_date());
|
||||
scheduledTootsListAdapter.notifyDataSetChanged();
|
||||
//Notifiy all is ok
|
||||
if( type == DisplayScheduledTootsFragment.typeOfSchedule.TOOT)
|
||||
Toasty.success(context,context.getString(R.string.toot_scheduled), Toast.LENGTH_LONG).show();
|
||||
else
|
||||
Toasty.success(context,context.getString(R.string.boost_scheduled), Toast.LENGTH_LONG).show();
|
||||
}catch (Exception ignored){}
|
||||
}else{
|
||||
int offset = TimeZone.getDefault().getRawOffset();
|
||||
calendar.add(Calendar.MILLISECOND, -offset);
|
||||
final String date = Helper.dateToString(new Date(calendar.getTimeInMillis()));
|
||||
storedStatus.getStatus().setScheduled_at(date);
|
||||
new PostActionAsyncTask(context, API.StatusAction.UPDATESERVERSCHEDULE, storedStatus, ScheduledTootsListAdapter.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
Toasty.success(context, context.getString(R.string.boost_scheduled), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
alertDialog.dismiss();
|
||||
}
|
||||
}
|
||||
|
@ -386,9 +412,27 @@ public class ScheduledTootsListAdapter extends BaseAdapter {
|
|||
context.startActivity(intentToot);
|
||||
}
|
||||
});
|
||||
else if( type == DisplayScheduledTootsFragment.typeOfSchedule.SERVER)
|
||||
holder.scheduled_toot_container.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intentToot = new Intent(context, TootActivity.class);
|
||||
Bundle b = new Bundle();
|
||||
if( storedStatus.getStatus().getSpoiler_text().equals("null"))
|
||||
storedStatus.getStatus().setSpoiler_text("");
|
||||
b.putParcelable("storedStatus", storedStatus);
|
||||
intentToot.putExtras(b);
|
||||
context.startActivity(intentToot);
|
||||
}
|
||||
});
|
||||
return convertView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPostAction(int statusCode, API.StatusAction statusAction, String userId, Error error) {
|
||||
|
||||
}
|
||||
|
||||
private class ViewHolder {
|
||||
LinearLayout scheduled_toot_container;
|
||||
TextView scheduled_toot_title;
|
||||
|
|
|
@ -198,9 +198,9 @@ public class SearchListAdapter extends BaseAdapter {
|
|||
Intent intent = new Intent(context, ShowAccountActivity.class);
|
||||
Bundle b = new Bundle();
|
||||
if( status.getReblog() == null)
|
||||
b.putString("accountId", status.getAccount().getId());
|
||||
b.putParcelable("account", status.getAccount());
|
||||
else
|
||||
b.putString("accountId", status.getReblog().getAccount().getId());
|
||||
b.putParcelable("account", status.getReblog().getAccount());
|
||||
intent.putExtras(b);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -36,8 +36,10 @@ import java.util.List;
|
|||
|
||||
import es.dmoral.toasty.Toasty;
|
||||
import fr.gouv.etalab.mastodon.R;
|
||||
import fr.gouv.etalab.mastodon.activities.MainActivity;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrieveAccountsAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrieveManyRelationshipsAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.UpdateAccountInfoAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.client.APIResponse;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Relationship;
|
||||
|
@ -78,7 +80,7 @@ public class DisplayAccountsFragment extends Fragment implements OnRetrieveAccou
|
|||
accounts = new ArrayList<>();
|
||||
if (bundle != null) {
|
||||
type = (RetrieveAccountsAsyncTask.Type) bundle.get("type");
|
||||
targetedId = bundle.getString("targetedId", null);
|
||||
targetedId = bundle.getString("targetedid", null);
|
||||
instance = bundle.getString("instance", null);
|
||||
name = bundle.getString("name", null);
|
||||
}
|
||||
|
@ -228,7 +230,7 @@ public class DisplayAccountsFragment extends Fragment implements OnRetrieveAccou
|
|||
}
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
firstLoad = false;
|
||||
if( type != RetrieveAccountsAsyncTask.Type.BLOCKED )
|
||||
if( type != RetrieveAccountsAsyncTask.Type.BLOCKED && MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON)
|
||||
new RetrieveManyRelationshipsAsyncTask(context, accounts,DisplayAccountsFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
|
|
|
@ -102,12 +102,10 @@ public class DisplayBookmarksFragment extends Fragment implements OnRetrieveFeed
|
|||
}catch (Exception ignored){}
|
||||
final boolean isOnWifi = Helper.isOnWIFI(context);
|
||||
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
final int behaviorWithAttachments = sharedpreferences.getInt(Helper.SET_ATTACHMENT_ACTION, Helper.ATTACHMENT_ALWAYS);
|
||||
final int positionSpinnerTrans = sharedpreferences.getInt(Helper.SET_TRANSLATOR, Helper.TRANS_YANDEX);
|
||||
statuses = apiResponse.getStatuses();
|
||||
if( statuses != null && statuses.size() > 0) {
|
||||
LinearLayoutManager mLayoutManager = new LinearLayoutManager(context);
|
||||
statusListAdapter = new StatusListAdapter(context, RetrieveFeedsAsyncTask.Type.CACHE_BOOKMARKS, null, isOnWifi, behaviorWithAttachments, positionSpinnerTrans, this.statuses);
|
||||
statusListAdapter = new StatusListAdapter(context, RetrieveFeedsAsyncTask.Type.CACHE_BOOKMARKS, null, isOnWifi, this.statuses);
|
||||
lv_status.setAdapter(statusListAdapter);
|
||||
lv_status.setLayoutManager(mLayoutManager);
|
||||
}else {
|
||||
|
@ -138,7 +136,7 @@ public class DisplayBookmarksFragment extends Fragment implements OnRetrieveFeed
|
|||
new StatusCacheDAO(context, db).removeAllStatus(StatusCacheDAO.STATUS_CACHE);
|
||||
statuses = new ArrayList<>();
|
||||
statuses.clear();
|
||||
statusListAdapter = new StatusListAdapter(context, RetrieveFeedsAsyncTask.Type.CACHE_BOOKMARKS, null, isOnWifi, behaviorWithAttachments, positionSpinnerTrans, statuses);
|
||||
statusListAdapter = new StatusListAdapter(context, RetrieveFeedsAsyncTask.Type.CACHE_BOOKMARKS, null, isOnWifi, statuses);
|
||||
lv_status.setAdapter(statusListAdapter);
|
||||
statusListAdapter.notifyDataSetChanged();
|
||||
textviewNoAction.setVisibility(View.VISIBLE);
|
||||
|
|
|
@ -90,7 +90,7 @@ public class DisplayMediaFragment extends Fragment implements OnRetrieveFeedsInt
|
|||
mainLoader.setVisibility(View.VISIBLE);
|
||||
nextElementLoader.setVisibility(View.GONE);
|
||||
if (bundle != null) {
|
||||
targetedId = bundle.getString("targetedId", null);
|
||||
targetedId = bundle.getString("targetedid", null);
|
||||
}
|
||||
|
||||
attachments = new ArrayList<>();
|
||||
|
@ -170,8 +170,11 @@ public class DisplayMediaFragment extends Fragment implements OnRetrieveFeedsInt
|
|||
mainLoader.setVisibility(View.GONE);
|
||||
nextElementLoader.setVisibility(View.GONE);
|
||||
//Discards 404 - error which can often happen due to toots which have been deleted
|
||||
if( apiResponse.getError() != null && apiResponse.getError().getStatusCode() != 404 ){
|
||||
Toasty.error(context, apiResponse.getError().getError(),Toast.LENGTH_LONG).show();
|
||||
if(apiResponse == null || apiResponse.getError() != null && apiResponse.getError().getStatusCode() != 404 ){
|
||||
if( apiResponse != null && apiResponse.getError() != null && apiResponse.getError().getError() != null)
|
||||
Toasty.error(context, apiResponse.getError().getError(),Toast.LENGTH_LONG).show();
|
||||
else
|
||||
Toasty.error(context, context.getString(R.string.toast_error),Toast.LENGTH_LONG).show();
|
||||
flag_loading = false;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,10 @@ package fr.gouv.etalab.mastodon.fragments;
|
|||
* You should have received a copy of the GNU General Public License along with Mastalab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
|
@ -23,6 +26,7 @@ import android.os.Looper;
|
|||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.support.v7.widget.DividerItemDecoration;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
|
@ -41,9 +45,12 @@ import fr.gouv.etalab.mastodon.R;
|
|||
import fr.gouv.etalab.mastodon.activities.MainActivity;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrieveMissingNotificationsAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrieveNotificationsAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.UpdateAccountInfoAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.client.API;
|
||||
import fr.gouv.etalab.mastodon.client.APIResponse;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Notification;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Status;
|
||||
import fr.gouv.etalab.mastodon.drawers.NotificationsListAdapter;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveMissingNotificationsInterface;
|
||||
|
@ -72,6 +79,8 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
|
|||
private String userId, instance;
|
||||
private SharedPreferences sharedpreferences;
|
||||
LinearLayoutManager mLayoutManager;
|
||||
private BroadcastReceiver receive_action;
|
||||
private BroadcastReceiver receive_data;
|
||||
|
||||
public DisplayNotificationsFragment(){
|
||||
}
|
||||
|
@ -125,6 +134,43 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
|
|||
}
|
||||
});
|
||||
|
||||
if( MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON) {
|
||||
|
||||
if( receive_action != null)
|
||||
LocalBroadcastManager.getInstance(context).unregisterReceiver(receive_action);
|
||||
receive_action = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Bundle b = intent.getExtras();
|
||||
assert b != null;
|
||||
Status status = b.getParcelable("status");
|
||||
API.StatusAction statusAction = (API.StatusAction) b.getSerializable("action");
|
||||
if( status != null) {
|
||||
notificationsListAdapter.notifyNotificationWithActionChanged(statusAction, status);
|
||||
}
|
||||
}
|
||||
};
|
||||
LocalBroadcastManager.getInstance(context).registerReceiver(receive_action, new IntentFilter(Helper.RECEIVE_ACTION));
|
||||
|
||||
if( receive_data != null)
|
||||
LocalBroadcastManager.getInstance(context).unregisterReceiver(receive_data);
|
||||
receive_data = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Bundle b = intent.getExtras();
|
||||
assert b != null;
|
||||
String userIdService = b.getString("userIdService", null);
|
||||
if( userIdService != null && userIdService.equals(userId)) {
|
||||
Notification notification = b.getParcelable("data");
|
||||
refresh(notification);
|
||||
if( context instanceof MainActivity)
|
||||
((MainActivity)context).updateNotifCounter();
|
||||
}
|
||||
}
|
||||
};
|
||||
LocalBroadcastManager.getInstance(context).registerReceiver(receive_data, new IntentFilter(Helper.RECEIVE_DATA));
|
||||
}
|
||||
|
||||
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
|
||||
@Override
|
||||
public void onRefresh() {
|
||||
|
@ -133,8 +179,14 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
|
|||
flag_loading = true;
|
||||
swiped = true;
|
||||
MainActivity.countNewNotifications = 0;
|
||||
try {
|
||||
((MainActivity) context).updateNotifCounter();
|
||||
}catch (Exception ignored){}
|
||||
String sinceId = null;
|
||||
if( notifications != null && notifications.size() > 0 )
|
||||
sinceId = notifications.get(0).getId();
|
||||
if( context != null)
|
||||
asyncTask = new RetrieveNotificationsAsyncTask(context, true, null, null, DisplayNotificationsFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
asyncTask = new RetrieveMissingNotificationsAsyncTask(context, sinceId, DisplayNotificationsFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
});
|
||||
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
|
@ -192,6 +244,11 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
|
|||
super.onDestroy();
|
||||
if(asyncTask != null && asyncTask.getStatus() == AsyncTask.Status.RUNNING)
|
||||
asyncTask.cancel(true);
|
||||
if( receive_action != null)
|
||||
LocalBroadcastManager.getInstance(context).unregisterReceiver(receive_action);
|
||||
if( receive_data != null)
|
||||
LocalBroadcastManager.getInstance(context).unregisterReceiver(receive_data);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -231,6 +288,9 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
|
|||
if( lastReadNotifications != null && Long.parseLong(tmpNotification.getId()) > Long.parseLong(lastReadNotifications)) {
|
||||
MainActivity.countNewNotifications++;
|
||||
}
|
||||
try {
|
||||
((MainActivity) context).updateNotifCounter();
|
||||
}catch (Exception ignored){}
|
||||
this.notifications.add(tmpNotification);
|
||||
}
|
||||
if( firstLoad) {
|
||||
|
@ -267,6 +327,7 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
|
|||
return;
|
||||
//Store last notification id to avoid to notify for those that have been already seen
|
||||
if (visible && notifications != null && notifications.size() > 0) {
|
||||
retrieveMissingNotifications(notifications.get(0).getId());
|
||||
updateNotificationLastId(notifications.get(0).getId());
|
||||
}
|
||||
}
|
||||
|
@ -302,6 +363,9 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
|
|||
MainActivity.lastNotificationId = notification.getId();
|
||||
notifications.add(0, notification);
|
||||
MainActivity.countNewNotifications++;
|
||||
try {
|
||||
((MainActivity) context).updateNotifCounter();
|
||||
}catch (Exception ignored){}
|
||||
int firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();
|
||||
if (firstVisibleItem > 0)
|
||||
notificationsListAdapter.notifyItemInserted(0);
|
||||
|
@ -317,7 +381,8 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
|
|||
|
||||
@Override
|
||||
public void onRetrieveMissingNotifications(List<Notification> notifications) {
|
||||
|
||||
flag_loading = false;
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
if( notifications != null && notifications.size() > 0) {
|
||||
for (int i = notifications.size()-1 ; i >= 0 ; i--) {
|
||||
if (this.notifications.size() == 0 ||
|
||||
|
|
|
@ -37,14 +37,20 @@ import android.view.ViewGroup;
|
|||
import android.widget.ListView;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import es.dmoral.toasty.Toasty;
|
||||
import fr.gouv.etalab.mastodon.R;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrieveFeedsAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrieveScheduledTootsAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.client.APIResponse;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.StoredStatus;
|
||||
import fr.gouv.etalab.mastodon.drawers.ScheduledTootsListAdapter;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveFeedsInterface;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveScheduledTootsInterface;
|
||||
import fr.gouv.etalab.mastodon.sqlite.BoostScheduleDAO;
|
||||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||
|
@ -57,7 +63,7 @@ import static fr.gouv.etalab.mastodon.helper.Helper.changeDrawableColor;
|
|||
* Created by Thomas on 16/07/2017.
|
||||
* Fragment to display scheduled toots
|
||||
*/
|
||||
public class DisplayScheduledTootsFragment extends Fragment implements OnRetrieveScheduledTootsInterface {
|
||||
public class DisplayScheduledTootsFragment extends Fragment implements OnRetrieveScheduledTootsInterface, OnRetrieveFeedsInterface {
|
||||
|
||||
|
||||
private Context context;
|
||||
|
@ -66,10 +72,14 @@ public class DisplayScheduledTootsFragment extends Fragment implements OnRetriev
|
|||
private ListView lv_scheduled_toots;
|
||||
private TextView warning_battery_message;
|
||||
private typeOfSchedule type;
|
||||
private List<StoredStatus> storedStatuses;
|
||||
private boolean firstCall;
|
||||
private ScheduledTootsListAdapter scheduledTootsListAdapter;
|
||||
|
||||
public enum typeOfSchedule{
|
||||
TOOT,
|
||||
BOOST
|
||||
BOOST,
|
||||
SERVER
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -83,75 +93,101 @@ public class DisplayScheduledTootsFragment extends Fragment implements OnRetriev
|
|||
if( type == null)
|
||||
type = typeOfSchedule.TOOT;
|
||||
lv_scheduled_toots = rootView.findViewById(R.id.lv_scheduled_toots);
|
||||
|
||||
firstCall = true;
|
||||
mainLoader = rootView.findViewById(R.id.loader);
|
||||
warning_battery_message = rootView.findViewById(R.id.warning_battery_message);
|
||||
textviewNoAction = rootView.findViewById(R.id.no_action);
|
||||
mainLoader.setVisibility(View.VISIBLE);
|
||||
|
||||
storedStatuses = new ArrayList<>();
|
||||
//Removes all scheduled toots that have sent
|
||||
SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
if( type == typeOfSchedule.TOOT)
|
||||
new StatusStoredDAO(context, db).removeAllSent();
|
||||
else if( type == typeOfSchedule.BOOST)
|
||||
new BoostScheduleDAO(context, db).removeAllSent();
|
||||
else if( type == typeOfSchedule.SERVER)
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, RetrieveFeedsAsyncTask.Type.SCHEDULED_TOOTS, null, DisplayScheduledTootsFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
|
||||
scheduledTootsListAdapter = new ScheduledTootsListAdapter(context, type, storedStatuses, textviewNoAction);
|
||||
lv_scheduled_toots.setAdapter(scheduledTootsListAdapter);
|
||||
return rootView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRetrieveFeeds(APIResponse apiResponse) {
|
||||
if( apiResponse.getError() != null && apiResponse.getError().getStatusCode() != 404 ){
|
||||
Toasty.error(context, apiResponse.getError().getError(), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
mainLoader.setVisibility(View.GONE);
|
||||
if(apiResponse.getStoredStatuses() != null && apiResponse.getStoredStatuses().size() > 0 ){
|
||||
storedStatuses.addAll(apiResponse.getStoredStatuses());
|
||||
textviewNoAction.setVisibility(View.GONE);
|
||||
lv_scheduled_toots.setVisibility(View.VISIBLE);
|
||||
scheduledTootsListAdapter.notifyDataSetChanged();
|
||||
}else if( firstCall){
|
||||
textviewNoAction.setVisibility(View.VISIBLE);
|
||||
lv_scheduled_toots.setVisibility(View.GONE);
|
||||
}
|
||||
firstCall = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume(){
|
||||
super.onResume();
|
||||
//Retrieves scheduled toots
|
||||
asyncTask = new RetrieveScheduledTootsAsyncTask(context, type,DisplayScheduledTootsFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
final PowerManager powerManager = (PowerManager) getActivity().getSystemService(Context.POWER_SERVICE);
|
||||
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
//Battery saver is one and user never asked to stop showing the message
|
||||
changeDrawableColor(context, R.drawable.ic_report, R.color.mastodonC4);
|
||||
changeDrawableColor(context, R.drawable.ic_cancel, R.color.mastodonC4);
|
||||
if( powerManager != null && powerManager.isPowerSaveMode() && sharedpreferences.getBoolean(Helper.SHOW_BATTERY_SAVER_MESSAGE,true)){
|
||||
warning_battery_message.setVisibility(View.VISIBLE);
|
||||
}else {
|
||||
warning_battery_message.setVisibility(View.GONE);
|
||||
}
|
||||
warning_battery_message.setOnTouchListener(new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
final int DRAWABLE_RIGHT = 2;
|
||||
if(event.getAction() == MotionEvent.ACTION_UP) {
|
||||
if(event.getRawX() >= (warning_battery_message.getRight() - warning_battery_message.getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width())) {
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putBoolean(Helper.SHOW_BATTERY_SAVER_MESSAGE, false);
|
||||
editor.apply();
|
||||
warning_battery_message.setVisibility(View.GONE);
|
||||
return true;
|
||||
if( type != null && type != typeOfSchedule.SERVER) {
|
||||
//Retrieves scheduled toots
|
||||
asyncTask = new RetrieveScheduledTootsAsyncTask(context, type, DisplayScheduledTootsFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
final PowerManager powerManager = (PowerManager) getActivity().getSystemService(Context.POWER_SERVICE);
|
||||
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
//Battery saver is one and user never asked to stop showing the message
|
||||
changeDrawableColor(context, R.drawable.ic_report, R.color.mastodonC4);
|
||||
changeDrawableColor(context, R.drawable.ic_cancel, R.color.mastodonC4);
|
||||
if (powerManager != null && powerManager.isPowerSaveMode() && sharedpreferences.getBoolean(Helper.SHOW_BATTERY_SAVER_MESSAGE, true)) {
|
||||
warning_battery_message.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
warning_battery_message.setVisibility(View.GONE);
|
||||
}
|
||||
warning_battery_message.setOnTouchListener(new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
final int DRAWABLE_RIGHT = 2;
|
||||
if (event.getAction() == MotionEvent.ACTION_UP) {
|
||||
if (event.getRawX() >= (warning_battery_message.getRight() - warning_battery_message.getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width())) {
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putBoolean(Helper.SHOW_BATTERY_SAVER_MESSAGE, false);
|
||||
editor.apply();
|
||||
warning_battery_message.setVisibility(View.GONE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
warning_battery_message.setOnClickListener(new View.OnClickListener() {
|
||||
@SuppressLint("BatteryLife")
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
try {
|
||||
Intent battSaverIntent = new Intent();
|
||||
battSaverIntent.setComponent(new ComponentName("com.android.settings", "com.android.settings.Settings$BatterySaverSettingsActivity"));
|
||||
startActivityForResult(battSaverIntent, 0);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
try {
|
||||
Intent batterySaverIntent;
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
|
||||
batterySaverIntent = new Intent(Settings.ACTION_BATTERY_SAVER_SETTINGS);
|
||||
startActivity(batterySaverIntent);
|
||||
}
|
||||
} catch (ActivityNotFoundException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
warning_battery_message.setOnClickListener(new View.OnClickListener() {
|
||||
@SuppressLint("BatteryLife")
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
try {
|
||||
Intent battSaverIntent = new Intent();
|
||||
battSaverIntent.setComponent(new ComponentName("com.android.settings", "com.android.settings.Settings$BatterySaverSettingsActivity"));
|
||||
startActivityForResult(battSaverIntent, 0);
|
||||
}catch (ActivityNotFoundException e){
|
||||
try {
|
||||
Intent batterySaverIntent;
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
|
||||
batterySaverIntent = new Intent(Settings.ACTION_BATTERY_SAVER_SETTINGS);
|
||||
startActivity(batterySaverIntent);
|
||||
}
|
||||
}catch (ActivityNotFoundException ignored){}
|
||||
}
|
||||
}
|
||||
});
|
||||
}else {
|
||||
warning_battery_message.setVisibility(View.GONE);
|
||||
});
|
||||
} else {
|
||||
warning_battery_message.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,7 +216,7 @@ public class DisplayScheduledTootsFragment extends Fragment implements OnRetriev
|
|||
|
||||
mainLoader.setVisibility(View.GONE);
|
||||
if( storedStatuses != null && storedStatuses.size() > 0 ){
|
||||
ScheduledTootsListAdapter scheduledTootsListAdapter = new ScheduledTootsListAdapter(context, type, storedStatuses, textviewNoAction);
|
||||
scheduledTootsListAdapter = new ScheduledTootsListAdapter(context, type, storedStatuses, textviewNoAction);
|
||||
lv_scheduled_toots.setAdapter(scheduledTootsListAdapter);
|
||||
textviewNoAction.setVisibility(View.GONE);
|
||||
}else {
|
||||
|
|
|
@ -15,8 +15,10 @@ package fr.gouv.etalab.mastodon.fragments;
|
|||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.AsyncTask;
|
||||
|
@ -26,6 +28,7 @@ import android.os.Looper;
|
|||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
|
@ -33,6 +36,7 @@ import android.view.LayoutInflater;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -43,9 +47,12 @@ import es.dmoral.toasty.Toasty;
|
|||
import fr.gouv.etalab.mastodon.R;
|
||||
import fr.gouv.etalab.mastodon.activities.BaseMainActivity;
|
||||
import fr.gouv.etalab.mastodon.activities.MainActivity;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrieveFeedsAfterBookmarkAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrieveFeedsAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrieveMissingFeedsAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrievePeertubeSearchAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.asynctasks.UpdateAccountInfoAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.client.API;
|
||||
import fr.gouv.etalab.mastodon.client.APIResponse;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Conversation;
|
||||
|
@ -53,12 +60,16 @@ import fr.gouv.etalab.mastodon.client.Entities.Peertube;
|
|||
import fr.gouv.etalab.mastodon.client.Entities.RemoteInstance;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Status;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.TagTimeline;
|
||||
import fr.gouv.etalab.mastodon.drawers.ArtListAdapter;
|
||||
import fr.gouv.etalab.mastodon.drawers.PeertubeAdapter;
|
||||
import fr.gouv.etalab.mastodon.drawers.PixelfedListAdapter;
|
||||
import fr.gouv.etalab.mastodon.drawers.StatusListAdapter;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveFeedsAfterBookmarkInterface;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveFeedsInterface;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveMissingFeedsInterface;
|
||||
import fr.gouv.etalab.mastodon.services.StreamingFederatedTimelineService;
|
||||
import fr.gouv.etalab.mastodon.services.StreamingHomeTimelineService;
|
||||
import fr.gouv.etalab.mastodon.services.StreamingLocalTimelineService;
|
||||
import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
|
||||
import fr.gouv.etalab.mastodon.sqlite.InstancesDAO;
|
||||
|
@ -71,7 +82,7 @@ import fr.gouv.etalab.mastodon.sqlite.TempMuteDAO;
|
|||
* Created by Thomas on 24/04/2017.
|
||||
* Fragment to display content related to status
|
||||
*/
|
||||
public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsInterface, OnRetrieveMissingFeedsInterface {
|
||||
public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsInterface, OnRetrieveMissingFeedsInterface, OnRetrieveFeedsAfterBookmarkInterface {
|
||||
|
||||
|
||||
private boolean flag_loading;
|
||||
|
@ -79,6 +90,8 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
private AsyncTask<Void, Void, Void> asyncTask;
|
||||
private StatusListAdapter statusListAdapter;
|
||||
private PeertubeAdapter peertubeAdapater;
|
||||
private ArtListAdapter artListAdapter;
|
||||
private PixelfedListAdapter pixelfedListAdapter;
|
||||
private String max_id;
|
||||
private List<Status> statuses;
|
||||
private List<Peertube> peertubes;
|
||||
|
@ -90,7 +103,7 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
private String tag;
|
||||
private RecyclerView lv_status;
|
||||
private boolean showMediaOnly, showPinned, showReply;
|
||||
private Intent streamingFederatedIntent, streamingLocalIntent;
|
||||
private Intent streamingHomeIntent, streamingFederatedIntent, streamingLocalIntent;
|
||||
LinearLayoutManager mLayoutManager;
|
||||
boolean firstTootsLoaded;
|
||||
private String userId, instance;
|
||||
|
@ -103,7 +116,13 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
private String initialBookMark;
|
||||
private boolean fetchMoreButtonDisplayed;
|
||||
private TagTimeline tagTimeline;
|
||||
|
||||
private String updatedBookMark;
|
||||
private String lastReadToot;
|
||||
private TextView textviewNoActionText;
|
||||
private boolean ischannel;
|
||||
private boolean ownVideos;
|
||||
private BroadcastReceiver receive_action;
|
||||
private BroadcastReceiver receive_data;
|
||||
public DisplayStatusFragment(){
|
||||
}
|
||||
|
||||
|
@ -116,14 +135,15 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
Bundle bundle = this.getArguments();
|
||||
showMediaOnly = false;
|
||||
//Will allow to load first toots if bookmark != null
|
||||
firstTootsLoaded = true;
|
||||
firstTootsLoaded = false;
|
||||
fetchMoreButtonDisplayed = false;
|
||||
showPinned = false;
|
||||
showReply = false;
|
||||
tagTimeline = null;
|
||||
if (bundle != null) {
|
||||
type = (RetrieveFeedsAsyncTask.Type) bundle.get("type");
|
||||
targetedId = bundle.getString("targetedId", null);
|
||||
targetedId = bundle.getString("targetedid", null);
|
||||
ownVideos = bundle.getBoolean("ownvideos", false); //Peetube account watching its videos
|
||||
tag = bundle.getString("tag", null);
|
||||
showMediaOnly = bundle.getBoolean("showMediaOnly",false);
|
||||
showPinned = bundle.getBoolean("showPinned",false);
|
||||
|
@ -131,10 +151,15 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
remoteInstance = bundle.getString("remote_instance", "");
|
||||
search_peertube = bundle.getString("search_peertube", null);
|
||||
remote_channel_name = bundle.getString("remote_channel_name", null);
|
||||
|
||||
instanceType = bundle.getString("instanceType", "MASTODON");
|
||||
ischannel = bundle.getBoolean("ischannel",false);
|
||||
}
|
||||
if( ischannel)
|
||||
type = RetrieveFeedsAsyncTask.Type.CHANNEL;
|
||||
|
||||
SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
if( !remoteInstance.equals("")){
|
||||
//instanceType should not be null only for Peertube accounts
|
||||
if( !remoteInstance.equals("") && instanceType == null){
|
||||
List<RemoteInstance> remoteInstanceObj = new InstancesDAO(context, db).getInstanceByName(remoteInstance);
|
||||
if( remoteInstanceObj != null && remoteInstanceObj.size() > 0)
|
||||
instanceType = remoteInstanceObj.get(0).getType();
|
||||
|
@ -143,104 +168,144 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
max_id = null;
|
||||
flag_loading = true;
|
||||
firstLoad = true;
|
||||
initialBookMark = null;
|
||||
|
||||
assert context != null;
|
||||
sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
boolean isOnWifi = Helper.isOnWIFI(context);
|
||||
int positionSpinnerTrans = sharedpreferences.getInt(Helper.SET_TRANSLATOR, Helper.TRANS_YANDEX);
|
||||
swipeRefreshLayout = rootView.findViewById(R.id.swipeContainer);
|
||||
int behaviorWithAttachments = sharedpreferences.getInt(Helper.SET_ATTACHMENT_ACTION, Helper.ATTACHMENT_ALWAYS);
|
||||
lv_status = rootView.findViewById(R.id.lv_status);
|
||||
mainLoader = rootView.findViewById(R.id.loader);
|
||||
nextElementLoader = rootView.findViewById(R.id.loading_next_status);
|
||||
textviewNoAction = rootView.findViewById(R.id.no_action);
|
||||
textviewNoActionText = rootView.findViewById(R.id.no_action_text);
|
||||
mainLoader.setVisibility(View.VISIBLE);
|
||||
nextElementLoader.setVisibility(View.GONE);
|
||||
|
||||
userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
instance = sharedpreferences.getString(Helper.PREF_INSTANCE, context!=null?Helper.getLiveInstance(context):null);
|
||||
Account account = new AccountDAO(context, db).getAccountByID(userId);
|
||||
mutedAccount = new TempMuteDAO(context, db).getAllTimeMuted(account);
|
||||
|
||||
if( type == RetrieveFeedsAsyncTask.Type.TAG && tag != null) {
|
||||
BaseMainActivity.displayPeertube = null;
|
||||
List<TagTimeline> tagTimelines = new SearchDAO(context, db).getTimelineInfo(tag);
|
||||
if( tagTimelines != null && tagTimelines.size() > 0) {
|
||||
tagTimeline = tagTimelines.get(0);
|
||||
statusListAdapter = new StatusListAdapter(context, tagTimeline, targetedId, isOnWifi, behaviorWithAttachments, positionSpinnerTrans, this.statuses);
|
||||
//For Home timeline, fetch stored values for bookmark and last read toot
|
||||
if( type == RetrieveFeedsAsyncTask.Type.HOME) {
|
||||
initialBookMark = sharedpreferences.getString(Helper.BOOKMARK_ID + userId + instance, null);
|
||||
lastReadToot = sharedpreferences.getString(Helper.LAST_READ_TOOT_ID + userId + instance, null);
|
||||
}
|
||||
if( instanceType.equals("MASTODON") || instanceType.equals("MISSKEY") ){
|
||||
if( type == RetrieveFeedsAsyncTask.Type.TAG && tag != null) {
|
||||
BaseMainActivity.displayPeertube = null;
|
||||
List<TagTimeline> tagTimelines = new SearchDAO(context, db).getTimelineInfo(tag);
|
||||
if( tagTimelines != null && tagTimelines.size() > 0) {
|
||||
tagTimeline = tagTimelines.get(0);
|
||||
statusListAdapter = new StatusListAdapter(context, tagTimeline, targetedId, isOnWifi, this.statuses);
|
||||
lv_status.setAdapter(statusListAdapter);
|
||||
}
|
||||
}else{
|
||||
BaseMainActivity.displayPeertube = null;
|
||||
statusListAdapter = new StatusListAdapter(context, type, targetedId, isOnWifi, this.statuses);
|
||||
lv_status.setAdapter(statusListAdapter);
|
||||
}
|
||||
}else if( search_peertube == null && (instanceType == null || instanceType.equals("MASTODON"))) {
|
||||
BaseMainActivity.displayPeertube = null;
|
||||
statusListAdapter = new StatusListAdapter(context, type, targetedId, isOnWifi, behaviorWithAttachments, positionSpinnerTrans, this.statuses);
|
||||
lv_status.setAdapter(statusListAdapter);
|
||||
}else {
|
||||
}else if( instanceType.equals("PEERTUBE")){
|
||||
if( remoteInstance != null && MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE) //if it's a Peertube account connected
|
||||
remoteInstance = account.getInstance();
|
||||
BaseMainActivity.displayPeertube = remoteInstance;
|
||||
peertubeAdapater = new PeertubeAdapter(context, remoteInstance, this.peertubes);
|
||||
peertubeAdapater = new PeertubeAdapter(context, remoteInstance, ownVideos, this.peertubes);
|
||||
lv_status.setAdapter(peertubeAdapater);
|
||||
}else if( instanceType.equals("PIXELFED")){
|
||||
if( remoteInstance != null && MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PIXELFED) //if it's a Peertube account connected
|
||||
remoteInstance = account.getInstance();
|
||||
pixelfedListAdapter = new PixelfedListAdapter(context, type, this.statuses);
|
||||
lv_status.setAdapter(pixelfedListAdapter);
|
||||
}else if( instanceType.equals("ART")){
|
||||
artListAdapter = new ArtListAdapter(context, this.statuses);
|
||||
lv_status.setAdapter(artListAdapter);
|
||||
}
|
||||
mLayoutManager = new LinearLayoutManager(context);
|
||||
lv_status.setLayoutManager(mLayoutManager);
|
||||
|
||||
|
||||
instance = sharedpreferences.getString(Helper.PREF_INSTANCE, context!=null?Helper.getLiveInstance(context):null);
|
||||
//Manage broadcast receiver for Mastodon timelines
|
||||
if( MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON) {
|
||||
if( receive_action != null)
|
||||
LocalBroadcastManager.getInstance(context).unregisterReceiver(receive_action);
|
||||
receive_action = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Bundle b = intent.getExtras();
|
||||
assert b != null;
|
||||
Status status = b.getParcelable("status");
|
||||
API.StatusAction statusAction = (API.StatusAction) b.getSerializable("action");
|
||||
if( status != null && statusListAdapter != null) {
|
||||
statusListAdapter.notifyStatusWithActionChanged(statusAction, status);
|
||||
}
|
||||
}
|
||||
};
|
||||
LocalBroadcastManager.getInstance(context).registerReceiver(receive_action, new IntentFilter(Helper.RECEIVE_ACTION));
|
||||
|
||||
if( type == RetrieveFeedsAsyncTask.Type.HOME || type == RetrieveFeedsAsyncTask.Type.LOCAL || type == RetrieveFeedsAsyncTask.Type.PUBLIC){
|
||||
|
||||
if (receive_data != null)
|
||||
LocalBroadcastManager.getInstance(context).unregisterReceiver(receive_data);
|
||||
receive_data = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Bundle b = intent.getExtras();
|
||||
assert b != null;
|
||||
String userIdService = b.getString("userIdService", null);
|
||||
if (userIdService != null && userIdService.equals(userId)) {
|
||||
Status status = b.getParcelable("data");
|
||||
refresh(status);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
if( type == RetrieveFeedsAsyncTask.Type.PUBLIC)
|
||||
LocalBroadcastManager.getInstance(context).registerReceiver(receive_data, new IntentFilter(Helper.RECEIVE_FEDERATED_DATA));
|
||||
else if( type == RetrieveFeedsAsyncTask.Type.HOME)
|
||||
LocalBroadcastManager.getInstance(context).registerReceiver(receive_data, new IntentFilter(Helper.RECEIVE_HOME_DATA));
|
||||
else if( type == RetrieveFeedsAsyncTask.Type.LOCAL)
|
||||
LocalBroadcastManager.getInstance(context).registerReceiver(receive_data, new IntentFilter(Helper.RECEIVE_LOCAL_DATA));
|
||||
}
|
||||
|
||||
if( type == RetrieveFeedsAsyncTask.Type.REMOTE_INSTANCE && search_peertube != null)
|
||||
((Activity)context).setTitle(remoteInstance + " - " + search_peertube);
|
||||
if( type == RetrieveFeedsAsyncTask.Type.REMOTE_INSTANCE && remote_channel_name != null)
|
||||
((Activity)context).setTitle(remote_channel_name + " - " + remoteInstance);
|
||||
lv_status.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy)
|
||||
{
|
||||
if (type != RetrieveFeedsAsyncTask.Type.ART && context instanceof BaseMainActivity ) {
|
||||
if( dy < 0 && !((BaseMainActivity)context).getFloatingVisibility() )
|
||||
((BaseMainActivity) context).manageFloatingButton(true);
|
||||
if( dy > 0 && ((BaseMainActivity)context).getFloatingVisibility() )
|
||||
((BaseMainActivity) context).manageFloatingButton(false);
|
||||
}
|
||||
int firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();
|
||||
if(dy > 0){
|
||||
int visibleItemCount = mLayoutManager.getChildCount();
|
||||
int totalItemCount = mLayoutManager.getItemCount();
|
||||
if(firstVisibleItem + visibleItemCount == totalItemCount && context != null) {
|
||||
if(!flag_loading ) {
|
||||
flag_loading = true;
|
||||
if( type == RetrieveFeedsAsyncTask.Type.USER)
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, type, targetedId, max_id, showMediaOnly, showPinned, showReply, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
else if( type == RetrieveFeedsAsyncTask.Type.TAG)
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, type, tag, targetedId, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
else if( type == RetrieveFeedsAsyncTask.Type.REMOTE_INSTANCE ) {
|
||||
if( search_peertube == null) {
|
||||
if( remote_channel_name == null)
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, type, remoteInstance, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
else
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, remoteInstance, remote_channel_name, null,DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
else
|
||||
asyncTask = new RetrievePeertubeSearchAsyncTask(context, remoteInstance, search_peertube, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}else{
|
||||
if( type == RetrieveFeedsAsyncTask.Type.HOME){
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, type, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}else {
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, type, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
if( type != RetrieveFeedsAsyncTask.Type.POVERVIEW ) //No paginations for Peertube Overviews (it's a fixed size content
|
||||
lv_status.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy)
|
||||
{
|
||||
if (type != RetrieveFeedsAsyncTask.Type.ART && context instanceof BaseMainActivity ) {
|
||||
if( dy < 0 && !((BaseMainActivity)context).getFloatingVisibility() )
|
||||
((BaseMainActivity) context).manageFloatingButton(true);
|
||||
if( dy > 0 && ((BaseMainActivity)context).getFloatingVisibility() )
|
||||
((BaseMainActivity) context).manageFloatingButton(false);
|
||||
}
|
||||
int firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();
|
||||
if(dy > 0){
|
||||
int visibleItemCount = mLayoutManager.getChildCount();
|
||||
int totalItemCount = mLayoutManager.getItemCount();
|
||||
if(firstVisibleItem + visibleItemCount == totalItemCount && context != null) {
|
||||
if(!flag_loading ) {
|
||||
flag_loading = true;
|
||||
manageAsyncTask(true);
|
||||
nextElementLoader.setVisibility(View.VISIBLE);
|
||||
}
|
||||
nextElementLoader.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
nextElementLoader.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
nextElementLoader.setVisibility(View.GONE);
|
||||
}
|
||||
if(type == RetrieveFeedsAsyncTask.Type.HOME && statuses != null && statuses.size() > firstVisibleItem && firstVisibleItem >= 0) {
|
||||
Long bookmarkL = Long.parseLong(statuses.get(firstVisibleItem).getId()) + 1;
|
||||
updatedBookMark = String.valueOf(bookmarkL);
|
||||
if( lastReadToot == null || bookmarkL > Long.parseLong(lastReadToot)) //Last read toot, only incremented if the id of the toot is greater than the recorded one
|
||||
lastReadToot = String.valueOf(bookmarkL);
|
||||
}
|
||||
}
|
||||
if(type == RetrieveFeedsAsyncTask.Type.HOME && statuses != null && statuses.size() > firstVisibleItem && firstVisibleItem >= 0)
|
||||
if( context instanceof BaseMainActivity){
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
Long bookmarkL = Long.parseLong(statuses.get(firstVisibleItem).getId()) + 1;
|
||||
editor.putString(Helper.BOOKMARK_ID + userId + instance, String.valueOf(bookmarkL));
|
||||
editor.apply();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
if( instanceType == null || instanceType.equals("MASTODON"))
|
||||
if( !instanceType.equals("PEERTUBE"))
|
||||
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
|
||||
@Override
|
||||
public void onRefresh() {
|
||||
|
@ -292,67 +357,36 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
break;
|
||||
}
|
||||
if( context != null) {
|
||||
if (type == RetrieveFeedsAsyncTask.Type.USER)
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, type, targetedId, max_id, showMediaOnly, showPinned, showReply,DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
else if (type == RetrieveFeedsAsyncTask.Type.TAG)
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, type, tag, targetedId, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
else if( type == RetrieveFeedsAsyncTask.Type.REMOTE_INSTANCE ) {
|
||||
if( search_peertube == null) {
|
||||
if( remote_channel_name == null)
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, type, remoteInstance, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
else
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, remoteInstance, remote_channel_name, null,DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
else
|
||||
asyncTask = new RetrievePeertubeSearchAsyncTask(context, remoteInstance, search_peertube, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}else {
|
||||
if( type == RetrieveFeedsAsyncTask.Type.HOME ){
|
||||
firstTootsLoaded = false;
|
||||
if( context instanceof BaseMainActivity){
|
||||
initialBookMark = ((BaseMainActivity) context).getBookmark();
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, type, initialBookMark, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
}else {
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, type, null, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
}
|
||||
//Load data depending of the value
|
||||
manageAsyncTask(false);
|
||||
}else {
|
||||
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if( context != null){
|
||||
if (type == RetrieveFeedsAsyncTask.Type.USER)
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, type, targetedId, max_id, showMediaOnly, showPinned, showReply,DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
else if (type == RetrieveFeedsAsyncTask.Type.TAG)
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, type, tag, targetedId, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
else if( type == RetrieveFeedsAsyncTask.Type.REMOTE_INSTANCE ) {
|
||||
if( search_peertube == null) {
|
||||
if( remote_channel_name == null)
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, type, remoteInstance, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
else
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, remoteInstance, remote_channel_name, null,DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
else
|
||||
asyncTask = new RetrievePeertubeSearchAsyncTask(context, remoteInstance, search_peertube, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}else {
|
||||
if( type == RetrieveFeedsAsyncTask.Type.HOME ){
|
||||
firstTootsLoaded = false;
|
||||
if( context instanceof BaseMainActivity){
|
||||
initialBookMark = ((BaseMainActivity) context).getBookmark();
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, type, initialBookMark,DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
}else {
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, type, null, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
}
|
||||
manageAsyncTask(false);
|
||||
}
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
|
||||
return rootView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause(){
|
||||
super.onPause();
|
||||
//Store bookmark on pause
|
||||
if (context instanceof BaseMainActivity && type == RetrieveFeedsAsyncTask.Type.HOME) {
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
if(updatedBookMark != null)
|
||||
editor.putString(Helper.BOOKMARK_ID + userId + instance, updatedBookMark);
|
||||
if( lastReadToot != null)
|
||||
editor.putString(Helper.LAST_READ_TOOT_ID + userId + instance, lastReadToot);
|
||||
if( lastReadToot != null || updatedBookMark != null)
|
||||
editor.apply();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle saveInstance)
|
||||
|
@ -373,16 +407,19 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
super.onDestroy();
|
||||
if(asyncTask != null && asyncTask.getStatus() == AsyncTask.Status.RUNNING)
|
||||
asyncTask.cancel(true);
|
||||
if( receive_action != null)
|
||||
LocalBroadcastManager.getInstance(context).unregisterReceiver(receive_action);
|
||||
if( receive_data != null)
|
||||
LocalBroadcastManager.getInstance(context).unregisterReceiver(receive_data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onRetrieveFeeds(APIResponse apiResponse) {
|
||||
//hide loaders
|
||||
mainLoader.setVisibility(View.GONE);
|
||||
nextElementLoader.setVisibility(View.GONE);
|
||||
//Discards 404 - error which can often happen due to toots which have been deleted
|
||||
if( apiResponse == null || (apiResponse.getError() != null && apiResponse.getError().getStatusCode() != 404) ){
|
||||
//handle other API error but discards 404 - error which can often happen due to toots which have been deleted
|
||||
if( this.peertubes == null || this.statuses == null || apiResponse == null || (apiResponse.getError() != null && apiResponse.getError().getStatusCode() != 404) ){
|
||||
if( apiResponse == null)
|
||||
Toasty.error(context, context.getString(R.string.toast_error),Toast.LENGTH_LONG).show();
|
||||
else
|
||||
|
@ -392,24 +429,38 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
return;
|
||||
}
|
||||
|
||||
if( type == RetrieveFeedsAsyncTask.Type.REMOTE_INSTANCE && peertubeAdapater != null){
|
||||
//For remote Peertube remote instances
|
||||
if(instanceType.equals("PEERTUBE")){
|
||||
int previousPosition = this.peertubes.size();
|
||||
if( max_id == null)
|
||||
max_id = "0";
|
||||
//max_id needs to work like an offset
|
||||
max_id = String.valueOf(Integer.valueOf(max_id) + 50);
|
||||
if( apiResponse.getPeertubes() == null){
|
||||
return;
|
||||
}
|
||||
this.peertubes.addAll(apiResponse.getPeertubes());
|
||||
//If no item were inserted previously the adapter is created
|
||||
if( previousPosition == 0) {
|
||||
peertubeAdapater = new PeertubeAdapter(context, remoteInstance, this.peertubes);
|
||||
peertubeAdapater = new PeertubeAdapter(context, remoteInstance, ownVideos, this.peertubes);
|
||||
lv_status.setAdapter(peertubeAdapater);
|
||||
}else
|
||||
peertubeAdapater.notifyItemRangeInserted(previousPosition, apiResponse.getPeertubes().size());
|
||||
//remove handlers
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
firstLoad = false;
|
||||
if( firstLoad && (apiResponse.getPeertubes() == null || apiResponse.getPeertubes().size() ==0)){
|
||||
textviewNoActionText.setText(R.string.no_video_to_display);
|
||||
textviewNoAction.setVisibility(View.VISIBLE);
|
||||
}
|
||||
flag_loading = false;
|
||||
firstLoad = false;
|
||||
}else {
|
||||
//Add conversation in status
|
||||
if( type == RetrieveFeedsAsyncTask.Type.CONVERSATION ){
|
||||
|
||||
//When Mastodon statuses have been fetched.
|
||||
if( type == RetrieveFeedsAsyncTask.Type.CONVERSATION ){ //Conversation timeline
|
||||
//this timeline is dealt differently because it is embedded in Conversation entity and not directly in statuses
|
||||
List<Conversation> conversations = apiResponse.getConversations();
|
||||
//Statuses from conversation entity are retrieved
|
||||
List<Status> statusesConversations = new ArrayList<>();
|
||||
if( conversations != null) {
|
||||
for (Conversation conversation : conversations) {
|
||||
|
@ -428,90 +479,58 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
}
|
||||
int previousPosition = this.statuses.size();
|
||||
List<Status> statuses = apiResponse.getStatuses();
|
||||
if( type == RetrieveFeedsAsyncTask.Type.HOME) {
|
||||
if (max_id == null || (apiResponse.getMax_id() != null && Long.parseLong(max_id) > Long.parseLong(apiResponse.getMax_id())))
|
||||
max_id = apiResponse.getMax_id();
|
||||
}else {
|
||||
//At this point all statuses are in "List<Status> statuses"
|
||||
//Pagination for Pixelfed
|
||||
if(instanceType.equals("PIXELFED")) {
|
||||
if( max_id == null)
|
||||
max_id = "1";
|
||||
//max_id needs to work like an offset
|
||||
max_id = String.valueOf(Integer.valueOf(max_id) + 1);
|
||||
}else{
|
||||
max_id = apiResponse.getMax_id();
|
||||
}
|
||||
//while max_id is different from null, there are some more toots to load when scrolling
|
||||
flag_loading = (max_id == null );
|
||||
if( firstLoad && (statuses == null || statuses.size() == 0))
|
||||
//If it's the first load and the reply doesn't contain any toots, a message is displayed.
|
||||
if( firstLoad && (statuses == null || statuses.size() == 0)) {
|
||||
textviewNoAction.setVisibility(View.VISIBLE);
|
||||
else
|
||||
lv_status.setVisibility(View.GONE);
|
||||
}else {
|
||||
lv_status.setVisibility(View.VISIBLE);
|
||||
textviewNoAction.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
//First toot are loaded as soon as the bookmark has been retrieved
|
||||
//Only for the Home timeline
|
||||
|
||||
if( type == RetrieveFeedsAsyncTask.Type.HOME && !firstTootsLoaded){
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, type, null, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
asyncTask = new RetrieveFeedsAfterBookmarkAsyncTask(context, null, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
firstTootsLoaded = true;
|
||||
}
|
||||
//Let's deal with statuses
|
||||
if( statuses != null && statuses.size() > 0) {
|
||||
if (type == RetrieveFeedsAsyncTask.Type.HOME) {
|
||||
//Toots are older than the bookmark -> no special treatment with them
|
||||
if( initialBookMark == null || Long.parseLong(statuses.get(0).getId()) + 1 < Long.parseLong(initialBookMark)){
|
||||
this.statuses.addAll(statuses);
|
||||
statusListAdapter.notifyItemRangeInserted(previousPosition, statuses.size());
|
||||
}else { //Toots are younger than the bookmark
|
||||
String currentMaxId = sharedpreferences.getString(Helper.LAST_HOMETIMELINE_MAX_ID + userId + instance, null);
|
||||
int position = 0;
|
||||
while (position < this.statuses.size() && Long.parseLong(statuses.get(0).getId()) < Long.parseLong(this.statuses.get(position).getId())) {
|
||||
position++;
|
||||
}
|
||||
ArrayList<Status> tmpStatuses = new ArrayList<>();
|
||||
for (Status tmpStatus : statuses) {
|
||||
//Mark status at new ones when their id is greater than the bookmark id / Also increments counter
|
||||
if (currentMaxId != null && Long.parseLong(tmpStatus.getId()) > Long.parseLong(currentMaxId)) {
|
||||
tmpStatus.setNew(true);
|
||||
MainActivity.countNewStatus++;
|
||||
}
|
||||
//Put the toot at its place in the list (id desc)
|
||||
if( !this.statuses.contains(tmpStatus) ) { //Element not already addeds
|
||||
tmpStatuses.add(tmpStatus);
|
||||
}
|
||||
}
|
||||
int tootPerPage = sharedpreferences.getInt(Helper.SET_TOOTS_PER_PAGE, 40);
|
||||
if( tmpStatuses.size() >= tootPerPage) {
|
||||
if (!fetchMoreButtonDisplayed && tmpStatuses.size() > 0 && Long.parseLong(tmpStatuses.get(tmpStatuses.size() - 1).getId()) > Long.parseLong(initialBookMark)) {
|
||||
tmpStatuses.get(tmpStatuses.size() - 1).setFetchMore(true);
|
||||
fetchMoreButtonDisplayed = true;
|
||||
}
|
||||
}
|
||||
this.statuses.addAll(position, tmpStatuses);
|
||||
statusListAdapter.notifyItemRangeInserted(position, tmpStatuses.size());
|
||||
if( tmpStatuses.size() < 3) //If new toots are only two
|
||||
lv_status.scrollToPosition(0);
|
||||
else {
|
||||
lv_status.scrollToPosition(position + tmpStatuses.size());
|
||||
}
|
||||
}
|
||||
|
||||
}else if ( statusListAdapter != null){
|
||||
if( tagTimeline == null || !tagTimeline.isART() || (tagTimeline.isART() && tagTimeline.isNSFW())) {
|
||||
this.statuses.addAll(statuses);
|
||||
statusListAdapter.notifyItemRangeInserted(previousPosition, statuses.size());
|
||||
}else { //If it's an Art timeline not allowing NSFW
|
||||
if ( statusListAdapter != null && ( instanceType.equals("MASTODON") || instanceType.equals("MISSKEY"))) {
|
||||
this.statuses.addAll(statuses);
|
||||
statusListAdapter.notifyItemRangeInserted(previousPosition, statuses.size());
|
||||
}else if(artListAdapter != null && instanceType.equals("ART") ) {
|
||||
boolean show_nsfw = sharedpreferences.getBoolean(Helper.SET_ART_WITH_NSFW, false);
|
||||
if( !show_nsfw) {
|
||||
ArrayList<Status> safeStatuses = new ArrayList<>();
|
||||
|
||||
for(Status status: statuses){
|
||||
if( !status.isSensitive())
|
||||
safeStatuses.add(status);
|
||||
safeStatuses.add(status);
|
||||
}
|
||||
this.statuses.addAll(safeStatuses);
|
||||
statusListAdapter.notifyItemRangeInserted(previousPosition, safeStatuses.size());
|
||||
artListAdapter.notifyItemRangeInserted(previousPosition, safeStatuses.size());
|
||||
}else {
|
||||
this.statuses.addAll(statuses);
|
||||
artListAdapter.notifyItemRangeInserted(previousPosition, statuses.size());
|
||||
}
|
||||
|
||||
}else if(pixelfedListAdapter != null && instanceType.equals("PIXELFED") ) {
|
||||
this.statuses.addAll(statuses);
|
||||
pixelfedListAdapter.notifyItemRangeInserted(previousPosition, statuses.size());
|
||||
}
|
||||
if( type == RetrieveFeedsAsyncTask.Type.HOME ) {
|
||||
//Update the id of the last toot retrieved
|
||||
if( MainActivity.lastHomeId == null || Long.parseLong(statuses.get(0).getId()) > Long.parseLong(MainActivity.lastHomeId))
|
||||
MainActivity.lastHomeId = statuses.get(0).getId();
|
||||
if( firstLoad )
|
||||
updateStatusLastId(statuses.get(0).getId());
|
||||
}
|
||||
if( type == RetrieveFeedsAsyncTask.Type.HOME)
|
||||
//Display new value in counter
|
||||
try {
|
||||
((MainActivity) context).updateHomeCounter();
|
||||
}catch (Exception ignored){}
|
||||
}
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
firstLoad = false;
|
||||
|
@ -540,13 +559,15 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
//Update the id of the last toot retrieved
|
||||
MainActivity.lastHomeId = status.getId();
|
||||
statuses.add(0, status);
|
||||
if (!status.getAccount().getId().equals(userId))
|
||||
if (status.getAccount() != null && !status.getAccount().getId().equals(userId)) {
|
||||
MainActivity.countNewStatus++;
|
||||
statusListAdapter.notifyItemInserted(0);
|
||||
if (textviewNoAction.getVisibility() == View.VISIBLE)
|
||||
textviewNoAction.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
try {
|
||||
((MainActivity) context).updateHomeCounter();
|
||||
}catch (Exception ignored){}
|
||||
|
||||
statusListAdapter.notifyItemInserted(0);
|
||||
}
|
||||
|
||||
} else if (type == RetrieveFeedsAsyncTask.Type.PUBLIC || type == RetrieveFeedsAsyncTask.Type.LOCAL|| type == RetrieveFeedsAsyncTask.Type.DIRECT) {
|
||||
|
||||
|
@ -570,8 +591,24 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
super.onResume();
|
||||
boolean liveNotifications = sharedpreferences.getBoolean(Helper.SET_LIVE_NOTIFICATIONS, true);
|
||||
int batteryProfile = sharedpreferences.getInt(Helper.SET_BATTERY_PROFILE, Helper.BATTERY_PROFILE_NORMAL);
|
||||
if( type == RetrieveFeedsAsyncTask.Type.PUBLIC){
|
||||
|
||||
|
||||
if (type == RetrieveFeedsAsyncTask.Type.HOME){
|
||||
if( getUserVisibleHint() ){
|
||||
statusListAdapter.updateMuted(mutedAccount);
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putBoolean(Helper.SHOULD_CONTINUE_STREAMING_HOME + userId + instance, true);
|
||||
editor.apply();
|
||||
if(liveNotifications && batteryProfile == Helper.BATTERY_PROFILE_NORMAL) {
|
||||
streamingHomeIntent = new Intent(context, StreamingHomeTimelineService.class);
|
||||
try {
|
||||
context.startService(streamingHomeIntent);
|
||||
}catch (Exception ignored){}
|
||||
}
|
||||
if( statuses != null && statuses.size() > 0)
|
||||
retrieveMissingToots(statuses.get(0).getId());
|
||||
}
|
||||
} else if( type == RetrieveFeedsAsyncTask.Type.PUBLIC){
|
||||
if( getUserVisibleHint() ){
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putBoolean(Helper.SHOULD_CONTINUE_STREAMING_FEDERATED + userId + instance, true);
|
||||
|
@ -610,10 +647,6 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
if( statuses != null && statuses.size() > 0)
|
||||
retrieveMissingToots(statuses.get(0).getId());
|
||||
}
|
||||
}else if (type == RetrieveFeedsAsyncTask.Type.HOME){
|
||||
statusListAdapter.updateMuted(mutedAccount);
|
||||
if( statuses != null && statuses.size() > 0)
|
||||
retrieveMissingToots(statuses.get(0).getId());
|
||||
}else if (type == RetrieveFeedsAsyncTask.Type.TAG){
|
||||
if( getUserVisibleHint() ){
|
||||
if( statuses != null && statuses.size() > 0)
|
||||
|
@ -627,8 +660,13 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
* @param sinceId String
|
||||
*/
|
||||
public void retrieveMissingToots(String sinceId){
|
||||
if (type == RetrieveFeedsAsyncTask.Type.REMOTE_INSTANCE)
|
||||
|
||||
if( type == RetrieveFeedsAsyncTask.Type.HOME)
|
||||
asyncTask = new RetrieveFeedsAfterBookmarkAsyncTask(context, null, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
if (type == RetrieveFeedsAsyncTask.Type.REMOTE_INSTANCE )
|
||||
asyncTask = new RetrieveMissingFeedsAsyncTask(context, remoteInstance, sinceId, type, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
else if(type == RetrieveFeedsAsyncTask.Type.TAG)
|
||||
asyncTask = new RetrieveMissingFeedsAsyncTask(context, tag, sinceId, type, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
else
|
||||
asyncTask = new RetrieveMissingFeedsAsyncTask(context, sinceId, type, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
|
||||
|
@ -646,8 +684,28 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
boolean liveNotifications = sharedpreferences.getBoolean(Helper.SET_LIVE_NOTIFICATIONS, true);
|
||||
int batteryProfile = sharedpreferences.getInt(Helper.SET_BATTERY_PROFILE, Helper.BATTERY_PROFILE_NORMAL);
|
||||
//Store last toot id for home timeline to avoid to notify for those that have been already seen
|
||||
if (type == RetrieveFeedsAsyncTask.Type.HOME && visible && statuses != null && statuses.size() > 0) {
|
||||
updateStatusLastId(statuses.get(0).getId());
|
||||
if (type == RetrieveFeedsAsyncTask.Type.HOME ) {
|
||||
|
||||
if (visible) {
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putBoolean(Helper.SHOULD_CONTINUE_STREAMING_HOME + userId + instance, true);
|
||||
editor.apply();
|
||||
if(liveNotifications && batteryProfile == Helper.BATTERY_PROFILE_NORMAL) {
|
||||
streamingHomeIntent = new Intent(context, StreamingHomeTimelineService.class);
|
||||
try {
|
||||
context.startService(streamingHomeIntent);
|
||||
}catch (Exception ignored){}
|
||||
}
|
||||
if( statuses != null && statuses.size() > 0)
|
||||
retrieveMissingToots(statuses.get(0).getId());
|
||||
}else {
|
||||
if( streamingHomeIntent != null ){
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putBoolean(Helper.SHOULD_CONTINUE_STREAMING_HOME + userId + instance, false);
|
||||
editor.apply();
|
||||
context.stopService(streamingHomeIntent);
|
||||
}
|
||||
}
|
||||
} else if( type == RetrieveFeedsAsyncTask.Type.PUBLIC ){
|
||||
if (visible) {
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
|
@ -696,7 +754,12 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
@Override
|
||||
public void onStop(){
|
||||
super.onStop();
|
||||
if( type == RetrieveFeedsAsyncTask.Type.PUBLIC && streamingFederatedIntent != null){
|
||||
if( type == RetrieveFeedsAsyncTask.Type.HOME && streamingHomeIntent != null){
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putBoolean(Helper.SHOULD_CONTINUE_STREAMING_HOME + userId + instance, false);
|
||||
editor.apply();
|
||||
context.stopService(streamingHomeIntent);
|
||||
} else if( type == RetrieveFeedsAsyncTask.Type.PUBLIC && streamingFederatedIntent != null){
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putBoolean(Helper.SHOULD_CONTINUE_STREAMING_FEDERATED + userId + instance, false);
|
||||
editor.apply();
|
||||
|
@ -710,12 +773,13 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
}
|
||||
|
||||
public void scrollToTop(){
|
||||
if( lv_status != null) {
|
||||
lv_status.setAdapter(statusListAdapter);
|
||||
//Store last toot id for home timeline to avoid to notify for those that have been already seen
|
||||
if (type == RetrieveFeedsAsyncTask.Type.HOME && statuses != null && statuses.size() > 0) {
|
||||
updateStatusLastId(statuses.get(0).getId());
|
||||
}
|
||||
if( lv_status != null && instanceType != null) {
|
||||
if( statusListAdapter != null && (instanceType.equals("MASTODON") || instanceType.equals("MISSKEY")))
|
||||
lv_status.setAdapter(statusListAdapter);
|
||||
else if( pixelfedListAdapter != null && instanceType.equals("PIXELFED"))
|
||||
lv_status.setAdapter(pixelfedListAdapter);
|
||||
else if( artListAdapter != null && instanceType.equals("ART"))
|
||||
lv_status.setAdapter(artListAdapter);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -723,7 +787,13 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
* Refresh status in list
|
||||
*/
|
||||
public void refreshFilter(){
|
||||
statusListAdapter.notifyDataSetChanged();
|
||||
|
||||
if( instanceType.equals("MASTODON") || instanceType.equals("MISSKEY"))
|
||||
statusListAdapter.notifyDataSetChanged();
|
||||
else if( instanceType.equals("PIXELFED"))
|
||||
pixelfedListAdapter.notifyDataSetChanged();
|
||||
else if( instanceType.equals("ART"))
|
||||
artListAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -736,7 +806,12 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
for (Status status : this.statuses) {
|
||||
status.setNew(false);
|
||||
}
|
||||
statusListAdapter.notifyItemRangeChanged(0, this.statuses.size());
|
||||
if( instanceType.equals("MASTODON") || instanceType.equals("MISSKEY"))
|
||||
statusListAdapter.notifyItemRangeChanged(0, this.statuses.size());
|
||||
else if( instanceType.equals("PIXELFED"))
|
||||
pixelfedListAdapter.notifyItemRangeChanged(0, this.statuses.size());
|
||||
else if( instanceType.equals("ART"))
|
||||
artListAdapter.notifyItemRangeChanged(0, this.statuses.size());
|
||||
}
|
||||
isSwipped = false;
|
||||
if( statuses != null && statuses.size() > 0) {
|
||||
|
@ -746,14 +821,16 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
int position = 0;
|
||||
insertedConversation = statuses.size();
|
||||
if( this.statuses != null) {
|
||||
long initialConversationId = -1;
|
||||
if( this.statuses.size() > 0 )
|
||||
initialConversationId = Long.parseLong(this.statuses.get(0).getConversationId());
|
||||
for (Iterator<Status> it = this.statuses.iterator(); it.hasNext(); ) {
|
||||
Status status = it.next();
|
||||
for (Status status1 : statuses) {
|
||||
if (status.getConversationId() != null && status.getConversationId().equals(status1.getConversationId())) {
|
||||
statusListAdapter.notifyItemRemoved(position);
|
||||
if( instanceType.equals("MASTODON") || instanceType.equals("MISSKEY"))
|
||||
statusListAdapter.notifyItemRemoved(position);
|
||||
else if( instanceType.equals("PIXELFED"))
|
||||
pixelfedListAdapter.notifyItemRemoved(position);
|
||||
else if( instanceType.equals("ART"))
|
||||
artListAdapter.notifyItemRemoved(position);
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
|
@ -763,18 +840,45 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
}
|
||||
for (int i = statuses.size() - 1; i >= 0; i--) {
|
||||
if( this.statuses != null) {
|
||||
if (this.statuses.size() == 0 ||
|
||||
Long.parseLong(statuses.get(i).getId()) > Long.parseLong(this.statuses.get(0).getId())) {
|
||||
if (type == RetrieveFeedsAsyncTask.Type.HOME)
|
||||
statuses.get(i).setNew(true);
|
||||
inserted++;
|
||||
this.statuses.add(0, statuses.get(i));
|
||||
if (type == RetrieveFeedsAsyncTask.Type.HOME && !statuses.get(i).getAccount().getId().equals(userId))
|
||||
MainActivity.countNewStatus++;
|
||||
if( type != RetrieveFeedsAsyncTask.Type.HOME){
|
||||
if( tagTimeline == null || !tagTimeline.isART() || (tagTimeline.isART() && tagTimeline.isNSFW())) {
|
||||
if (this.statuses.size() == 0 || Long.parseLong(statuses.get(i).getId()) > Long.parseLong(this.statuses.get(0).getId())) {
|
||||
inserted++;
|
||||
this.statuses.add(0, statuses.get(i));
|
||||
|
||||
}
|
||||
}else{
|
||||
ArrayList<Status> safeStatuses = new ArrayList<>();
|
||||
for(Status status: statuses){
|
||||
if( !status.isSensitive())
|
||||
safeStatuses.add(status);
|
||||
}
|
||||
this.statuses.addAll(safeStatuses);
|
||||
if( instanceType.equals("MASTODON") || instanceType.equals("MISSKEY"))
|
||||
statusListAdapter.notifyItemRangeInserted(0, safeStatuses.size());
|
||||
else if( instanceType.equals("PIXELFED"))
|
||||
pixelfedListAdapter.notifyItemRangeInserted(0, safeStatuses.size());
|
||||
else if( instanceType.equals("ART"))
|
||||
artListAdapter.notifyItemRangeInserted(0, safeStatuses.size());
|
||||
}
|
||||
}else {
|
||||
if( lastReadToot != null && Long.parseLong(statuses.get(i).getId()) > Long.parseLong(lastReadToot)) {
|
||||
if( !this.statuses.contains(statuses.get(i)) ) {
|
||||
statuses.get(i).setNew(true);
|
||||
MainActivity.countNewStatus++;
|
||||
inserted++;
|
||||
this.statuses.add(0, statuses.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
statusListAdapter.notifyItemRangeInserted(0, inserted);
|
||||
if( instanceType.equals("MASTODON") || instanceType.equals("MISSKEY"))
|
||||
statusListAdapter.notifyItemRangeInserted(0, inserted);
|
||||
else if( instanceType.equals("PIXELFED"))
|
||||
pixelfedListAdapter.notifyItemRangeInserted(0, inserted);
|
||||
else if( instanceType.equals("ART"))
|
||||
artListAdapter.notifyItemRangeInserted(0, inserted);
|
||||
try {
|
||||
if( type == RetrieveFeedsAsyncTask.Type.HOME)
|
||||
((MainActivity) context).updateHomeCounter();
|
||||
|
@ -790,22 +894,102 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
|
||||
public void fetchMore(String max_id){
|
||||
fetchMoreButtonDisplayed = false;
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, type, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
asyncTask = new RetrieveFeedsAfterBookmarkAsyncTask(context, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Records the id of the status only if its greater than the previous one.
|
||||
* @param statusId String current status id to check
|
||||
*/
|
||||
private void updateStatusLastId(String statusId){
|
||||
|
||||
String lastNotif = sharedpreferences.getString(Helper.LAST_HOMETIMELINE_MAX_ID + userId + instance, null);
|
||||
if( lastNotif == null || Long.parseLong(statusId) > Long.parseLong(lastNotif)){
|
||||
MainActivity.countNewStatus = 0;
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.LAST_HOMETIMELINE_MAX_ID + userId + instance, statusId);
|
||||
editor.apply();
|
||||
@Override
|
||||
public void onRetrieveFeedsAfterBookmark(APIResponse apiResponse) {
|
||||
if( apiResponse == null || (apiResponse.getError() != null && apiResponse.getError().getStatusCode() != 404) ){
|
||||
if( apiResponse == null)
|
||||
Toasty.error(context, context.getString(R.string.toast_error),Toast.LENGTH_LONG).show();
|
||||
else
|
||||
Toasty.error(context, apiResponse.getError().getError(),Toast.LENGTH_LONG).show();
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
flag_loading = false;
|
||||
return;
|
||||
}
|
||||
List<Status> statuses = apiResponse.getStatuses();
|
||||
if( statuses == null || statuses.size() == 0 )
|
||||
return;
|
||||
//Find the position of toots between those already present
|
||||
int position = 0;
|
||||
while (position < this.statuses.size() && Long.parseLong(statuses.get(0).getId()) < Long.parseLong(this.statuses.get(position).getId())) {
|
||||
position++;
|
||||
}
|
||||
ArrayList<Status> tmpStatuses = new ArrayList<>();
|
||||
for (Status tmpStatus : statuses) {
|
||||
//Put the toot at its place in the list (id desc)
|
||||
if( !this.statuses.contains(tmpStatus) ) { //Element not already added
|
||||
//Mark status at new ones when their id is greater than the last read toot id
|
||||
if (type == RetrieveFeedsAsyncTask.Type.HOME && lastReadToot != null && Long.parseLong(tmpStatus.getId()) > Long.parseLong(lastReadToot)) {
|
||||
tmpStatus.setNew(true);
|
||||
MainActivity.countNewStatus++;
|
||||
}
|
||||
tmpStatuses.add(tmpStatus);
|
||||
}
|
||||
}
|
||||
try {
|
||||
((MainActivity) context).updateHomeCounter();
|
||||
}catch (Exception ignored){}
|
||||
int tootPerPage = sharedpreferences.getInt(Helper.SET_TOOTS_PER_PAGE, 40);
|
||||
//Display the fetch more toot button
|
||||
if( tmpStatuses.size() >= tootPerPage) {
|
||||
if (initialBookMark != null && !fetchMoreButtonDisplayed && tmpStatuses.size() > 0 && Long.parseLong(tmpStatuses.get(tmpStatuses.size() - 1).getId()) > Long.parseLong(initialBookMark)) {
|
||||
tmpStatuses.get(tmpStatuses.size() - 1).setFetchMore(true);
|
||||
fetchMoreButtonDisplayed = true;
|
||||
}
|
||||
}
|
||||
this.statuses.addAll(position, tmpStatuses);
|
||||
statusListAdapter.notifyItemRangeInserted(position, tmpStatuses.size());
|
||||
if( textviewNoAction.getVisibility() == View.VISIBLE && tmpStatuses.size() > 0){
|
||||
textviewNoAction.setVisibility(View.GONE);
|
||||
lv_status.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
//Update last read toots value when pressing tab button
|
||||
public void updateLastReadToot(){
|
||||
if (type == RetrieveFeedsAsyncTask.Type.HOME && this.statuses != null && this.statuses.size() > 0) {
|
||||
lastReadToot = this.statuses.get(0).getId();
|
||||
}
|
||||
}
|
||||
|
||||
private void manageAsyncTask(boolean pagination){
|
||||
//Message for an account
|
||||
if (type == RetrieveFeedsAsyncTask.Type.USER || type == RetrieveFeedsAsyncTask.Type.CHANNEL)
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, type, targetedId, max_id, showMediaOnly, showPinned, showReply,DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
//Tag timelines
|
||||
else if (type == RetrieveFeedsAsyncTask.Type.TAG)
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, type, tag, targetedId, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
else if( type == RetrieveFeedsAsyncTask.Type.REMOTE_INSTANCE) {
|
||||
//Remote instances
|
||||
if( search_peertube == null) { //Not a Peertube search
|
||||
if( remote_channel_name == null) { //Not a channel
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, type, remoteInstance, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
else
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, remoteInstance, remote_channel_name, null, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
else
|
||||
asyncTask = new RetrievePeertubeSearchAsyncTask(context, remoteInstance, search_peertube, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}else {
|
||||
if( !pagination) {
|
||||
if (type == RetrieveFeedsAsyncTask.Type.HOME) {
|
||||
if (context instanceof BaseMainActivity) {
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, type, initialBookMark, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
} else { //Most classical search will be done by this call
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, type, null, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
}else {
|
||||
if( type == RetrieveFeedsAsyncTask.Type.HOME){
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, type, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}else {//Most classical search will be done by this call for pagination
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, type, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -16,13 +16,11 @@ package fr.gouv.etalab.mastodon.fragments;
|
|||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentUris;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.net.Uri;
|
||||
|
@ -52,8 +50,6 @@ import android.widget.Spinner;
|
|||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import es.dmoral.toasty.Toasty;
|
||||
import fr.gouv.etalab.mastodon.R;
|
||||
import fr.gouv.etalab.mastodon.activities.MainActivity;
|
||||
|
@ -63,7 +59,7 @@ import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
|
|||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||
|
||||
import static android.app.Activity.RESULT_OK;
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.CHANGE_THEME_INTENT;
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.BACK_TO_SETTINGS;
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.INTENT_ACTION;
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.SET_YANDEX_API_KEY;
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.changeDrawableColor;
|
||||
|
@ -404,7 +400,7 @@ public class SettingsFragment extends Fragment {
|
|||
if( getActivity() != null)
|
||||
getActivity().recreate();
|
||||
Intent intent = new Intent(context, MainActivity.class);
|
||||
intent.putExtra(INTENT_ACTION, CHANGE_THEME_INTENT);
|
||||
intent.putExtra(INTENT_ACTION, BACK_TO_SETTINGS);
|
||||
if(getActivity() != null)
|
||||
getActivity().finish();
|
||||
startActivity(intent);
|
||||
|
@ -425,7 +421,7 @@ public class SettingsFragment extends Fragment {
|
|||
if( getActivity() != null)
|
||||
getActivity().recreate();
|
||||
Intent intent = new Intent(context, MainActivity.class);
|
||||
intent.putExtra(INTENT_ACTION, CHANGE_THEME_INTENT);
|
||||
intent.putExtra(INTENT_ACTION, BACK_TO_SETTINGS);
|
||||
if(getActivity() != null)
|
||||
getActivity().finish();
|
||||
startActivity(intent);
|
||||
|
@ -624,7 +620,7 @@ public class SettingsFragment extends Fragment {
|
|||
if (getActivity() != null)
|
||||
getActivity().recreate();
|
||||
Intent intent = new Intent(context, MainActivity.class);
|
||||
intent.putExtra(INTENT_ACTION, CHANGE_THEME_INTENT);
|
||||
intent.putExtra(INTENT_ACTION, BACK_TO_SETTINGS);
|
||||
startActivity(intent);
|
||||
}
|
||||
count1++;
|
||||
|
@ -636,114 +632,6 @@ public class SettingsFragment extends Fragment {
|
|||
});
|
||||
|
||||
|
||||
String currentLanguage = sharedpreferences.getString(Helper.SET_DEFAULT_LOCALE_NEW, Helper.localeToStringStorage(Locale.getDefault()));
|
||||
Locale currentLocale = Helper.restoreLocaleFromString(currentLanguage);
|
||||
final Spinner set_change_locale = rootView.findViewById(R.id.set_change_locale);
|
||||
ArrayAdapter<String> adapterLocale = new ArrayAdapter<>(context,
|
||||
android.R.layout.simple_spinner_dropdown_item, Helper.getLocales(context));
|
||||
|
||||
set_change_locale.setAdapter(adapterLocale);
|
||||
|
||||
int positionSpinnerLanguage = Helper.languageSpinnerPosition(context);
|
||||
set_change_locale.setSelection(positionSpinnerLanguage);
|
||||
set_change_locale.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
if( count2 > 0 ) {
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
switch (position) {
|
||||
case 0:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, Helper.getDefaultLocale());
|
||||
editor.commit();
|
||||
break;
|
||||
case 1:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "en");
|
||||
editor.commit();
|
||||
break;
|
||||
case 2:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "fr");
|
||||
editor.commit();
|
||||
break;
|
||||
case 3:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "de");
|
||||
editor.commit();
|
||||
break;
|
||||
case 4:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "it");
|
||||
editor.commit();
|
||||
break;
|
||||
case 5:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "ja");
|
||||
editor.commit();
|
||||
break;
|
||||
case 6:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW,"zh-TW");
|
||||
editor.commit();
|
||||
break;
|
||||
case 7:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "zh-CN");
|
||||
editor.commit();
|
||||
break;
|
||||
case 8:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "eu");
|
||||
editor.commit();
|
||||
break;
|
||||
case 9:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "ar");
|
||||
editor.commit();
|
||||
break;
|
||||
case 10:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "nl");
|
||||
editor.commit();
|
||||
break;
|
||||
case 11:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "gl");
|
||||
editor.commit();
|
||||
break;
|
||||
case 12:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "el");
|
||||
editor.commit();
|
||||
break;
|
||||
case 13:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "pt");
|
||||
editor.commit();
|
||||
break;
|
||||
case 14:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "es");
|
||||
editor.commit();
|
||||
break;
|
||||
case 15:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "pl");
|
||||
editor.commit();
|
||||
break;
|
||||
case 16:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "sr");
|
||||
editor.commit();
|
||||
break;
|
||||
case 17:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "uk");
|
||||
editor.commit();
|
||||
case 18:
|
||||
editor.putString(Helper.SET_DEFAULT_LOCALE_NEW, "ru");
|
||||
editor.commit();
|
||||
break;
|
||||
}
|
||||
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
Intent intent = packageManager.getLaunchIntentForPackage(context.getPackageName());
|
||||
assert intent != null;
|
||||
ComponentName componentName = intent.getComponent();
|
||||
Intent mainIntent = Intent.makeRestartActivityTask(componentName);
|
||||
context.startActivity(mainIntent);
|
||||
Runtime.getRuntime().exit(0);
|
||||
}
|
||||
count2++;
|
||||
}
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
// NSFW Timeout
|
||||
SeekBar nsfwTimeoutSeekBar = rootView.findViewById(R.id.set_nsfw_timeout);
|
||||
|
@ -955,7 +843,7 @@ public class SettingsFragment extends Fragment {
|
|||
if( getActivity() != null)
|
||||
getActivity().recreate();
|
||||
Intent intent = new Intent(context, MainActivity.class);
|
||||
intent.putExtra(INTENT_ACTION, CHANGE_THEME_INTENT);
|
||||
intent.putExtra(INTENT_ACTION, BACK_TO_SETTINGS);
|
||||
startActivity(intent);
|
||||
}
|
||||
count3++;
|
||||
|
|
|
@ -57,7 +57,7 @@ public class SettingsNotificationsFragment extends Fragment {
|
|||
private int style;
|
||||
private static final int ACTIVITY_CHOOSE_SOUND = 412;
|
||||
int count = 0;
|
||||
|
||||
int count1 = 0;
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
|
||||
|
||||
|
@ -209,6 +209,48 @@ public class SettingsNotificationsFragment extends Fragment {
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
final Spinner action_notification = rootView.findViewById(R.id.action_notification);
|
||||
ArrayAdapter<CharSequence> adapterAction = ArrayAdapter.createFromResource(getContext(),
|
||||
R.array.action_notification, android.R.layout.simple_spinner_item);
|
||||
action_notification.setAdapter(adapterAction);
|
||||
int positionNotificationAntion;
|
||||
switch (sharedpreferences.getInt(Helper.SET_NOTIFICATION_ACTION, Helper.ACTION_ACTIVE)){
|
||||
case Helper.ACTION_ACTIVE:
|
||||
positionNotificationAntion = 0;
|
||||
break;
|
||||
case Helper.ACTION_SILENT:
|
||||
positionNotificationAntion = 1;
|
||||
break;
|
||||
default:
|
||||
positionNotificationAntion = 0;
|
||||
}
|
||||
action_notification.setSelection(positionNotificationAntion);
|
||||
action_notification.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
if( count1 > 0 ) {
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
|
||||
switch (position) {
|
||||
case 0:
|
||||
editor.putInt(Helper.SET_NOTIFICATION_ACTION, Helper.ACTION_ACTIVE);
|
||||
editor.apply();
|
||||
break;
|
||||
case 1:
|
||||
editor.putInt(Helper.SET_NOTIFICATION_ACTION, Helper.ACTION_SILENT);
|
||||
editor.apply();
|
||||
break;
|
||||
}
|
||||
}
|
||||
count1++;
|
||||
}
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
set_notif_follow.setChecked(notif_follow);
|
||||
set_notif_follow_add.setChecked(notif_add);
|
||||
set_notif_follow_ask.setChecked(notif_ask);
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
package fr.gouv.etalab.mastodon.fragments;
|
||||
/* Copyright 2018 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Mastalab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Mastalab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.Spinner;
|
||||
|
||||
import fr.gouv.etalab.mastodon.R;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Created by Thomas on 06/01/2019.
|
||||
* Fragment for peertube settings
|
||||
*/
|
||||
public class SettingsPeertubeFragment extends Fragment {
|
||||
|
||||
|
||||
private Context context;
|
||||
private int count1;
|
||||
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
|
||||
final View rootView = inflater.inflate(R.layout.fragment_peertube_settings, container, false);
|
||||
context = getContext();
|
||||
assert context != null;
|
||||
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
|
||||
int videoMode = sharedpreferences.getInt(Helper.SET_VIDEO_MODE, Helper.VIDEO_MODE_DIRECT);
|
||||
|
||||
|
||||
//Video mode
|
||||
final Spinner video_mode_spinner = rootView.findViewById(R.id.set_video_mode);
|
||||
ArrayAdapter<CharSequence> video_mode_spinnerAdapter = ArrayAdapter.createFromResource(getContext(),
|
||||
R.array.settings_video_mode, android.R.layout.simple_spinner_item);
|
||||
video_mode_spinner.setAdapter(video_mode_spinnerAdapter);
|
||||
if (videoMode == Helper.VIDEO_MODE_TORRENT)
|
||||
videoMode = 2;
|
||||
video_mode_spinner.setSelection(videoMode);
|
||||
video_mode_spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
if( count1 > 0 ) {
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
switch (position) {
|
||||
/*case 0:
|
||||
editor.putInt(Helper.SET_VIDEO_MODE, Helper.VIDEO_MODE_TORRENT);
|
||||
editor.apply();
|
||||
break;*/
|
||||
case 1:
|
||||
editor.putInt(Helper.SET_VIDEO_MODE, Helper.VIDEO_MODE_WEBVIEW);
|
||||
editor.apply();
|
||||
break;
|
||||
case 2:
|
||||
editor.putInt(Helper.SET_VIDEO_MODE, Helper.VIDEO_MODE_DIRECT);
|
||||
editor.apply();
|
||||
break;
|
||||
}
|
||||
}
|
||||
count1++;
|
||||
}
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
boolean video_nsfw = sharedpreferences.getBoolean(Helper.SET_VIDEO_NSFW, false);
|
||||
final CheckBox set_video_nsfw = rootView.findViewById(R.id.set_video_nsfw);
|
||||
set_video_nsfw.setChecked(video_nsfw);
|
||||
|
||||
set_video_nsfw.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putBoolean(Helper.SET_VIDEO_NSFW, set_video_nsfw.isChecked());
|
||||
editor.apply();
|
||||
}
|
||||
});
|
||||
|
||||
return rootView;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle saveInstance) {
|
||||
super.onCreate(saveInstance);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -43,7 +43,8 @@ public class TabLayoutScheduleFragment extends Fragment {
|
|||
View inflatedView = inflater.inflate(R.layout.tablayout_toots, container, false);
|
||||
|
||||
TabLayout tabLayout = inflatedView.findViewById(R.id.tabLayout);
|
||||
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.toots)));
|
||||
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.toots_server)));
|
||||
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.toots_client)));
|
||||
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.reblog)));
|
||||
final ViewPager viewPager = inflatedView.findViewById(R.id.viewpager);
|
||||
viewPager.setAdapter(new PagerAdapter
|
||||
|
@ -87,10 +88,16 @@ public class TabLayoutScheduleFragment extends Fragment {
|
|||
case 0:
|
||||
DisplayScheduledTootsFragment displayScheduledTootsFragment = new DisplayScheduledTootsFragment();
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putSerializable("type", DisplayScheduledTootsFragment.typeOfSchedule.TOOT);
|
||||
bundle.putSerializable("type", DisplayScheduledTootsFragment.typeOfSchedule.SERVER);
|
||||
displayScheduledTootsFragment.setArguments(bundle);
|
||||
return displayScheduledTootsFragment;
|
||||
case 1:
|
||||
displayScheduledTootsFragment = new DisplayScheduledTootsFragment();
|
||||
bundle = new Bundle();
|
||||
bundle.putSerializable("type", DisplayScheduledTootsFragment.typeOfSchedule.TOOT);
|
||||
displayScheduledTootsFragment.setArguments(bundle);
|
||||
return displayScheduledTootsFragment;
|
||||
case 2:
|
||||
displayScheduledTootsFragment = new DisplayScheduledTootsFragment();
|
||||
bundle = new Bundle();
|
||||
bundle.putSerializable("type", DisplayScheduledTootsFragment.typeOfSchedule.BOOST);
|
||||
|
|
|
@ -52,7 +52,7 @@ public class TabLayoutTootsFragment extends Fragment {
|
|||
final ViewPager viewPager = inflatedView.findViewById(R.id.viewpager);
|
||||
Bundle bundle = this.getArguments();
|
||||
if (bundle != null) {
|
||||
this.targetedId = bundle.getString("targetedId", null);
|
||||
this.targetedId = bundle.getString("targetedid", null);
|
||||
}
|
||||
viewPager.setAdapter(new PagerAdapter
|
||||
(getChildFragmentManager(), tabLayout.getTabCount()));
|
||||
|
@ -97,7 +97,7 @@ public class TabLayoutTootsFragment extends Fragment {
|
|||
DisplayStatusFragment displayStatusFragment = new DisplayStatusFragment();
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putSerializable("type", RetrieveFeedsAsyncTask.Type.USER);
|
||||
bundle.putString("targetedId", targetedId);
|
||||
bundle.putString("targetedid", targetedId);
|
||||
bundle.putBoolean("showReply",false);
|
||||
displayStatusFragment.setArguments(bundle);
|
||||
return displayStatusFragment;
|
||||
|
@ -105,21 +105,21 @@ public class TabLayoutTootsFragment extends Fragment {
|
|||
displayStatusFragment = new DisplayStatusFragment();
|
||||
bundle = new Bundle();
|
||||
bundle.putSerializable("type", RetrieveFeedsAsyncTask.Type.USER);
|
||||
bundle.putString("targetedId", targetedId);
|
||||
bundle.putString("targetedid", targetedId);
|
||||
bundle.putBoolean("showReply",true);
|
||||
displayStatusFragment.setArguments(bundle);
|
||||
return displayStatusFragment;
|
||||
case 2:
|
||||
DisplayMediaFragment displayMediaFragment = new DisplayMediaFragment();
|
||||
bundle = new Bundle();
|
||||
bundle.putString("targetedId", targetedId);
|
||||
bundle.putString("targetedid", targetedId);
|
||||
displayMediaFragment.setArguments(bundle);
|
||||
return displayMediaFragment;
|
||||
case 3:
|
||||
displayStatusFragment = new DisplayStatusFragment();
|
||||
bundle = new Bundle();
|
||||
bundle.putSerializable("type", RetrieveFeedsAsyncTask.Type.USER);
|
||||
bundle.putString("targetedId", targetedId);
|
||||
bundle.putString("targetedid", targetedId);
|
||||
bundle.putBoolean("showPinned",true);
|
||||
displayStatusFragment.setArguments(bundle);
|
||||
return displayStatusFragment;
|
||||
|
|
|
@ -46,6 +46,7 @@ import fr.gouv.etalab.mastodon.client.Entities.Mention;
|
|||
import fr.gouv.etalab.mastodon.client.Entities.Results;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Status;
|
||||
import fr.gouv.etalab.mastodon.drawers.AccountsSearchAdapter;
|
||||
import fr.gouv.etalab.mastodon.drawers.PixelfedListAdapter;
|
||||
import fr.gouv.etalab.mastodon.drawers.StatusListAdapter;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnPostActionInterface;
|
||||
import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
|
||||
|
@ -87,7 +88,8 @@ public class CrossActions {
|
|||
for(Account account: accountstmp){
|
||||
String mentionAcct = (mention.getAcct().contains("@"))?mention.getAcct():mention.getAcct()+"@"+currentAccount.getInstance();
|
||||
if( (account.getAcct() + "@" + account.getInstance()).equals(mentionAcct) && !addedAccount.contains(account.getId() + "|" + account.getAcct())) {
|
||||
accounts.add(account);
|
||||
if( account.getSocial() == null || account.getSocial().equals("MASTODON"))
|
||||
accounts.add(account);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +97,8 @@ public class CrossActions {
|
|||
Account tootOwner = status.getAccount();
|
||||
String mentionAcct = (tootOwner.getAcct().contains("@"))?tootOwner.getAcct():tootOwner.getAcct()+"@"+currentAccount.getInstance();
|
||||
if( (account.getAcct() + "@" + account.getInstance()).equals(mentionAcct) && !addedAccount.contains(account.getId() + "|" + account.getAcct())) {
|
||||
accounts.add(account);
|
||||
if( account.getSocial() == null || account.getSocial().equals("MASTODON"))
|
||||
accounts.add(account);
|
||||
}
|
||||
}
|
||||
}else {
|
||||
|
@ -140,22 +143,74 @@ public class CrossActions {
|
|||
SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
Account currentAccount = new AccountDAO(context, db).getAccountByID(userId);
|
||||
if (confirmation)
|
||||
displayConfirmationDialogCrossAction(context, currentAccount, doAction, status, onPostActionInterface);
|
||||
else
|
||||
displayConfirmationDialogCrossAction(context, currentAccount, doAction, status, onPostActionInterface, baseAdapter);
|
||||
else {
|
||||
new PostActionAsyncTask(context, currentAccount, status, doAction, onPostActionInterface).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
if( doAction == API.StatusAction.FAVOURITE || doAction == API.StatusAction.UNFAVOURITE){
|
||||
if (doAction == API.StatusAction.FAVOURITE) {
|
||||
status.setFavourited(true);
|
||||
status.setFavAnimated(true);
|
||||
}else{
|
||||
status.setFavourited(false);
|
||||
status.setFavAnimated(false);
|
||||
}
|
||||
if(baseAdapter instanceof PixelfedListAdapter)
|
||||
((PixelfedListAdapter) baseAdapter).notifyStatusChanged(status);
|
||||
else if(baseAdapter instanceof StatusListAdapter)
|
||||
((StatusListAdapter) baseAdapter).notifyStatusChanged(status);
|
||||
}else if(doAction == API.StatusAction.REBLOG || doAction == API.StatusAction.UNREBLOG){
|
||||
if (doAction == API.StatusAction.REBLOG) {
|
||||
status.setReblogged(true);
|
||||
status.setBoostAnimated(true);
|
||||
}else{
|
||||
status.setReblogged(false);
|
||||
status.setBoostAnimated(false);
|
||||
}
|
||||
if(baseAdapter instanceof PixelfedListAdapter)
|
||||
((PixelfedListAdapter) baseAdapter).notifyStatusChanged(status);
|
||||
else if(baseAdapter instanceof StatusListAdapter)
|
||||
((StatusListAdapter) baseAdapter).notifyStatusChanged(status);
|
||||
}
|
||||
}
|
||||
} else if (accounts.size() == 1 || undoAction) {
|
||||
|
||||
if (confirmation)
|
||||
displayConfirmationDialog(context, doAction, status, baseAdapter, onPostActionInterface);
|
||||
else {
|
||||
if (doAction == API.StatusAction.REBLOG || doAction == API.StatusAction.UNREBLOG)
|
||||
reblogAction(context, status, baseAdapter, onPostActionInterface);
|
||||
reblogAction(context, status, onPostActionInterface);
|
||||
else if (doAction == API.StatusAction.FAVOURITE || doAction == API.StatusAction.UNFAVOURITE)
|
||||
favouriteAction(context, status, baseAdapter, onPostActionInterface);
|
||||
favouriteAction(context, status, onPostActionInterface);
|
||||
else if (doAction == API.StatusAction.PIN || doAction == API.StatusAction.UNPIN)
|
||||
pinAction(context, status, baseAdapter, onPostActionInterface);
|
||||
|
||||
if( doAction == API.StatusAction.FAVOURITE || doAction == API.StatusAction.UNFAVOURITE){
|
||||
if (doAction == API.StatusAction.FAVOURITE) {
|
||||
status.setFavourited(true);
|
||||
status.setFavAnimated(true);
|
||||
}else{
|
||||
status.setFavourited(false);
|
||||
status.setFavAnimated(false);
|
||||
}
|
||||
if(baseAdapter instanceof PixelfedListAdapter)
|
||||
((PixelfedListAdapter) baseAdapter).notifyStatusChanged(status);
|
||||
else if(baseAdapter instanceof StatusListAdapter)
|
||||
((StatusListAdapter) baseAdapter).notifyStatusChanged(status);
|
||||
}else if(doAction == API.StatusAction.REBLOG || doAction == API.StatusAction.UNREBLOG){
|
||||
if (doAction == API.StatusAction.REBLOG) {
|
||||
status.setReblogged(true);
|
||||
status.setBoostAnimated(true);
|
||||
}else{
|
||||
status.setReblogged(false);
|
||||
status.setBoostAnimated(false);
|
||||
}
|
||||
if(baseAdapter instanceof PixelfedListAdapter)
|
||||
((PixelfedListAdapter) baseAdapter).notifyStatusChanged(status);
|
||||
else if(baseAdapter instanceof StatusListAdapter)
|
||||
((StatusListAdapter) baseAdapter).notifyStatusChanged(status);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
AlertDialog.Builder builderSingle = new AlertDialog.Builder(context, style);
|
||||
builderSingle.setTitle(context.getString(R.string.choose_accounts));
|
||||
final AccountsSearchAdapter accountsSearchAdapter = new AccountsSearchAdapter(context, accounts, true);
|
||||
|
@ -196,7 +251,8 @@ public class CrossActions {
|
|||
} else if (doAction == API.StatusAction.PIN) {
|
||||
status.setPinned(true);
|
||||
}
|
||||
baseAdapter.notifyDataSetChanged();
|
||||
if( baseAdapter != null)
|
||||
baseAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}else{
|
||||
new PostActionAsyncTask(context, selectedAccount, targetedAccount, doAction, onPostActionInterface).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
|
@ -204,7 +260,8 @@ public class CrossActions {
|
|||
if (doAction == API.StatusAction.FOLLOW) {
|
||||
targetedAccount.setFollowing(true);
|
||||
}
|
||||
baseAdapter.notifyDataSetChanged();
|
||||
if( baseAdapter != null)
|
||||
baseAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
dialog.dismiss();
|
||||
|
@ -264,11 +321,13 @@ public class CrossActions {
|
|||
@Override
|
||||
protected Void doInBackground(Void... voids) {
|
||||
API api = new API(contextReference.get(), account.getInstance(), account.getToken());
|
||||
String url;
|
||||
if( remoteAccount.getHost() != null && remoteAccount.getAcct().split("@").length > 1) //Peertube compatibility
|
||||
url = "https://" + remoteAccount.getHost() + "/accounts/" + remoteAccount.getAcct().split("@")[0];
|
||||
else
|
||||
url = "https://" + remoteAccount.getInstance() + "/@" + remoteAccount.getAcct();
|
||||
String url = remoteAccount.getUrl();
|
||||
if( url == null) {
|
||||
if (remoteAccount.getHost() != null && remoteAccount.getAcct().split("@").length > 1) //Peertube compatibility
|
||||
url = "https://" + remoteAccount.getHost() + "/accounts/" + remoteAccount.getAcct().split("@")[0];
|
||||
else
|
||||
url = "https://" + remoteAccount.getInstance() + "/@" + remoteAccount.getAcct();
|
||||
}
|
||||
response = api.search(url);
|
||||
return null;
|
||||
}
|
||||
|
@ -283,8 +342,8 @@ public class CrossActions {
|
|||
Bundle b = new Bundle();
|
||||
//Flag it has a peertube account
|
||||
if( remoteAccount.getHost() != null && remoteAccount.getAcct().split("@").length > 1)
|
||||
b.putBoolean("peertubeAccount", true);
|
||||
b.putString("accountId", remoteAccounts.get(0).getId());
|
||||
b.putBoolean("peertubeaccount", true);
|
||||
b.putParcelable("account", remoteAccounts.get(0));
|
||||
intent.putExtras(b);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
@ -696,11 +755,37 @@ public class CrossActions {
|
|||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if( action == API.StatusAction.REBLOG || action == API.StatusAction.UNREBLOG)
|
||||
reblogAction(context, status, baseAdapter, onPostActionInterface);
|
||||
reblogAction(context, status, onPostActionInterface);
|
||||
else if( action == API.StatusAction.FAVOURITE || action == API.StatusAction.UNFAVOURITE)
|
||||
favouriteAction(context, status, baseAdapter, onPostActionInterface);
|
||||
favouriteAction(context, status, onPostActionInterface);
|
||||
else if ( action == API.StatusAction.PIN || action == API.StatusAction.UNPIN)
|
||||
pinAction(context, status, baseAdapter, onPostActionInterface);
|
||||
|
||||
if( action == API.StatusAction.FAVOURITE || action == API.StatusAction.UNFAVOURITE){
|
||||
if (action == API.StatusAction.FAVOURITE) {
|
||||
status.setFavourited(true);
|
||||
status.setFavAnimated(true);
|
||||
}else{
|
||||
status.setFavourited(false);
|
||||
status.setFavAnimated(false);
|
||||
}
|
||||
if(baseAdapter instanceof PixelfedListAdapter)
|
||||
((PixelfedListAdapter) baseAdapter).notifyStatusChanged(status);
|
||||
else if(baseAdapter instanceof StatusListAdapter)
|
||||
((StatusListAdapter) baseAdapter).notifyStatusChanged(status);
|
||||
}else if(action == API.StatusAction.REBLOG || action == API.StatusAction.UNREBLOG){
|
||||
if (action == API.StatusAction.REBLOG) {
|
||||
status.setReblogged(true);
|
||||
status.setBoostAnimated(true);
|
||||
}else{
|
||||
status.setReblogged(false);
|
||||
status.setBoostAnimated(false);
|
||||
}
|
||||
if(baseAdapter instanceof PixelfedListAdapter)
|
||||
((PixelfedListAdapter) baseAdapter).notifyStatusChanged(status);
|
||||
else if(baseAdapter instanceof StatusListAdapter)
|
||||
((StatusListAdapter) baseAdapter).notifyStatusChanged(status);
|
||||
}
|
||||
dialog.dismiss();
|
||||
}
|
||||
})
|
||||
|
@ -721,7 +806,7 @@ public class CrossActions {
|
|||
* @param action int
|
||||
* @param status Status
|
||||
*/
|
||||
private static void displayConfirmationDialogCrossAction(final Context context,Account currentAccount, final API.StatusAction action, final Status status, final OnPostActionInterface onPostActionInterface){
|
||||
private static void displayConfirmationDialogCrossAction(final Context context,Account currentAccount, final API.StatusAction action, final Status status, final OnPostActionInterface onPostActionInterface, final RecyclerView.Adapter baseAdapter){
|
||||
|
||||
String title = null;
|
||||
if( action == API.StatusAction.FAVOURITE){
|
||||
|
@ -750,6 +835,31 @@ public class CrossActions {
|
|||
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if( action == API.StatusAction.FAVOURITE || action == API.StatusAction.UNFAVOURITE){
|
||||
if (action == API.StatusAction.FAVOURITE) {
|
||||
status.setFavourited(true);
|
||||
status.setFavAnimated(true);
|
||||
}else{
|
||||
status.setFavourited(false);
|
||||
status.setFavAnimated(false);
|
||||
}
|
||||
if(baseAdapter instanceof PixelfedListAdapter)
|
||||
((PixelfedListAdapter) baseAdapter).notifyStatusChanged(status);
|
||||
else if(baseAdapter instanceof StatusListAdapter)
|
||||
((StatusListAdapter) baseAdapter).notifyStatusChanged(status);
|
||||
}else if(action == API.StatusAction.REBLOG || action == API.StatusAction.UNREBLOG){
|
||||
if (action == API.StatusAction.REBLOG) {
|
||||
status.setReblogged(true);
|
||||
status.setBoostAnimated(true);
|
||||
}else{
|
||||
status.setReblogged(false);
|
||||
status.setBoostAnimated(false);
|
||||
}
|
||||
if(baseAdapter instanceof PixelfedListAdapter)
|
||||
((PixelfedListAdapter) baseAdapter).notifyStatusChanged(status);
|
||||
else if(baseAdapter instanceof StatusListAdapter)
|
||||
((StatusListAdapter) baseAdapter).notifyStatusChanged(status);
|
||||
}
|
||||
new PostActionAsyncTask(context, currentAccount, status, action, onPostActionInterface).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
dialog.dismiss();
|
||||
}
|
||||
|
@ -783,7 +893,8 @@ public class CrossActions {
|
|||
* Favourites/Unfavourites a status
|
||||
* @param status Status
|
||||
*/
|
||||
private static void favouriteAction(Context context, Status status, RecyclerView.Adapter baseAdapter, OnPostActionInterface onPostActionInterface){
|
||||
private static void favouriteAction(Context context, Status status,OnPostActionInterface onPostActionInterface){
|
||||
|
||||
if( status.isFavourited() || (status.getReblog() != null && status.getReblog().isFavourited())){
|
||||
new PostActionAsyncTask(context, API.StatusAction.UNFAVOURITE, status.getId(), onPostActionInterface).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
status.setFavourited(false);
|
||||
|
@ -791,14 +902,13 @@ public class CrossActions {
|
|||
new PostActionAsyncTask(context, API.StatusAction.FAVOURITE, status.getId(), onPostActionInterface).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
status.setFavourited(true);
|
||||
}
|
||||
baseAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reblog/Unreblog a status
|
||||
* @param status Status
|
||||
*/
|
||||
private static void reblogAction(Context context, Status status, RecyclerView.Adapter baseAdapter, OnPostActionInterface onPostActionInterface){
|
||||
private static void reblogAction(Context context, Status status, OnPostActionInterface onPostActionInterface){
|
||||
if( status.isReblogged() || (status.getReblog()!= null && status.getReblog().isReblogged())){
|
||||
String statusId = status.getReblog()!=null?status.getReblog().getId():status.getId();
|
||||
new PostActionAsyncTask(context, API.StatusAction.UNREBLOG, statusId, onPostActionInterface).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
|
@ -807,7 +917,6 @@ public class CrossActions {
|
|||
new PostActionAsyncTask(context, API.StatusAction.REBLOG, status.getId(), onPostActionInterface).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
status.setReblogged(true);
|
||||
}
|
||||
baseAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
package fr.gouv.etalab.mastodon.helper;
|
||||
|
||||
import android.support.annotation.DimenRes;
|
||||
import android.support.annotation.Px;
|
||||
|
||||
import com.vanniktech.emoji.emoji.Emoji;
|
||||
|
||||
public interface EmojiEditTextInterface {
|
||||
void backspace();
|
||||
|
||||
void input(Emoji emoji);
|
||||
|
||||
float getEmojiSize();
|
||||
|
||||
/** sets the emoji size in pixels and automatically invalidates the text and renders it with the new size */
|
||||
void setEmojiSize(@Px int pixels);
|
||||
|
||||
/** sets the emoji size in pixels and automatically invalidates the text and renders it with the new size when {@code shouldInvalidate} is true */
|
||||
void setEmojiSize(@Px int pixels, boolean shouldInvalidate);
|
||||
|
||||
/** sets the emoji size in pixels with the provided resource and automatically invalidates the text and renders it with the new size */
|
||||
void setEmojiSizeRes(@DimenRes int res);
|
||||
|
||||
/** sets the emoji size in pixels with the provided resource and invalidates the text and renders it with the new size when {@code shouldInvalidate} is true */
|
||||
void setEmojiSizeRes(@DimenRes int res, boolean shouldInvalidate);
|
||||
}
|
|
@ -122,7 +122,7 @@ public class FullScreenMediaController extends MediaController {
|
|||
resolution.setText(String.format("%sp",resolutionVal));
|
||||
}
|
||||
|
||||
private void changeIcon(){
|
||||
public void changeIcon(){
|
||||
//fullscreen indicator from intent
|
||||
if(((PeertubeActivity)getContext()).getFullscreen() == fullscreen.ON){
|
||||
Resources resources = getResources();
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -11,7 +11,6 @@ import android.support.annotation.Px;
|
|||
import android.util.AttributeSet;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import com.vanniktech.emoji.EmojiEditTextInterface;
|
||||
import com.vanniktech.emoji.EmojiManager;
|
||||
import com.vanniktech.emoji.emoji.Emoji;
|
||||
|
||||
|
|
|
@ -14,11 +14,10 @@
|
|||
* see <http://www.gnu.org/licenses>. */
|
||||
package fr.gouv.etalab.mastodon.interfaces;
|
||||
|
||||
import android.text.SpannableString;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Emojis;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Notification;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Status;
|
||||
|
||||
|
||||
|
@ -28,5 +27,6 @@ import fr.gouv.etalab.mastodon.client.Entities.Status;
|
|||
*/
|
||||
public interface OnRetrieveEmojiInterface {
|
||||
void onRetrieveEmoji(Status status, boolean fromTranslation);
|
||||
void onRetrieveEmoji(Notification notification);
|
||||
void onRetrieveSearchEmoji(List<Emojis> emojis);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
/* Copyright 2018 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Mastalab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Mastalab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
package fr.gouv.etalab.mastodon.interfaces;
|
||||
|
||||
import fr.gouv.etalab.mastodon.client.APIResponse;
|
||||
|
||||
/**
|
||||
* Created by Thomas on 22/12/2018.
|
||||
* Interface when status younger than the bookmark have been retrieved
|
||||
*/
|
||||
public interface OnRetrieveFeedsAfterBookmarkInterface {
|
||||
void onRetrieveFeedsAfterBookmark(APIResponse apiResponse);
|
||||
}
|
|
@ -23,4 +23,5 @@ import fr.gouv.etalab.mastodon.client.APIResponse;
|
|||
public interface OnRetrievePeertubeInterface {
|
||||
void onRetrievePeertube(APIResponse apiResponse);
|
||||
void onRetrievePeertubeComments(APIResponse apiResponse);
|
||||
void onRetrievePeertubeChannels(APIResponse apiResponse);
|
||||
}
|
||||
|
|
|
@ -30,8 +30,6 @@ public class ApplicationJob implements JobCreator {
|
|||
switch (tag) {
|
||||
case NotificationsSyncJob.NOTIFICATION_REFRESH:
|
||||
return new NotificationsSyncJob();
|
||||
case HomeTimelineSyncJob.HOME_TIMELINE:
|
||||
return new HomeTimelineSyncJob();
|
||||
case ScheduledTootsSyncJob.SCHEDULED_TOOT:
|
||||
return new ScheduledTootsSyncJob();
|
||||
case ScheduledBoostsSyncJob.SCHEDULED_BOOST:
|
||||
|
|
|
@ -1,221 +0,0 @@
|
|||
package fr.gouv.etalab.mastodon.jobs;
|
||||
/* Copyright 2017 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Mastalab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Mastalab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.DataSource;
|
||||
import com.bumptech.glide.load.engine.GlideException;
|
||||
import com.bumptech.glide.request.RequestListener;
|
||||
import com.bumptech.glide.request.target.SimpleTarget;
|
||||
import com.bumptech.glide.request.target.Target;
|
||||
import com.bumptech.glide.request.transition.Transition;
|
||||
import com.evernote.android.job.Job;
|
||||
import com.evernote.android.job.JobManager;
|
||||
import com.evernote.android.job.JobRequest;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import fr.gouv.etalab.mastodon.R;
|
||||
import fr.gouv.etalab.mastodon.activities.MainActivity;
|
||||
import fr.gouv.etalab.mastodon.client.API;
|
||||
import fr.gouv.etalab.mastodon.client.APIResponse;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Status;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
|
||||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||
|
||||
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.HOME_TIMELINE_INTENT;
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.INTENT_ACTION;
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.PREF_INSTANCE;
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.PREF_KEY_ID;
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.canNotify;
|
||||
import static fr.gouv.etalab.mastodon.helper.Helper.notify_user;
|
||||
|
||||
|
||||
/**
|
||||
* Created by Thomas on 20/05/2017.
|
||||
* Notifications for home timeline job
|
||||
*/
|
||||
|
||||
public class HomeTimelineSyncJob extends Job {
|
||||
|
||||
static final String HOME_TIMELINE = "home_timeline";
|
||||
static {
|
||||
Helper.installProvider();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected Result onRunJob(@NonNull Params params) {
|
||||
callAsynchronousTask();
|
||||
return Result.SUCCESS;
|
||||
}
|
||||
public static int schedule(boolean updateCurrent){
|
||||
|
||||
Set<JobRequest> jobRequests = JobManager.instance().getAllJobRequestsForTag(HOME_TIMELINE);
|
||||
if (!jobRequests.isEmpty() && !updateCurrent) {
|
||||
return jobRequests.iterator().next().getJobId();
|
||||
}
|
||||
|
||||
return new JobRequest.Builder(HomeTimelineSyncJob.HOME_TIMELINE)
|
||||
.setPeriodic(TimeUnit.MINUTES.toMillis(Helper.MINUTES_BETWEEN_HOME_TIMELINE), TimeUnit.MINUTES.toMillis(5))
|
||||
.setUpdateCurrent(updateCurrent)
|
||||
.setRequiredNetworkType(JobRequest.NetworkType.METERED)
|
||||
.setRequiresBatteryNotLow(true)
|
||||
.setRequirementsEnforced(false)
|
||||
.build()
|
||||
.schedule();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Task in background starts here.
|
||||
*/
|
||||
private void callAsynchronousTask() {
|
||||
|
||||
if( !canNotify(getContext()))
|
||||
return;
|
||||
final SharedPreferences sharedpreferences = getContext().getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
boolean notif_hometimeline = sharedpreferences.getBoolean(Helper.SET_NOTIF_HOMETIMELINE, false);
|
||||
//User disagree with home timeline refresh
|
||||
if( !notif_hometimeline)
|
||||
return; //Nothing is done
|
||||
//No account connected, the service is stopped
|
||||
if(!Helper.isLoggedIn(getContext()))
|
||||
return;
|
||||
SQLiteDatabase db = Sqlite.getInstance(getContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
//If an Internet connection and user agrees with notification refresh
|
||||
//If WIFI only and on WIFI OR user defined any connections to use the service.
|
||||
if(!sharedpreferences.getBoolean(Helper.SET_WIFI_ONLY, false) || Helper.isOnWIFI(getContext())) {
|
||||
List<Account> accounts = new AccountDAO(getContext(),db).getAllAccount();
|
||||
//It means there is no user in DB.
|
||||
if( accounts == null )
|
||||
return;
|
||||
//Retrieve users in db that owner has.
|
||||
for (Account account: accounts) {
|
||||
String max_id = sharedpreferences.getString(Helper.LAST_HOMETIMELINE_NOTIFICATION_MAX_ID + account.getId() + account.getInstance(), null);
|
||||
String lastHomeSeen = sharedpreferences.getString(Helper.LAST_HOMETIMELINE_MAX_ID + account.getId() + account.getInstance(), null);
|
||||
if( lastHomeSeen != null && max_id != null){
|
||||
if( Long.parseLong(lastHomeSeen) > Long.parseLong(max_id)){
|
||||
max_id = lastHomeSeen;
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.LAST_HOMETIMELINE_NOTIFICATION_MAX_ID + account.getId() + account.getInstance(), max_id);
|
||||
editor.apply();
|
||||
}
|
||||
}
|
||||
API api = new API(getContext(), account.getInstance(), account.getToken());
|
||||
APIResponse apiResponse = api.getHomeTimelineSinceId(max_id);
|
||||
onRetrieveHomeTimelineService(apiResponse, account);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onRetrieveHomeTimelineService(APIResponse apiResponse, final Account account) {
|
||||
final List<Status> statuses = apiResponse.getStatuses();
|
||||
if( apiResponse.getError() != null || statuses == null || statuses.size() == 0 || account == null)
|
||||
return;
|
||||
|
||||
final SharedPreferences sharedpreferences = getContext().getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
|
||||
final String max_id = sharedpreferences.getString(Helper.LAST_HOMETIMELINE_NOTIFICATION_MAX_ID + account.getId() + account.getInstance(), null);
|
||||
//No previous notifications in cache, so no notification will be sent
|
||||
String message;
|
||||
|
||||
for(Status status: statuses){
|
||||
//The notification associated to max_id is discarded as it is supposed to have already been sent
|
||||
//Also, if the toot comes from the owner, we will avoid to warn him/her...
|
||||
if( max_id != null && (status.getId().equals(max_id)) || (account.getAcct() != null && status.getAccount().getAcct().trim().equals(account.getAcct().trim()) ))
|
||||
continue;
|
||||
final String notificationUrl = status.getAccount().getAvatar();
|
||||
|
||||
if(statuses.size() > 0 )
|
||||
message = getContext().getResources().getQuantityString(R.plurals.other_notif_hometimeline, statuses.size(), statuses.size());
|
||||
else
|
||||
message = "";
|
||||
final Intent intent = new Intent(getContext(), MainActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK );
|
||||
intent.putExtra(INTENT_ACTION, HOME_TIMELINE_INTENT);
|
||||
intent.putExtra(PREF_KEY_ID, account.getId());
|
||||
intent.putExtra(PREF_INSTANCE, account.getInstance());
|
||||
long notif_id = Long.parseLong(account.getId());
|
||||
final int notificationId = ((notif_id + 2) > 2147483647) ? (int) (2147483647 - notif_id - 2) : (int) (notif_id + 2);
|
||||
if( notificationUrl != null){
|
||||
|
||||
final String finalMessage = message;
|
||||
String title;
|
||||
if( status.getAccount().getDisplay_name() != null && status.getAccount().getDisplay_name().length() > 0 )
|
||||
title = getContext().getResources().getString(R.string.notif_pouet, Helper.shortnameToUnicode(status.getAccount().getDisplay_name(), true));
|
||||
else
|
||||
title = getContext().getResources().getString(R.string.notif_pouet, status.getAccount().getUsername());
|
||||
final String finalTitle = title;
|
||||
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
|
||||
Runnable myRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {Glide.with(getContext())
|
||||
.asBitmap()
|
||||
.load(notificationUrl)
|
||||
.listener(new RequestListener<Bitmap>(){
|
||||
|
||||
@Override
|
||||
public boolean onResourceReady(Bitmap resource, Object model, Target<Bitmap> target, DataSource dataSource, boolean isFirstResource) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
|
||||
notify_user(getContext(), intent, notificationId, BitmapFactory.decodeResource(getContext().getResources(),
|
||||
R.drawable.mastodonlogo), Helper.NotifType.TOOT, finalTitle, finalMessage);
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.LAST_HOMETIMELINE_NOTIFICATION_MAX_ID + account.getId() + account.getInstance(), statuses.get(0).getId());
|
||||
editor.apply();
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.into(new SimpleTarget<Bitmap>() {
|
||||
@Override
|
||||
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
|
||||
notify_user(getContext(), intent, notificationId, resource, Helper.NotifType.TOOT, finalTitle, finalMessage);
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.LAST_HOMETIMELINE_NOTIFICATION_MAX_ID + account.getId() + account.getInstance(), statuses.get(0).getId());
|
||||
editor.apply();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
mainHandler.post(myRunnable);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -40,13 +40,14 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import fr.gouv.etalab.mastodon.R;
|
||||
import fr.gouv.etalab.mastodon.activities.MainActivity;
|
||||
import fr.gouv.etalab.mastodon.client.API;
|
||||
import fr.gouv.etalab.mastodon.client.APIResponse;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.R;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Notification;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
|
||||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||
|
||||
|
@ -130,9 +131,11 @@ public class NotificationsSyncJob extends Job {
|
|||
return;
|
||||
//Retrieve users in db that owner has.
|
||||
for (Account account: accounts) {
|
||||
API api = new API(getContext(), account.getInstance(), account.getToken());
|
||||
APIResponse apiResponse = api.getNotificationsSince(null, false);
|
||||
onRetrieveNotifications(apiResponse, account);
|
||||
if( account.getSocial() == null || account.getSocial().equals("MASTODON")) {
|
||||
API api = new API(getContext(), account.getInstance(), account.getToken());
|
||||
APIResponse apiResponse = api.getNotificationsSince(null, false);
|
||||
onRetrieveNotifications(apiResponse, account);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,7 +58,11 @@ import org.json.JSONObject;
|
|||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import fr.gouv.etalab.mastodon.R;
|
||||
import fr.gouv.etalab.mastodon.activities.MainActivity;
|
||||
|
@ -90,7 +94,8 @@ public class LiveNotificationService extends Service implements NetworkStateRece
|
|||
|
||||
protected Account account;
|
||||
boolean backgroundProcess;
|
||||
private static Thread thread;
|
||||
private static HashMap<String, Thread> threads = new HashMap<>();
|
||||
private static HashMap<String, Boolean> canStartStream = new HashMap<>();
|
||||
private NetworkStateReceiver networkStateReceiver;
|
||||
private static HashMap<String, WebSocket> webSocketFutures = new HashMap<>();
|
||||
|
||||
|
@ -99,39 +104,71 @@ public class LiveNotificationService extends Service implements NetworkStateRece
|
|||
networkStateReceiver = new NetworkStateReceiver();
|
||||
networkStateReceiver.addListener(this);
|
||||
registerReceiver(networkStateReceiver, new IntentFilter(android.net.ConnectivityManager.CONNECTIVITY_ACTION));
|
||||
startStream();
|
||||
startStream(null);
|
||||
}
|
||||
|
||||
private void startStream(){
|
||||
private void startStream(Account account){
|
||||
|
||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
backgroundProcess = sharedpreferences.getBoolean(Helper.SET_KEEP_BACKGROUND_PROCESS, true);
|
||||
boolean liveNotifications = sharedpreferences.getBoolean(Helper.SET_LIVE_NOTIFICATIONS, true);
|
||||
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
if( liveNotifications ){
|
||||
if( thread == null || !thread.isAlive()){
|
||||
if(thread != null)
|
||||
thread.interrupt();
|
||||
thread = new Thread() {
|
||||
if( account == null){
|
||||
|
||||
Iterator it = threads.entrySet().iterator();
|
||||
Thread thread;
|
||||
while (it.hasNext()) {
|
||||
Map.Entry pair = (Map.Entry)it.next();
|
||||
if( pair.getValue() == null || !((Thread)pair.getValue()).isAlive()) {
|
||||
if ((pair.getValue()) != null)
|
||||
((Thread) pair.getValue()).interrupt();
|
||||
}
|
||||
it.remove();
|
||||
}
|
||||
List<Account> accountStreams = new AccountDAO(getApplicationContext(), db).getAllAccount();
|
||||
if (accountStreams != null) {
|
||||
for (final Account accountStream : accountStreams) {
|
||||
if( accountStream.getSocial() == null || accountStream.getSocial().equals("MASTODON")) {
|
||||
thread = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
taks(accountStream);
|
||||
}
|
||||
};
|
||||
thread.start();
|
||||
threads.put(accountStream.getAcct() + "@" + accountStream.getInstance(), thread);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}else {
|
||||
String key = account.getAcct() + "@" + account.getInstance();
|
||||
if(webSocketFutures.containsKey(key)){
|
||||
if (webSocketFutures.get(key) != null && webSocketFutures.get(key).isOpen()) {
|
||||
try {
|
||||
webSocketFutures.get(key).close();
|
||||
}catch (Exception ignored){}
|
||||
}
|
||||
}
|
||||
if(threads.containsKey(key)){
|
||||
if (threads.get(key) != null && !threads.get(key).isAlive()) {
|
||||
threads.get(key).interrupt();
|
||||
}
|
||||
}
|
||||
Thread thread = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
List<Account> accountStreams = new AccountDAO(getApplicationContext(), db).getAllAccount();
|
||||
if (accountStreams != null) {
|
||||
for (final Account accountStream : accountStreams) {
|
||||
taks(accountStream);
|
||||
}
|
||||
}
|
||||
taks(account);
|
||||
}
|
||||
};
|
||||
thread.start();
|
||||
}
|
||||
threads.put(account.getAcct()+"@"+account.getInstance(), thread);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
Helper.installProvider();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
if( intent == null || intent.getBooleanExtra("stop", false) ) {
|
||||
|
@ -183,16 +220,14 @@ public class LiveNotificationService extends Service implements NetworkStateRece
|
|||
headers.add("Connection", "Keep-Alive");
|
||||
headers.add("method", "GET");
|
||||
headers.add("scheme", "https");
|
||||
String urlKey = "wss://" + account.getInstance() + "/api/v1/streaming/?stream=user&access_token=" + account.getToken();
|
||||
String urlKey = "wss://" + account.getInstance() + "/api/v1/streaming/?stream=user:notification&access_token=" + account.getToken();
|
||||
Uri url = Uri.parse(urlKey);
|
||||
AsyncHttpRequest.setDefaultHeaders(headers, url);
|
||||
if( webSocketFutures.containsKey(urlKey) ){
|
||||
try {
|
||||
if( webSocketFutures.get(urlKey) != null && webSocketFutures.get(urlKey).isOpen())
|
||||
webSocketFutures.get(urlKey).close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
if( Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT ) {
|
||||
try {
|
||||
|
@ -204,12 +239,21 @@ public class LiveNotificationService extends Service implements NetworkStateRece
|
|||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
AsyncHttpClient.getDefaultInstance().websocket("wss://" + account.getInstance() + "/api/v1/streaming/?stream=user&access_token=" + account.getToken(), "wss", new AsyncHttpClient.WebSocketConnectCallback() {
|
||||
AsyncHttpClient.getDefaultInstance().websocket("wss://" + account.getInstance() + "/api/v1/streaming/?stream=user:notification&access_token=" + account.getToken(), "wss", new AsyncHttpClient.WebSocketConnectCallback() {
|
||||
@Override
|
||||
public void onCompleted(Exception ex, WebSocket webSocket) {
|
||||
webSocketFutures.put(account.getAcct()+"@"+account.getInstance(), webSocket);
|
||||
if (ex != null) {
|
||||
ex.printStackTrace();
|
||||
if( !canStartStream.containsKey(account.getAcct()+"@"+account.getInstance()) || canStartStream.get(account.getAcct()+"@"+account.getInstance())) {
|
||||
canStartStream.put(account.getAcct()+"@"+account.getInstance(),false);
|
||||
new Timer().schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
startStream(account);
|
||||
canStartStream.put(account.getAcct()+"@"+account.getInstance(),true);
|
||||
}
|
||||
}, 15000);
|
||||
}
|
||||
return;
|
||||
}
|
||||
webSocket.setStringCallback(new WebSocket.StringCallback() {
|
||||
|
@ -225,8 +269,9 @@ public class LiveNotificationService extends Service implements NetworkStateRece
|
|||
@Override
|
||||
public void onCompleted(Exception ex) {
|
||||
try {
|
||||
if (ex != null)
|
||||
if (ex != null) {
|
||||
webSocket.close();
|
||||
}
|
||||
} finally {
|
||||
if( webSocketFutures != null && webSocketFutures.containsKey(urlKey))
|
||||
webSocketFutures.remove(urlKey);
|
||||
|
@ -255,12 +300,11 @@ public class LiveNotificationService extends Service implements NetworkStateRece
|
|||
private void onRetrieveStreaming(Account account, JSONObject response) {
|
||||
if( response == null )
|
||||
return;
|
||||
fr.gouv.etalab.mastodon.client.Entities.Status status ;
|
||||
final Notification notification;
|
||||
String dataId = null;
|
||||
String dataId;
|
||||
Bundle b = new Bundle();
|
||||
boolean canSendBroadCast = true;
|
||||
Helper.EventStreaming event = null;
|
||||
Helper.EventStreaming event;
|
||||
final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
try {
|
||||
|
@ -388,43 +432,42 @@ public class LiveNotificationService extends Service implements NetworkStateRece
|
|||
mainHandler.post(myRunnable);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "update":
|
||||
event = Helper.EventStreaming.UPDATE;
|
||||
status = API.parseStatuses(getApplicationContext(), new JSONObject(response.get("payload").toString()));
|
||||
status.setNew(true);
|
||||
b.putParcelable("data", status);
|
||||
if( canSendBroadCast) {
|
||||
if (account != null)
|
||||
b.putString("userIdService", account.getId());
|
||||
Intent intentBC = new Intent(Helper.RECEIVE_DATA);
|
||||
intentBC.putExtra("eventStreaming", event);
|
||||
intentBC.putExtras(b);
|
||||
b.putParcelable("data", notification);
|
||||
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intentBC);
|
||||
}
|
||||
break;
|
||||
case "delete":
|
||||
event = Helper.EventStreaming.DELETE;
|
||||
try {
|
||||
dataId = response.getString("id");
|
||||
b.putString("dataId", dataId);
|
||||
} catch (JSONException ignored) {
|
||||
}
|
||||
} catch (JSONException ignored) { }
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if( canSendBroadCast) {
|
||||
if (account != null)
|
||||
b.putString("userIdService", account.getId());
|
||||
Intent intentBC = new Intent(Helper.RECEIVE_DATA);
|
||||
intentBC.putExtra("eventStreaming", event);
|
||||
intentBC.putExtras(b);
|
||||
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intentBC);
|
||||
}
|
||||
} catch (Exception ignored) { }
|
||||
}
|
||||
|
||||
@Override
|
||||
public void networkAvailable() {
|
||||
startStream();
|
||||
startStream(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void networkUnavailable() {
|
||||
if( thread != null && thread.isAlive())
|
||||
thread.interrupt();
|
||||
Iterator it = threads.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Map.Entry pair = (Map.Entry) it.next();
|
||||
if (pair.getValue() == null || !((Thread) pair.getValue()).isAlive()) {
|
||||
if ((pair.getValue()) != null)
|
||||
((Thread) pair.getValue()).interrupt();
|
||||
}
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,167 @@
|
|||
package fr.gouv.etalab.mastodon.services;
|
||||
/* Copyright 2018 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Mastalab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Mastalab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import android.app.IntentService;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
|
||||
import com.koushikdutta.async.http.AsyncHttpClient;
|
||||
import com.koushikdutta.async.http.AsyncHttpRequest;
|
||||
import com.koushikdutta.async.http.Headers;
|
||||
import com.koushikdutta.async.http.WebSocket;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
|
||||
import fr.gouv.etalab.mastodon.client.API;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Status;
|
||||
import fr.gouv.etalab.mastodon.client.TLSSocketFactory;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
|
||||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||
|
||||
|
||||
/**
|
||||
* Created by Thomas on 18/12/2018.
|
||||
* Manage service for streaming api for home and notifications
|
||||
*/
|
||||
|
||||
public class StreamingHomeTimelineService extends IntentService {
|
||||
|
||||
static {
|
||||
Helper.installProvider();
|
||||
}
|
||||
/**
|
||||
* Creates an IntentService. Invoked by your subclass's constructor.
|
||||
*
|
||||
* @param name Used to name the worker thread, important only for debugging.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public StreamingHomeTimelineService(String name) {
|
||||
super(name);
|
||||
}
|
||||
@SuppressWarnings("unused")
|
||||
public StreamingHomeTimelineService() {
|
||||
super("StreamingHomeTimelineService");
|
||||
}
|
||||
|
||||
private static HttpsURLConnection httpsURLConnection;
|
||||
protected Account account;
|
||||
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
boolean display_global = sharedpreferences.getBoolean(Helper.SET_DISPLAY_GLOBAL, true);
|
||||
if( !display_global){
|
||||
stopSelf();
|
||||
}
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
String instance = sharedpreferences.getString(Helper.PREF_INSTANCE, Helper.getLiveInstance(getApplicationContext()));
|
||||
editor.putBoolean(Helper.SHOULD_CONTINUE_STREAMING_HOME + userId + instance, true);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onHandleIntent(@Nullable Intent intent) {
|
||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
Account accountStream = null;
|
||||
if( userId != null) {
|
||||
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
accountStream = new AccountDAO(getApplicationContext(), db).getAccountByID(userId);
|
||||
}
|
||||
if( accountStream != null) {
|
||||
Headers headers = new Headers();
|
||||
headers.add("Authorization", "Bearer " + accountStream.getToken());
|
||||
headers.add("Connection", "Keep-Alive");
|
||||
headers.add("method", "GET");
|
||||
headers.add("scheme", "https");
|
||||
Uri url = Uri.parse("wss://" + accountStream.getInstance() + "/api/v1/streaming/?stream=user&access_token="+ accountStream.getToken());
|
||||
AsyncHttpRequest.setDefaultHeaders(headers, url);
|
||||
Account finalAccountStream = accountStream;
|
||||
if( Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT ) {
|
||||
try {
|
||||
AsyncHttpClient.getDefaultInstance().getSSLSocketMiddleware().setSSLContext(new TLSSocketFactory().getSSLContext());
|
||||
AsyncHttpClient.getDefaultInstance().getSSLSocketMiddleware().setConnectAllAddresses(true);
|
||||
} catch (KeyManagementException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
AsyncHttpClient.getDefaultInstance().websocket("wss://" + accountStream.getInstance() + "/api/v1/streaming/?stream=user&access_token="+ accountStream.getToken(),"wss", new AsyncHttpClient.WebSocketConnectCallback() {
|
||||
@Override
|
||||
public void onCompleted(Exception ex, WebSocket webSocket) {
|
||||
if (ex != null) {
|
||||
ex.printStackTrace();
|
||||
return;
|
||||
}
|
||||
webSocket.setStringCallback(new WebSocket.StringCallback() {
|
||||
public void onStringAvailable(String s) {
|
||||
if (!sharedpreferences.getBoolean(Helper.SHOULD_CONTINUE_STREAMING_HOME + finalAccountStream.getId() + finalAccountStream.getInstance(), true)) {
|
||||
stopSelf();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
JSONObject eventJson = new JSONObject(s);
|
||||
|
||||
onRetrieveStreaming(finalAccountStream, eventJson);
|
||||
} catch (JSONException ignored) {}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void onRetrieveStreaming(Account account, JSONObject response) {
|
||||
if( response == null )
|
||||
return;
|
||||
Status status ;
|
||||
Bundle b = new Bundle();
|
||||
try {
|
||||
if( response.get("event").toString().equals("update")){
|
||||
status = API.parseStatuses(getApplicationContext(), new JSONObject(response.get("payload").toString()));
|
||||
status.setNew(true);
|
||||
b.putParcelable("data", status);
|
||||
if( account != null)
|
||||
b.putString("userIdService",account.getId());
|
||||
Intent intentBC = new Intent(Helper.RECEIVE_HOME_DATA);
|
||||
intentBC.putExtras(b);
|
||||
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intentBC);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -69,6 +69,12 @@ public class AccountDAO {
|
|||
values.put(Sqlite.COL_CREATED_AT, Helper.dateToString(account.getCreated_at()));
|
||||
values.put(Sqlite.COL_INSTANCE, account.getInstance());
|
||||
values.put(Sqlite.COL_EMOJIS, Helper.emojisToStringStorage(account.getEmojis()));
|
||||
values.put(Sqlite.COL_SOCIAL, account.getSocial());
|
||||
if( account.getClient_id() != null && account.getClient_secret() != null && account.getRefresh_token() != null) {
|
||||
values.put(Sqlite.COL_CLIENT_ID, account.getClient_id());
|
||||
values.put(Sqlite.COL_CLIENT_SECRET, account.getClient_secret());
|
||||
values.put(Sqlite.COL_REFRESH_TOKEN, account.getRefresh_token());
|
||||
}
|
||||
if( account.getToken() != null)
|
||||
values.put(Sqlite.COL_OAUTHTOKEN, account.getToken());
|
||||
|
||||
|
@ -77,6 +83,7 @@ public class AccountDAO {
|
|||
db.insert(Sqlite.TABLE_USER_ACCOUNT, null, values);
|
||||
|
||||
}catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -106,6 +113,11 @@ public class AccountDAO {
|
|||
values.put(Sqlite.COL_CREATED_AT, Helper.dateToString(account.getCreated_at()));
|
||||
values.put(Sqlite.COL_INSTANCE, account.getInstance());
|
||||
values.put(Sqlite.COL_EMOJIS, Helper.emojisToStringStorage(account.getEmojis()));
|
||||
if( account.getClient_id() != null && account.getClient_secret() != null && account.getRefresh_token() != null) {
|
||||
values.put(Sqlite.COL_CLIENT_ID, account.getClient_id());
|
||||
values.put(Sqlite.COL_CLIENT_SECRET, account.getClient_secret());
|
||||
values.put(Sqlite.COL_REFRESH_TOKEN, account.getRefresh_token());
|
||||
}
|
||||
if( account.getToken() != null)
|
||||
values.put(Sqlite.COL_OAUTHTOKEN, account.getToken());
|
||||
|
||||
|
@ -243,7 +255,10 @@ public class AccountDAO {
|
|||
account.setInstance(c.getString(c.getColumnIndex(Sqlite.COL_INSTANCE)));
|
||||
account.setEmojis(Helper.restoreEmojisFromString(c.getString(c.getColumnIndex(Sqlite.COL_EMOJIS))));
|
||||
account.setToken(c.getString(c.getColumnIndex(Sqlite.COL_OAUTHTOKEN)));
|
||||
|
||||
account.setSocial(c.getString(c.getColumnIndex(Sqlite.COL_SOCIAL))!=null?c.getString(c.getColumnIndex(Sqlite.COL_SOCIAL)):"MASTODON");
|
||||
account.setClient_id(c.getString(c.getColumnIndex(Sqlite.COL_CLIENT_ID)));
|
||||
account.setClient_secret(c.getString(c.getColumnIndex(Sqlite.COL_CLIENT_SECRET)));
|
||||
account.setRefresh_token(c.getString(c.getColumnIndex(Sqlite.COL_REFRESH_TOKEN)));
|
||||
//Close the cursor
|
||||
c.close();
|
||||
|
||||
|
@ -282,6 +297,10 @@ public class AccountDAO {
|
|||
account.setCreated_at(Helper.stringToDate(context, c.getString(c.getColumnIndex(Sqlite.COL_CREATED_AT))));
|
||||
account.setInstance(c.getString(c.getColumnIndex(Sqlite.COL_INSTANCE)));
|
||||
account.setToken(c.getString(c.getColumnIndex(Sqlite.COL_OAUTHTOKEN)));
|
||||
account.setSocial(c.getString(c.getColumnIndex(Sqlite.COL_SOCIAL))!=null?c.getString(c.getColumnIndex(Sqlite.COL_SOCIAL)):"MASTODON");
|
||||
account.setClient_id(c.getString(c.getColumnIndex(Sqlite.COL_CLIENT_ID)));
|
||||
account.setClient_secret(c.getString(c.getColumnIndex(Sqlite.COL_CLIENT_SECRET)));
|
||||
account.setRefresh_token(c.getString(c.getColumnIndex(Sqlite.COL_REFRESH_TOKEN)));
|
||||
accounts.add(account);
|
||||
}
|
||||
//Close the cursor
|
||||
|
|
|
@ -56,13 +56,16 @@ public class SearchDAO {
|
|||
*/
|
||||
public void insertSearch(String keyword) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(Sqlite.COL_KEYWORDS, keyword);
|
||||
values.put(Sqlite.COL_USER_ID, userId);
|
||||
values.put(Sqlite.COL_DATE_CREATION, Helper.dateToString(new Date()));
|
||||
//Inserts search
|
||||
try{
|
||||
db.insert(Sqlite.TABLE_SEARCH, null, values);
|
||||
}catch (Exception ignored) {}
|
||||
if( keyword != null && keyword.trim().length() > 0) {
|
||||
values.put(Sqlite.COL_KEYWORDS, keyword.trim());
|
||||
values.put(Sqlite.COL_USER_ID, userId);
|
||||
values.put(Sqlite.COL_DATE_CREATION, Helper.dateToString(new Date()));
|
||||
//Inserts search
|
||||
try {
|
||||
db.insert(Sqlite.TABLE_SEARCH, null, values);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -72,11 +75,18 @@ public class SearchDAO {
|
|||
* update tag timeline info in database
|
||||
* @param tagTimeline TagTimeline
|
||||
*/
|
||||
public void updateSearch(TagTimeline tagTimeline) {
|
||||
public void updateSearch(TagTimeline tagTimeline, String name, List<String> any, List<String> all, List<String> none) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(Sqlite.COL_IS_ART, tagTimeline.isART()?1:0);
|
||||
values.put(Sqlite.COL_IS_NSFW, tagTimeline.isNSFW()?1:0);
|
||||
//Inserts search
|
||||
if( any != null && any.size() > 0)
|
||||
values.put(Sqlite.COL_ANY, Helper.arrayToStringStorage(any));
|
||||
if( all != null && all.size() > 0)
|
||||
values.put(Sqlite.COL_ALL, Helper.arrayToStringStorage(all));
|
||||
if( none != null && none.size() > 0)
|
||||
values.put(Sqlite.COL_NONE, Helper.arrayToStringStorage(none));
|
||||
if( name != null && name.trim().length() > 0)
|
||||
values.put(Sqlite.COL_NAME, name.trim());
|
||||
try{
|
||||
db.update(Sqlite.TABLE_SEARCH, values, Sqlite.COL_USER_ID + " = ? AND " + Sqlite.COL_KEYWORDS + " = ?", new String[]{userId, tagTimeline.getName()});
|
||||
}catch (Exception ignored) {}
|
||||
|
@ -148,7 +158,10 @@ public class SearchDAO {
|
|||
return null;
|
||||
List<String> searches = new ArrayList<>();
|
||||
while (c.moveToNext() ) {
|
||||
searches.add(c.getString(c.getColumnIndex(Sqlite.COL_KEYWORDS)));
|
||||
if( c.getString(c.getColumnIndex(Sqlite.COL_NAME)) != null)
|
||||
searches.add(c.getString(c.getColumnIndex(Sqlite.COL_NAME)));
|
||||
else
|
||||
searches.add(c.getString(c.getColumnIndex(Sqlite.COL_KEYWORDS)));
|
||||
}
|
||||
//Close the cursor
|
||||
c.close();
|
||||
|
@ -170,6 +183,32 @@ public class SearchDAO {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TagTimeline information by its keyword in db
|
||||
* @return info List<TagTimeline>
|
||||
*/
|
||||
public List<TagTimeline> getTabInfo(String name){
|
||||
try {
|
||||
Cursor c = db.query(Sqlite.TABLE_SEARCH, null, Sqlite.COL_NAME + " = \"" + name + "\" AND " + Sqlite.COL_USER_ID + " = \"" + userId+ "\"", null, null, null, null, null);
|
||||
return cursorToTagTimelineSearch(c);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TagTimeline information by its keyword in db
|
||||
* @return info List<TagTimeline>
|
||||
*/
|
||||
public List<TagTimeline> getTabInfoKeyword(String name){
|
||||
try {
|
||||
Cursor c = db.query(Sqlite.TABLE_SEARCH, null, Sqlite.COL_KEYWORDS + " = \"" + name + "\" AND " + Sqlite.COL_USER_ID + " = \"" + userId+ "\"", null, null, null, null, null);
|
||||
return cursorToTagTimelineSearch(c);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* Method to hydrate stored search from database
|
||||
* @param c Cursor
|
||||
|
@ -182,7 +221,17 @@ public class SearchDAO {
|
|||
List<TagTimeline> searches = new ArrayList<>();
|
||||
while (c.moveToNext() ) {
|
||||
TagTimeline tagTimeline = new TagTimeline();
|
||||
try {
|
||||
tagTimeline.setAny(Helper.restoreArrayFromString(c.getString(c.getColumnIndex(Sqlite.COL_ANY))));
|
||||
}catch (Exception ignored){}
|
||||
try {
|
||||
tagTimeline.setAll(Helper.restoreArrayFromString(c.getString(c.getColumnIndex(Sqlite.COL_ALL))));
|
||||
}catch (Exception ignored){}
|
||||
try {
|
||||
tagTimeline.setNone(Helper.restoreArrayFromString(c.getString(c.getColumnIndex(Sqlite.COL_NONE))));
|
||||
}catch (Exception ignored){}
|
||||
tagTimeline.setName(c.getString(c.getColumnIndex(Sqlite.COL_KEYWORDS)));
|
||||
tagTimeline.setDisplayname(c.getString(c.getColumnIndex(Sqlite.COL_NAME)));
|
||||
tagTimeline.setART(c.getInt(c.getColumnIndex(Sqlite.COL_IS_ART))==1);
|
||||
tagTimeline.setNSFW(c.getInt(c.getColumnIndex(Sqlite.COL_IS_NSFW))==1);
|
||||
searches.add(tagTimeline);
|
||||
|
|
|
@ -26,7 +26,7 @@ import android.database.sqlite.SQLiteOpenHelper;
|
|||
|
||||
public class Sqlite extends SQLiteOpenHelper {
|
||||
|
||||
public static final int DB_VERSION = 20;
|
||||
public static final int DB_VERSION = 24;
|
||||
public static final String DB_NAME = "mastodon_etalab_db";
|
||||
public static SQLiteDatabase db;
|
||||
private static Sqlite sInstance;
|
||||
|
@ -82,7 +82,10 @@ public class Sqlite extends SQLiteOpenHelper {
|
|||
static final String COL_INSTANCE = "INSTANCE";
|
||||
static final String COL_OAUTHTOKEN = "OAUTH_TOKEN";
|
||||
static final String COL_EMOJIS = "EMOJIS";
|
||||
|
||||
static final String COL_SOCIAL = "SOCIAL";
|
||||
static final String COL_CLIENT_ID = "CLIENT_ID";
|
||||
static final String COL_CLIENT_SECRET = "CLIENT_SECRET";
|
||||
static final String COL_REFRESH_TOKEN = "REFRESH_TOKEN";
|
||||
|
||||
private static final String CREATE_TABLE_USER_ACCOUNT = "CREATE TABLE " + TABLE_USER_ACCOUNT + " ("
|
||||
+ COL_USER_ID + " TEXT PRIMARY KEY, " + COL_USERNAME + " TEXT NOT NULL, " + COL_ACCT + " TEXT NOT NULL, "
|
||||
|
@ -92,6 +95,8 @@ public class Sqlite extends SQLiteOpenHelper {
|
|||
+ COL_AVATAR + " TEXT NOT NULL, "+ COL_AVATAR_STATIC + " TEXT NOT NULL, "
|
||||
+ COL_HEADER + " TEXT NOT NULL, "+ COL_HEADER_STATIC + " TEXT NOT NULL, "
|
||||
+ COL_EMOJIS + " TEXT, "
|
||||
+ COL_SOCIAL + " TEXT, "
|
||||
+ COL_CLIENT_ID + " TEXT, " + COL_CLIENT_SECRET + " TEXT, " + COL_REFRESH_TOKEN + " TEXT,"
|
||||
+ COL_INSTANCE + " TEXT NOT NULL, " + COL_OAUTHTOKEN + " TEXT NOT NULL, " + COL_CREATED_AT + " TEXT NOT NULL)";
|
||||
|
||||
|
||||
|
@ -123,9 +128,14 @@ public class Sqlite extends SQLiteOpenHelper {
|
|||
static final String COL_KEYWORDS = "KEYWORDS";
|
||||
static final String COL_IS_ART= "IS_ART";
|
||||
static final String COL_IS_NSFW= "IS_NSFW";
|
||||
static final String COL_ANY= "ANY_TAG";
|
||||
static final String COL_ALL= "ALL_TAG";
|
||||
static final String COL_NONE = "NONE_TAG";
|
||||
static final String COL_NAME = "NAME";
|
||||
private final String CREATE_TABLE_SEARCH = "CREATE TABLE " + TABLE_SEARCH + " ("
|
||||
+ COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||
+ COL_KEYWORDS + " TEXT NOT NULL, " + COL_USER_ID + " TEXT NOT NULL, "
|
||||
+ COL_ANY + " TEXT, " + COL_ALL + " TEXT, " + COL_NONE + " TEXT, "+ COL_NAME + " TEXT, "
|
||||
+ COL_IS_ART + " INTEGER DEFAULT 0, " + COL_IS_NSFW + " INTEGER DEFAULT 0, "
|
||||
+ COL_DATE_CREATION + " TEXT NOT NULL)";
|
||||
|
||||
|
@ -161,6 +171,7 @@ public class Sqlite extends SQLiteOpenHelper {
|
|||
static final String COL_DATE_BACKUP = "DATE_BACKUP";
|
||||
static final String COL_CARD = "CARD";
|
||||
|
||||
|
||||
private final String CREATE_TABLE_STATUSES_CACHE = "CREATE TABLE " + TABLE_STATUSES_CACHE + " ("
|
||||
+ COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||
+ COL_CACHED_ACTION + " INTEGER NOT NULL, "+ COL_INSTANCE + " TEXT NOT NULL, " + COL_USER_ID + " NOT NULL, " + COL_DATE_BACKUP + " TEXT NOT NULL, "
|
||||
|
@ -291,6 +302,22 @@ public class Sqlite extends SQLiteOpenHelper {
|
|||
db.execSQL("ALTER TABLE " + TABLE_SEARCH + " ADD COLUMN " + COL_IS_ART + " INTEGER DEFAULT 0");
|
||||
db.execSQL("ALTER TABLE " + TABLE_SEARCH + " ADD COLUMN " + COL_IS_NSFW + " INTEGER DEFAULT 0");
|
||||
}
|
||||
case 20:
|
||||
if( oldVersion > 6) {
|
||||
db.execSQL("ALTER TABLE " + TABLE_SEARCH + " ADD COLUMN " + COL_ANY + " TEXT");
|
||||
db.execSQL("ALTER TABLE " + TABLE_SEARCH + " ADD COLUMN " + COL_ALL + " TEXT");
|
||||
db.execSQL("ALTER TABLE " + TABLE_SEARCH + " ADD COLUMN " + COL_NONE + " TEXT");
|
||||
}
|
||||
case 21:
|
||||
if( oldVersion > 6) {
|
||||
db.execSQL("ALTER TABLE " + TABLE_SEARCH + " ADD COLUMN " + COL_NAME + " TEXT");
|
||||
}
|
||||
case 22:
|
||||
db.execSQL("ALTER TABLE " + TABLE_USER_ACCOUNT + " ADD COLUMN " + COL_SOCIAL + " TEXT");
|
||||
case 23:
|
||||
db.execSQL("ALTER TABLE " + TABLE_USER_ACCOUNT + " ADD COLUMN " + COL_CLIENT_ID + " TEXT");
|
||||
db.execSQL("ALTER TABLE " + TABLE_USER_ACCOUNT + " ADD COLUMN " + COL_CLIENT_SECRET + " TEXT");
|
||||
db.execSQL("ALTER TABLE " + TABLE_USER_ACCOUNT + " ADD COLUMN " + COL_REFRESH_TOKEN + " TEXT");
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -224,6 +224,24 @@ public class StatusCacheDAO {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns all cached Statuses in db depending of their cache type
|
||||
* @return stored status List<StoredStatus>
|
||||
*/
|
||||
public List<String> getAllStatusId(int cacheType){
|
||||
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
String instance = Helper.getLiveInstance(context);
|
||||
try {
|
||||
Cursor c = db.query(Sqlite.TABLE_STATUSES_CACHE, new String[]{Sqlite.COL_STATUS_ID}, Sqlite.COL_CACHED_ACTION + " = '" + cacheType+ "' AND " + Sqlite.COL_INSTANCE + " = '" + instance+ "' AND " + Sqlite.COL_USER_ID + " = '" + userId+ "'", null, null, null, Sqlite.COL_CREATED_AT + " DESC", null);
|
||||
return cursorToListStatusesId(c);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns all cached Statuses in db depending of their cache type
|
||||
* @return stored status List<StoredStatus>
|
||||
|
@ -512,4 +530,26 @@ public class StatusCacheDAO {
|
|||
//Statuses list is returned
|
||||
return statuses;
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
* Method to get cached statuses ID from database
|
||||
* @param c Cursor
|
||||
* @return List<Status>
|
||||
*/
|
||||
private List<String> cursorToListStatusesId(Cursor c){
|
||||
//No element found
|
||||
if (c.getCount() == 0)
|
||||
return null;
|
||||
List<String> statusesId = new ArrayList<>();
|
||||
while (c.moveToNext() ) {
|
||||
//Restore cached status
|
||||
|
||||
statusesId.add(c.getString(c.getColumnIndex(Sqlite.COL_STATUS_ID)));
|
||||
}
|
||||
//Close the cursor
|
||||
c.close();
|
||||
//Statuses list is returned
|
||||
return statusesId;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M7,7h10v3l4,-4 -4,-4v3L5,5v6h2L7,7zM17,17L7,17v-3l-4,4 4,4v-3h12v-6h-2v4z"/>
|
||||
</vector>
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.89,2 2,2zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2z"/>
|
||||
</vector>
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM18.92,8h-2.95c-0.32,-1.25 -0.78,-2.45 -1.38,-3.56 1.84,0.63 3.37,1.91 4.33,3.56zM12,4.04c0.83,1.2 1.48,2.53 1.91,3.96h-3.82c0.43,-1.43 1.08,-2.76 1.91,-3.96zM4.26,14C4.1,13.36 4,12.69 4,12s0.1,-1.36 0.26,-2h3.38c-0.08,0.66 -0.14,1.32 -0.14,2 0,0.68 0.06,1.34 0.14,2L4.26,14zM5.08,16h2.95c0.32,1.25 0.78,2.45 1.38,3.56 -1.84,-0.63 -3.37,-1.9 -4.33,-3.56zM8.03,8L5.08,8c0.96,-1.66 2.49,-2.93 4.33,-3.56C8.81,5.55 8.35,6.75 8.03,8zM12,19.96c-0.83,-1.2 -1.48,-2.53 -1.91,-3.96h3.82c-0.43,1.43 -1.08,2.76 -1.91,3.96zM14.34,14L9.66,14c-0.09,-0.66 -0.16,-1.32 -0.16,-2 0,-0.68 0.07,-1.35 0.16,-2h4.68c0.09,0.65 0.16,1.32 0.16,2 0,0.68 -0.07,1.34 -0.16,2zM14.59,19.56c0.6,-1.11 1.06,-2.31 1.38,-3.56h2.95c-0.96,1.65 -2.49,2.93 -4.33,3.56zM16.36,14c0.08,-0.66 0.14,-1.32 0.14,-2 0,-0.68 -0.06,-1.34 -0.14,-2h3.38c0.16,0.64 0.26,1.31 0.26,2s-0.1,1.36 -0.26,2h-3.38z"/>
|
||||
</vector>
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12,21.35l-1.45,-1.32C5.4,15.36 2,12.28 2,8.5 2,5.42 4.42,3 7.5,3c1.74,0 3.41,0.81 4.5,2.09C13.09,3.81 14.76,3 16.5,3 19.58,3 22,5.42 22,8.5c0,3.78 -3.4,6.86 -8.55,11.54L12,21.35z"/>
|
||||
</vector>
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M16.5,3c-1.74,0 -3.41,0.81 -4.5,2.09C10.91,3.81 9.24,3 7.5,3 4.42,3 2,5.42 2,8.5c0,3.78 3.4,6.86 8.55,11.54L12,21.35l1.45,-1.32C18.6,15.36 22,12.28 22,8.5 22,5.42 19.58,3 16.5,3zM12.1,18.55l-0.1,0.1 -0.1,-0.1C7.14,14.24 4,11.39 4,8.5 4,6.5 5.5,5 7.5,5c1.54,0 3.04,0.99 3.57,2.36h1.87C13.46,5.99 14.96,5 16.5,5c2,0 3.5,1.5 3.5,3.5 0,2.89 -3.14,5.74 -7.9,10.05z"/>
|
||||
</vector>
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M2,6L0,6v5h0.01L0,20c0,1.1 0.9,2 2,2h18v-2L2,20L2,6zM22,4h-8l-2,-2L6,2c-1.1,0 -1.99,0.9 -1.99,2L4,16c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L24,6c0,-1.1 -0.9,-2 -2,-2zM7,15l4.5,-6 3.5,4.51 2.5,-3.01L21,15L7,15z"/>
|
||||
</vector>
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M13,7h-2v4L7,11v2h4v4h2v-4h4v-2h-4L13,7zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8z"/>
|
||||
</vector>
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M20,8L4,8L4,6h16v2zM18,2L6,2v2h12L18,2zM22,12v8c0,1.1 -0.9,2 -2,2L4,22c-1.1,0 -2,-0.9 -2,-2v-8c0,-1.1 0.9,-2 2,-2h16c1.1,0 2,0.9 2,2zM16,16l-6,-3.27v6.53L16,16z"/>
|
||||
</vector>
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12.87,15.07l-2.54,-2.51 0.03,-0.03c1.74,-1.94 2.98,-4.17 3.71,-6.53L17,6L17,4h-7L10,2L8,2v2L1,4v1.99h11.17C11.5,7.92 10.44,9.75 9,11.35 8.07,10.32 7.3,9.19 6.69,8h-2c0.73,1.63 1.73,3.17 2.98,4.56l-5.09,5.02L4,19l5,-5 3.11,3.11 0.76,-2.04zM18.5,10h-2L12,22h2l1.12,-3h4.75L21,22h2l-4.5,-12zM15.88,17l1.62,-4.33L19.12,17h-3.24z"/>
|
||||
</vector>
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M16,6l2.29,2.29 -4.88,4.88 -4,-4L2,16.59 3.41,18l6,-6 4,4 6.3,-6.29L22,12V6z"/>
|
||||
</vector>
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M4,6L2,6v14c0,1.1 0.9,2 2,2h14v-2L4,20L4,6zM20,2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM12,14.5v-9l6,4.5 -6,4.5z"/>
|
||||
</vector>
|
Binary file not shown.
After Width: | Height: | Size: 331 B |
Binary file not shown.
After Width: | Height: | Size: 146 B |
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue