428 lines
20 KiB
Java
428 lines
20 KiB
Java
package app.fedilab.mobilizon;
|
|
|
|
import android.Manifest;
|
|
import android.annotation.SuppressLint;
|
|
import android.app.Activity;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.SharedPreferences;
|
|
import android.content.pm.PackageInfo;
|
|
import android.content.pm.PackageManager;
|
|
import android.net.Uri;
|
|
import android.os.Bundle;
|
|
import android.text.SpannableString;
|
|
import android.text.style.UnderlineSpan;
|
|
import android.view.LayoutInflater;
|
|
import android.view.Menu;
|
|
import android.view.MenuItem;
|
|
import android.view.View;
|
|
import android.view.ViewGroup;
|
|
import android.webkit.ValueCallback;
|
|
import android.webkit.WebView;
|
|
import android.widget.EditText;
|
|
import android.widget.FrameLayout;
|
|
import android.widget.LinearLayout;
|
|
import android.widget.RelativeLayout;
|
|
import android.widget.TextView;
|
|
import android.widget.Toast;
|
|
|
|
import androidx.annotation.NonNull;
|
|
import androidx.appcompat.app.ActionBarDrawerToggle;
|
|
import androidx.appcompat.app.AlertDialog;
|
|
import androidx.appcompat.app.AppCompatActivity;
|
|
import androidx.appcompat.widget.SearchView;
|
|
import androidx.appcompat.widget.Toolbar;
|
|
import androidx.core.view.GravityCompat;
|
|
import androidx.drawerlayout.widget.DrawerLayout;
|
|
|
|
import com.google.android.material.navigation.NavigationView;
|
|
import com.google.android.material.snackbar.Snackbar;
|
|
import com.karumi.dexter.Dexter;
|
|
import com.karumi.dexter.listener.multi.MultiplePermissionsListener;
|
|
import com.karumi.dexter.listener.multi.SnackbarOnAnyDeniedMultiplePermissionsListener;
|
|
|
|
import java.io.File;
|
|
import java.io.UnsupportedEncodingException;
|
|
import java.net.URLEncoder;
|
|
import java.nio.charset.StandardCharsets;
|
|
|
|
import app.fedilab.mobilizon.client.RetrofitMobilizonAPI;
|
|
import app.fedilab.mobilizon.client.entities.WellKnownNodeinfo;
|
|
import app.fedilab.mobilizon.helper.Helper;
|
|
import app.fedilab.mobilizon.webview.MobilizonWebChromeClient;
|
|
import app.fedilab.mobilizon.webview.MobilizonWebViewClient;
|
|
import es.dmoral.toasty.Toasty;
|
|
|
|
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
|
|
|
|
public static final int INPUT_FILE_REQUEST_CODE = 123;
|
|
public static boolean isAuthenticated = false;
|
|
private RelativeLayout progress;
|
|
private WebView main_webview;
|
|
private FrameLayout webview_container;
|
|
private ValueCallback<Uri[]> mFilePathCallback;
|
|
private static final int PICK_INSTANCE = 546;
|
|
|
|
@Override
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
super.onCreate(savedInstanceState);
|
|
setContentView(R.layout.activity_main);
|
|
Toolbar toolbar = findViewById(R.id.toolbar);
|
|
setSupportActionBar(toolbar);
|
|
|
|
final DrawerLayout drawer = findViewById(R.id.drawer_layout);
|
|
|
|
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
|
|
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
|
|
toggle.setDrawerIndicatorEnabled(false);
|
|
if (getSupportActionBar() != null) {
|
|
getSupportActionBar().setHomeButtonEnabled(true);
|
|
|
|
toggle = new ActionBarDrawerToggle(
|
|
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
|
|
toggle.setDrawerIndicatorEnabled(true);
|
|
drawer.addDrawerListener(toggle);
|
|
toggle.syncState();
|
|
|
|
}
|
|
final NavigationView navigationView = findViewById(R.id.nav_view);
|
|
navigationView.setNavigationItemSelectedListener(this);
|
|
|
|
|
|
WebView.setWebContentsDebuggingEnabled(true);
|
|
drawMenu();
|
|
main_webview = findViewById(R.id.main_webview);
|
|
|
|
progress = findViewById(R.id.progress);
|
|
webview_container = findViewById(R.id.webview_container);
|
|
final ViewGroup videoLayout = findViewById(R.id.videoLayout);
|
|
String instance = Helper.getLiveInstance(MainActivity.this);
|
|
Helper.initializeWebview(MainActivity.this, main_webview, instance);
|
|
MobilizonWebChromeClient mobilizonWebChromeClient = new MobilizonWebChromeClient(MainActivity.this, main_webview, webview_container, videoLayout);
|
|
main_webview.setWebChromeClient(mobilizonWebChromeClient);
|
|
main_webview.setWebViewClient(new MobilizonWebViewClient(MainActivity.this));
|
|
|
|
showProgressDialog();
|
|
main_webview.loadUrl("https://" + instance);
|
|
|
|
MultiplePermissionsListener snackbarMultiplePermissionsListener =
|
|
SnackbarOnAnyDeniedMultiplePermissionsListener.Builder
|
|
.with(main_webview, R.string.permissions_message)
|
|
.withOpenSettingsButton(R.string.settings)
|
|
.withCallback(new Snackbar.Callback() {
|
|
@Override
|
|
public void onShown(Snackbar snackbar) {
|
|
// Event handler for when the given Snackbar is visible
|
|
}
|
|
@Override
|
|
public void onDismissed(Snackbar snackbar, int event) {
|
|
// Event handler for when the given Snackbar has been dismissed
|
|
}
|
|
})
|
|
.build();
|
|
Dexter.withContext(this)
|
|
.withPermissions(
|
|
Manifest.permission.ACCESS_COARSE_LOCATION,
|
|
Manifest.permission.ACCESS_FINE_LOCATION
|
|
)
|
|
.withListener(snackbarMultiplePermissionsListener).check();
|
|
|
|
new Thread(() -> {
|
|
try {
|
|
WellKnownNodeinfo.NodeInfo instanceNodeInfo = new RetrofitMobilizonAPI(instance).getNodeInfo();
|
|
if (instanceNodeInfo.getSoftware() != null && instanceNodeInfo.getSoftware().getName().trim().toLowerCase().compareTo("mobilizon") == 0) {
|
|
runOnUiThread(() -> {
|
|
final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
|
String previousVersion = sharedpreferences.getString(Helper.PREF_VERSION+instance, null);
|
|
if( previousVersion != null && previousVersion.trim().compareTo(instanceNodeInfo.getSoftware().getVersion()) != 0) {
|
|
SharedPreferences.Editor editor = sharedpreferences.edit();
|
|
editor.putString(Helper.PREF_VERSION + instance.trim(), instanceNodeInfo.getSoftware().getVersion().trim());
|
|
editor.apply();
|
|
File dir = new File(getFilesDir().getPath()+"/" + instance);
|
|
if (dir.isDirectory()) {
|
|
String[] children = dir.list();
|
|
if( children != null) {
|
|
for (String child : children) {
|
|
//noinspection ResultOfMethodCallIgnored
|
|
new File(dir, child).delete();
|
|
}
|
|
}
|
|
}
|
|
main_webview.reload();
|
|
}else if(previousVersion == null) {
|
|
SharedPreferences.Editor editor = sharedpreferences.edit();
|
|
editor.putString(Helper.PREF_VERSION + instance.trim(), instanceNodeInfo.getSoftware().getVersion().trim());
|
|
editor.apply();
|
|
}
|
|
});
|
|
}
|
|
} catch (Exception ignored) {}
|
|
|
|
}).start();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
public boolean onCreateOptionsMenu(Menu menu) {
|
|
// Inflate the menu; this adds items to the action bar if it is present.
|
|
getMenuInflater().inflate(R.menu.menu_main, menu);
|
|
|
|
MenuItem myActionMenuItem = menu.findItem(R.id.action_search);
|
|
SearchView searchView = (SearchView) myActionMenuItem.getActionView();
|
|
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
|
@Override
|
|
public boolean onQueryTextSubmit(String query) {
|
|
try {
|
|
main_webview.loadUrl("https://" + Helper.getLiveInstance(MainActivity.this) + "/search?term=" + URLEncoder.encode(query, String.valueOf(StandardCharsets.UTF_8)));
|
|
} catch (UnsupportedEncodingException e) {
|
|
e.printStackTrace();
|
|
}
|
|
if (!searchView.isIconified()) {
|
|
searchView.setIconified(true);
|
|
}
|
|
myActionMenuItem.collapseActionView();
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean onQueryTextChange(String s) {
|
|
return false;
|
|
}
|
|
});
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean onOptionsItemSelected(MenuItem item) {
|
|
// Handle action bar item clicks here. The action bar will
|
|
// automatically handle clicks on the Home/Up button, so long
|
|
// as you specify a parent activity in AndroidManifest.xml.
|
|
int id = item.getItemId();
|
|
|
|
//noinspection SimplifiableIfStatement
|
|
if (id == R.id.action_instance) {
|
|
showRadioButtonDialogFullInstances();
|
|
return true;
|
|
} else if (id == R.id.action_about) {
|
|
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
|
|
LayoutInflater inflater = getLayoutInflater();
|
|
View dialogView = inflater.inflate(R.layout.popup_about, new LinearLayout(MainActivity.this), false);
|
|
TextView about = dialogView.findViewById(R.id.about);
|
|
TextView terms = dialogView.findViewById(R.id.terms);
|
|
TextView license = dialogView.findViewById(R.id.license);
|
|
TextView about_the_app = dialogView.findViewById(R.id.about_the_app);
|
|
|
|
SpannableString contentAbout = new SpannableString(about.getText().toString());
|
|
contentAbout.setSpan(new UnderlineSpan(), 0, contentAbout.length(), 0);
|
|
about.setText(contentAbout);
|
|
about.setOnClickListener(v -> {
|
|
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://" + Helper.getLiveInstance(MainActivity.this) + "/about"));
|
|
startActivity(browserIntent);
|
|
});
|
|
|
|
SpannableString contentTerms = new SpannableString(terms.getText().toString());
|
|
contentTerms.setSpan(new UnderlineSpan(), 0, contentTerms.length(), 0);
|
|
terms.setText(contentTerms);
|
|
terms.setOnClickListener(v -> {
|
|
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://" + Helper.getLiveInstance(MainActivity.this) + "/terms"));
|
|
startActivity(browserIntent);
|
|
});
|
|
SpannableString contentLicense = new SpannableString(license.getText().toString());
|
|
contentLicense.setSpan(new UnderlineSpan(), 0, contentLicense.length(), 0);
|
|
license.setText(contentLicense);
|
|
license.setOnClickListener(v -> {
|
|
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://framagit.org/framasoft/mobilizon/blob/master/LICENSE"));
|
|
startActivity(browserIntent);
|
|
});
|
|
|
|
try {
|
|
PackageInfo pInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
|
|
String version = pInfo.versionName;
|
|
about_the_app.setText(getResources().getString(R.string.about_the_app, version));
|
|
} catch (PackageManager.NameNotFoundException ignored) {
|
|
}
|
|
|
|
SpannableString contentAboutApp = new SpannableString(about_the_app.getText().toString());
|
|
contentAboutApp.setSpan(new UnderlineSpan(), 0, contentAboutApp.length(), 0);
|
|
about_the_app.setText(contentAboutApp);
|
|
about_the_app.setOnClickListener(v -> {
|
|
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://framagit.org/tom79/mobilizon-android-app"));
|
|
startActivity(browserIntent);
|
|
});
|
|
|
|
builder.setView(dialogView);
|
|
builder
|
|
.setPositiveButton(R.string.close, (dialog, which) -> dialog.dismiss())
|
|
.setIcon(R.drawable.ic_baseline_info_24)
|
|
.show();
|
|
}
|
|
|
|
return super.onOptionsItemSelected(item);
|
|
}
|
|
|
|
public void showProgressDialog() {
|
|
if (progress != null) {
|
|
progress.setVisibility(View.VISIBLE);
|
|
webview_container.setVisibility(View.GONE);
|
|
}
|
|
}
|
|
|
|
public void hideProgressDialog() {
|
|
if (progress != null) {
|
|
progress.setVisibility(View.GONE);
|
|
webview_container.setVisibility(View.VISIBLE);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onBackPressed() {
|
|
if (main_webview.canGoBack()) {
|
|
main_webview.goBack();
|
|
} else {
|
|
super.onBackPressed();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
|
|
int id = item.getItemId();
|
|
if (id == R.id.nav_explore) {
|
|
main_webview.loadUrl("javascript:document.querySelector('a[href=\"/search\"]').click();");
|
|
} else if (id == R.id.nav_my_event) {
|
|
main_webview.loadUrl("javascript:document.querySelector('a[href=\"/events/me\"]').click();");
|
|
} else if (id == R.id.nav_my_group) {
|
|
main_webview.loadUrl("javascript:document.querySelector('a[href=\"/groups/me\"]').click();");
|
|
} else if (id == R.id.nav_create_event) {
|
|
main_webview.loadUrl("javascript:document.querySelector('a[href=\"/events/create\"]').click();");
|
|
} else if (id == R.id.nav_login) {
|
|
main_webview.loadUrl("javascript:document.querySelector('a[href=\"/login\"]').click();");
|
|
} else if (id == R.id.nav_logout) {
|
|
Helper.clearCookies();
|
|
new java.util.Timer().schedule(
|
|
new java.util.TimerTask() {
|
|
@Override
|
|
public void run() {
|
|
runOnUiThread(() -> {
|
|
isAuthenticated = false;
|
|
drawMenu();
|
|
main_webview.loadUrl("https://" + Helper.getLiveInstance(MainActivity.this));
|
|
});
|
|
}
|
|
},
|
|
1000
|
|
);
|
|
} else if (id == R.id.nav_profile) {
|
|
main_webview.loadUrl("javascript:document.querySelector('a[href=\"/identity/update\"]').click();");
|
|
} else if (id == R.id.nav_register) {
|
|
main_webview.loadUrl("javascript:document.querySelector('a[href=\"/register/user\"]').click();");
|
|
}
|
|
|
|
DrawerLayout drawer = findViewById(R.id.drawer_layout);
|
|
drawer.closeDrawer(GravityCompat.START);
|
|
return true;
|
|
}
|
|
|
|
@SuppressLint("ApplySharedPref")
|
|
private void showRadioButtonDialogFullInstances() {
|
|
final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
|
AlertDialog.Builder alt_bld = new AlertDialog.Builder(this);
|
|
alt_bld.setTitle(R.string.instance_choice);
|
|
String instance = Helper.getLiveInstance(MainActivity.this);
|
|
final EditText input = new EditText(MainActivity.this);
|
|
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
|
|
LinearLayout.LayoutParams.MATCH_PARENT,
|
|
LinearLayout.LayoutParams.MATCH_PARENT);
|
|
input.setLayoutParams(lp);
|
|
alt_bld.setView(input);
|
|
input.setText(instance);
|
|
alt_bld.setPositiveButton(R.string.validate,
|
|
(dialog, which) -> new Thread(() -> {
|
|
try {
|
|
String newInstance = input.getText().toString().trim();
|
|
WellKnownNodeinfo.NodeInfo instanceNodeInfo = new RetrofitMobilizonAPI(newInstance).getNodeInfo();
|
|
if (instanceNodeInfo.getSoftware() != null && instanceNodeInfo.getSoftware().getName().trim().toLowerCase().compareTo("mobilizon") == 0) {
|
|
SharedPreferences.Editor editor = sharedpreferences.edit();
|
|
editor.putString(Helper.PREF_INSTANCE, newInstance);
|
|
editor.commit();
|
|
runOnUiThread(() -> {
|
|
dialog.dismiss();
|
|
main_webview.clearHistory();
|
|
main_webview.loadUrl("https://" + newInstance);
|
|
});
|
|
} else {
|
|
runOnUiThread(() -> Toasty.error(MainActivity.this, getString(R.string.not_valide_instance), Toast.LENGTH_LONG).show());
|
|
}
|
|
} catch (Exception e) {
|
|
runOnUiThread(() -> Toasty.error(MainActivity.this, getString(R.string.not_valide_instance), Toast.LENGTH_LONG).show());
|
|
e.printStackTrace();
|
|
}
|
|
|
|
}).start());
|
|
//TODO: uncomment and add support for picking instances when available
|
|
alt_bld.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
|
|
alt_bld.setNeutralButton(R.string.help, (dialog, which) -> {
|
|
Intent intent = new Intent(MainActivity.this, InstancePickerActivity.class);
|
|
startActivityForResult(intent, PICK_INSTANCE);
|
|
});
|
|
AlertDialog alert = alt_bld.create();
|
|
alert.show();
|
|
}
|
|
|
|
public ValueCallback<Uri[]> getmFilePathCallback() {
|
|
return mFilePathCallback;
|
|
}
|
|
|
|
public void setmFilePathCallback(ValueCallback<Uri[]> mFilePathCallback) {
|
|
this.mFilePathCallback = mFilePathCallback;
|
|
}
|
|
|
|
@SuppressLint("ApplySharedPref")
|
|
@Override
|
|
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
if (requestCode != INPUT_FILE_REQUEST_CODE || mFilePathCallback == null) {
|
|
if (requestCode == PICK_INSTANCE && resultCode == Activity.RESULT_OK) {
|
|
if (data != null && data.getData() != null) {
|
|
final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
|
SharedPreferences.Editor editor = sharedpreferences.edit();
|
|
editor.putString(Helper.PREF_INSTANCE, String.valueOf(data.getData()));
|
|
editor.commit();
|
|
recreate();
|
|
}
|
|
}
|
|
super.onActivityResult(requestCode, resultCode, data);
|
|
return;
|
|
}
|
|
Uri[] results = null;
|
|
if (resultCode == Activity.RESULT_OK) {
|
|
if (data != null) {
|
|
String dataString = data.getDataString();
|
|
if (dataString != null) {
|
|
results = new Uri[]{Uri.parse(dataString)};
|
|
}
|
|
}
|
|
}
|
|
mFilePathCallback.onReceiveValue(results);
|
|
mFilePathCallback = null;
|
|
}
|
|
|
|
public void drawMenu() {
|
|
final NavigationView navigationView = findViewById(R.id.nav_view);
|
|
if (isAuthenticated) {
|
|
navigationView.getMenu().findItem(R.id.nav_create_event).setVisible(true);
|
|
navigationView.getMenu().findItem(R.id.nav_profile).setVisible(true);
|
|
navigationView.getMenu().findItem(R.id.nav_login).setVisible(false);
|
|
navigationView.getMenu().findItem(R.id.nav_logout).setVisible(true);
|
|
navigationView.getMenu().findItem(R.id.nav_register).setVisible(false);
|
|
} else {
|
|
navigationView.getMenu().findItem(R.id.nav_create_event).setVisible(false);
|
|
navigationView.getMenu().findItem(R.id.nav_profile).setVisible(false);
|
|
navigationView.getMenu().findItem(R.id.nav_login).setVisible(true);
|
|
navigationView.getMenu().findItem(R.id.nav_logout).setVisible(false);
|
|
navigationView.getMenu().findItem(R.id.nav_register).setVisible(true);
|
|
}
|
|
//navigationView.invalidate();
|
|
}
|
|
|
|
} |