diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 71b0e60c7..dc6012de3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -139,6 +139,18 @@
android:configChanges="orientation|screenSize"
android:label="@string/app_name"
/>
+
+
+
+
+
+
+
+
mPageReferenceMap = new HashMap<>();
private static boolean notificationChecked = false;
public static HashMap poll_limits = new HashMap<>();
+ private Instance instanceClass;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -974,6 +978,22 @@ public abstract class BaseMainActivity extends BaseActivity
intent = new Intent(getApplicationContext(), InstanceActivity.class);
startActivity(intent);
return true;
+ case R.id.action_send_invitation:
+ if( instanceClass != null){
+ if(instanceClass.isRegistration()){
+ Intent sendIntent = new Intent(Intent.ACTION_SEND);
+ String extra_text = getString(R.string.join_instance, Helper.getLiveInstance(getApplicationContext()),
+ "https://f-droid.org/en/packages/fr.gouv.etalab.mastodon/",
+ "https://play.google.com/store/apps/details?id=app.fedilab.android",
+ "https://fedilab.app/registration_helper/" + Helper.getLiveInstance(getApplicationContext()));
+ sendIntent.putExtra(Intent.EXTRA_TEXT, extra_text);
+ sendIntent.setType("text/plain");
+ startActivity(Intent.createChooser(sendIntent, getString(R.string.share_with)));
+ }else{
+ Toasty.info(getApplicationContext(), getString(R.string.registration_closed), Toast.LENGTH_SHORT).show();
+ }
+ }
+ return true;
case R.id.action_cache:
new Helper.CacheTask(BaseMainActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
return true;
@@ -1923,6 +1943,8 @@ public abstract class BaseMainActivity extends BaseActivity
}
if( apiResponse.getInstance() == null || apiResponse.getInstance().getVersion() == null || apiResponse.getInstance().getVersion().trim().length() == 0)
return;
+
+ instanceClass = apiResponse.getInstance();
poll_limits = apiResponse.getInstance().getPoll_limits();
Version currentVersion = new Version(apiResponse.getInstance().getVersion());
Version minVersion = new Version("1.6");
diff --git a/app/src/main/java/app/fedilab/android/activities/MastodonShareRegisterActivity.java b/app/src/main/java/app/fedilab/android/activities/MastodonShareRegisterActivity.java
new file mode 100644
index 000000000..94c5a442f
--- /dev/null
+++ b/app/src/main/java/app/fedilab/android/activities/MastodonShareRegisterActivity.java
@@ -0,0 +1,329 @@
+/* Copyright 2017 Thomas Schneider
+ *
+ * This file is a part of Fedilab
+ *
+ * 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.
+ *
+ * Fedilab 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 Fedilab; if not,
+ * see . */
+package app.fedilab.android.activities;
+
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.text.Html;
+import android.text.method.LinkMovementMethod;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.widget.Toolbar;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+
+import java.io.IOException;
+import java.lang.ref.WeakReference;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.List;
+
+import app.fedilab.android.R;
+import app.fedilab.android.asynctasks.CreateMastodonAccountAsyncTask;
+import app.fedilab.android.client.APIResponse;
+import app.fedilab.android.client.Entities.AccountCreation;
+import app.fedilab.android.client.Entities.InstanceReg;
+import app.fedilab.android.drawers.InstanceRegAdapter;
+import app.fedilab.android.helper.Helper;
+import app.fedilab.android.interfaces.OnPostStatusActionInterface;
+import app.fedilab.android.interfaces.OnRetrieveInstanceInterface;
+import es.dmoral.toasty.Toasty;
+
+import static android.os.AsyncTask.THREAD_POOL_EXECUTOR;
+
+/**
+ * Created by Thomas on 17/08/2019.
+ * Register activity class
+ */
+
+public class MastodonShareRegisterActivity extends BaseActivity implements OnRetrieveInstanceInterface, OnPostStatusActionInterface {
+
+
+ private Button signup;
+ private String instance;
+ private TextView error_message;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, 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);
+ }
+
+ setContentView(R.layout.activity_register);
+ ActionBar actionBar = getSupportActionBar();
+ if( actionBar != null ) {
+ LayoutInflater inflater = (LayoutInflater) this.getSystemService(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.sign_up);
+ if (theme == Helper.THEME_LIGHT){
+ Toolbar toolbar = actionBar.getCustomView().findViewById(R.id.toolbar);
+ Helper.colorizeToolbar(toolbar, R.color.black, MastodonShareRegisterActivity.this);
+ }
+ }
+ if( this.getIntent() == null || this.getIntent().getData() == null){
+ Intent mainActivity = new Intent(MastodonShareRegisterActivity.this, MastodonRegisterActivity.class);
+ startActivity(mainActivity);
+ finish();
+ }
+ Uri data = this.getIntent().getData();
+
+ assert data != null;
+ String[] splitURL = data.toString().split("registration_helper");
+ if( splitURL.length < 2 || splitURL[1] == null || splitURL[1].length() == 1){
+ Intent mainActivity = new Intent(MastodonShareRegisterActivity.this, MastodonRegisterActivity.class);
+ startActivity(mainActivity);
+ finish();
+ }
+ String instance = splitURL[1].replace("/","");
+ pickupInstance(instance);
+
+
+ LinearLayout form_container = findViewById(R.id.form_container);
+ LinearLayout drawer_layout = findViewById(R.id.drawer_layout);
+ TextView change_instance = findViewById(R.id.change_instance);
+ form_container.setVisibility(View.VISIBLE);
+ drawer_layout.setVisibility(View.GONE);
+ change_instance.setVisibility(View.GONE);
+ signup = findViewById(R.id.signup);
+ EditText username = findViewById(R.id.username);
+ EditText email = findViewById(R.id.email);
+ EditText password = findViewById(R.id.password);
+ EditText password_confirm = findViewById(R.id.password_confirm);
+ CheckBox agreement = findViewById(R.id.agreement);
+ error_message = findViewById(R.id.error_message);
+
+ signup.setOnClickListener(view->{
+ error_message.setVisibility(View.GONE);
+ if( username.getText().toString().trim().length() == 0 || email.getText().toString().trim().length() == 0 ||
+ password.getText().toString().trim().length() == 0 || password_confirm.getText().toString().trim().length() == 0 || !agreement.isChecked()){
+ Toasty.error(MastodonShareRegisterActivity.this, getString(R.string.all_field_filled)).show();
+ return;
+ }
+ if(!password.getText().toString().trim().equals(password_confirm.getText().toString().trim())){
+ Toasty.error(MastodonShareRegisterActivity.this, getString(R.string.password_error)).show();
+ return;
+ }
+ if(!android.util.Patterns.EMAIL_ADDRESS.matcher(email.getText().toString().trim()).matches()){
+ Toasty.error(MastodonShareRegisterActivity.this, getString(R.string.email_error)).show();
+ return;
+ }
+ if(password.getText().toString().trim().length() < 8 ){
+ Toasty.error(MastodonShareRegisterActivity.this, getString(R.string.password_too_short)).show();
+ return;
+ }
+ if(username.getText().toString().matches("[a-zA-Z0-9_]")){
+ Toasty.error(MastodonShareRegisterActivity.this, getString(R.string.username_error)).show();
+ return;
+ }
+ signup.setEnabled(false);
+ AccountCreation accountCreation = new AccountCreation();
+ accountCreation.setEmail(email.getText().toString().trim());
+ accountCreation.setPassword(password.getText().toString().trim());
+ accountCreation.setPasswordConfirm(password_confirm.getText().toString().trim());
+ accountCreation.setUsername(username.getText().toString().trim());
+ new CreateMastodonAccountAsyncTask(MastodonShareRegisterActivity.this, accountCreation, instance, MastodonShareRegisterActivity.this).executeOnExecutor(THREAD_POOL_EXECUTOR);
+ });
+
+
+ }
+
+ @Override
+ protected void onResume(){
+ super.onResume();
+ }
+
+ @Override
+ public void onRetrieveInstance(APIResponse apiResponse) {
+ if( apiResponse.getError() != null ){
+ Toasty.error(MastodonShareRegisterActivity.this, getString(R.string.toast_error_instance_reg), Toast.LENGTH_LONG).show();
+ return;
+ }
+ List instanceRegs = apiResponse.getInstanceRegs();
+ RecyclerView lv_instances = findViewById(R.id.reg_category_view);
+ InstanceRegAdapter instanceRegAdapter = new InstanceRegAdapter(MastodonShareRegisterActivity.this, instanceRegs);
+ LinearLayoutManager mLayoutManager = new LinearLayoutManager(MastodonShareRegisterActivity.this);
+ lv_instances.setLayoutManager(mLayoutManager);
+ lv_instances.setNestedScrollingEnabled(false);
+ lv_instances.setAdapter(instanceRegAdapter);
+
+
+ }
+
+ public void pickupInstance(String instance){
+
+ checkInstance(MastodonShareRegisterActivity.this, instance);
+
+
+ TextView host_reg = findViewById(R.id.host_reg);
+ host_reg.setText(instance);
+ this.instance = instance;
+
+
+ TextView agreement_text = findViewById(R.id.agreement_text);
+
+ TextView username_indicator = findViewById(R.id.username_indicator);
+ username_indicator.setText(getString(R.string.username_indicator, instance));
+
+ String tos = getString(R.string.tos);
+ String serverrules = getString(R.string.server_rules);
+ String content_agreement = getString(R.string.agreement_check,
+ ""+serverrules +"",
+ ""+tos +""
+ );
+ agreement_text.setMovementMethod(LinkMovementMethod.getInstance());
+ agreement_text.setText(Html.fromHtml(content_agreement));
+ }
+
+
+ private void checkInstance(Context context, String instance){
+ new checkRegistration(context, instance).executeOnExecutor(THREAD_POOL_EXECUTOR);
+ }
+
+ @Override
+ public void onPostStatusAction(APIResponse apiResponse) {
+ if( apiResponse.getError() != null){
+ String errorMessage;
+ if( apiResponse.getError().getError() != null){
+ try{
+ String[] resp = apiResponse.getError().getError().split(":");
+ if( resp.length == 2)
+ errorMessage = apiResponse.getError().getError().split(":")[1];
+ else if( resp.length == 3)
+ errorMessage = apiResponse.getError().getError().split(":")[2];
+ else
+ errorMessage = getString(R.string.toast_error);
+ }catch (Exception e){
+ errorMessage = getString(R.string.toast_error);
+ }
+ }else {
+ errorMessage = getString(R.string.toast_error);
+ }
+ error_message.setText(errorMessage);
+ error_message.setVisibility(View.VISIBLE);
+ signup.setEnabled(true);
+ return;
+ }
+ SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, 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;
+ }
+ AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(MastodonShareRegisterActivity.this, style);
+ dialogBuilder.setCancelable(false);
+ dialogBuilder.setPositiveButton(R.string.validate, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog,int which) {
+ dialog.dismiss();
+ finish();
+ }
+ });
+ AlertDialog alertDialog = dialogBuilder.create();
+ alertDialog.setTitle(getString(R.string.account_created));
+ alertDialog.setMessage(getString(R.string.account_created_message, this.instance));
+ alertDialog.show();
+ }
+
+
+ @SuppressLint("StaticFieldLeak")
+ private class checkRegistration extends AsyncTask {
+
+ private String instance;
+ private WeakReference weakReference;
+
+ checkRegistration(Context context, String instance){
+ this.instance = instance;
+ this.weakReference = new WeakReference<>(context);
+ }
+
+ @Override
+ protected String doInBackground(Void... params) {
+ String response = null;
+ try {
+ URL url = new URL("https://" + instance + "/auth/sign_up");
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
+ java.util.Scanner s = new java.util.Scanner(connection.getInputStream()).useDelimiter("\\A");
+ response = s.hasNext() ? s.next() : "";
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return response;
+ }
+
+ @Override
+ protected void onPostExecute(String result) {
+
+
+ if( result != null && result.contains("invite_request_attributes")){
+ TextView invitation = ((MastodonShareRegisterActivity)(weakReference.get())).findViewById(R.id.invitation);
+ if( invitation != null){
+ invitation.setVisibility(View.VISIBLE);
+ }
+ }
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/app/fedilab/android/client/API.java b/app/src/main/java/app/fedilab/android/client/API.java
index ee4314e3c..c8c13f5e4 100644
--- a/app/src/main/java/app/fedilab/android/client/API.java
+++ b/app/src/main/java/app/fedilab/android/client/API.java
@@ -4226,6 +4226,7 @@ public class API {
instanceSocial.setChecked_at(Helper.mstStringToDate(context, resobj.get("checked_at").toString()));
instanceSocial.setUpdated_at(Helper.mstStringToDate(context, resobj.get("updated_at").toString()));
+
} catch (Exception e) {
e.printStackTrace();
}
@@ -4993,7 +4994,16 @@ public class API {
instance.setDescription(resobj.get("description").toString());
instance.setEmail(resobj.get("email").toString());
instance.setVersion(resobj.get("version").toString());
-
+ if( resobj.has("registrations")){
+ instance.setRegistration(resobj.getBoolean("registrations"));
+ }else{
+ instance.setRegistration(false);
+ }
+ if( resobj.has("approval_required")){
+ instance.setApproval_required(resobj.getBoolean("approval_required"));
+ }else{
+ instance.setApproval_required(false);
+ }
if(resobj.has("poll_limits")){
HashMap poll_limits = new HashMap<>();
JSONObject polllimits = resobj.getJSONObject("poll_limits");
diff --git a/app/src/main/java/app/fedilab/android/client/Entities/Instance.java b/app/src/main/java/app/fedilab/android/client/Entities/Instance.java
index e0ff27c28..f4b4f4cd7 100644
--- a/app/src/main/java/app/fedilab/android/client/Entities/Instance.java
+++ b/app/src/main/java/app/fedilab/android/client/Entities/Instance.java
@@ -28,6 +28,9 @@ public class Instance {
private String description;
private String email;
private String version;
+ private boolean registration;
+ private boolean approval_required;
+
private HashMap poll_limits;
public String getUri() {
@@ -77,4 +80,20 @@ public class Instance {
public void setPoll_limits(HashMap poll_limits) {
this.poll_limits = poll_limits;
}
+
+ public boolean isRegistration() {
+ return registration;
+ }
+
+ public void setRegistration(boolean registration) {
+ this.registration = registration;
+ }
+
+ public boolean isApproval_required() {
+ return approval_required;
+ }
+
+ public void setApproval_required(boolean approval_required) {
+ this.approval_required = approval_required;
+ }
}
diff --git a/app/src/main/res/menu/main.xml b/app/src/main/res/menu/main.xml
index 027b74c0b..50a3bd3a0 100644
--- a/app/src/main/res/menu/main.xml
+++ b/app/src/main/res/menu/main.xml
@@ -9,6 +9,10 @@
android:id="@+id/action_about_instance"
android:title="@string/action_about_instance"
app:showAsAction="never" />
+
- Auto backup statuses
This option is per account. It will launch a service that will automatically store your statuses locally in the database. That allows to get statistics and charts
Report account
+ Send an invitation
+ Your instance does not allow to create an account!
- %d vote
- %d votes
@@ -1170,4 +1172,8 @@
- Webview
- Direct stream
+
+
+ For joining my instance \"%1$s\", you can download Fedilab:\n\nF-Droid: %2$s\nGoogle: %3$s\n\nThen click on the link below with Fedilab and create your account :)\n\n%4$s
+
\ No newline at end of file