mirror of https://github.com/MISP/misp-bump
parent
48674d130a
commit
be88d0e3a5
|
@ -0,0 +1,5 @@
|
||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<state>
|
||||||
|
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||||
|
</state>
|
||||||
|
</component>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="SuspiciousNameCombination" enabled="false" level="WARNING" enabled_by_default="false">
|
||||||
|
<group names="x,width,left,right" />
|
||||||
|
<group names="y,height,top,bottom" />
|
||||||
|
<ignored>
|
||||||
|
<option name="METHOD_MATCHER_CONFIG" value="java.io.PrintStream,println,java.io.PrintWriter,println,java.lang.System,identityHashCode,java.sql.PreparedStatement,set.*,java.sql.ResultSet,update.*,java.sql.SQLOutput,write.*,java.lang.Integer,compare.*,java.lang.Long,compare.*,java.lang.Short,compare,java.lang.Byte,compare,java.lang.Character,compare,java.lang.Boolean,compare,java.lang.Math,.*,java.lang.StrictMath,.*" />
|
||||||
|
</ignored>
|
||||||
|
</inspection_tool>
|
||||||
|
</profile>
|
||||||
|
</component>
|
|
@ -42,6 +42,9 @@ dependencies {
|
||||||
implementation 'com.journeyapps:zxing-android-embedded:3.2.0@aar'
|
implementation 'com.journeyapps:zxing-android-embedded:3.2.0@aar'
|
||||||
implementation 'com.google.zxing:core:3.4.0'
|
implementation 'com.google.zxing:core:3.4.0'
|
||||||
|
|
||||||
|
// external
|
||||||
|
implementation 'me.saket:inboxrecyclerview:1.0.0-rc1'
|
||||||
|
|
||||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
testImplementation 'junit:junit:4.12'
|
testImplementation 'junit:junit:4.12'
|
||||||
androidTestImplementation 'androidx.test:runner:1.2.0'
|
androidTestImplementation 'androidx.test:runner:1.2.0'
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
package="lu.circl.mispbump">
|
package="lu.circl.mispbump">
|
||||||
|
|
||||||
|
@ -15,13 +16,7 @@
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme"
|
android:theme="@style/AppTheme"
|
||||||
tools:ignore="GoogleAppIndexingWarning">
|
tools:ignore="GoogleAppIndexingWarning">
|
||||||
<activity android:name=".activities.UploadInformationActivity"
|
|
||||||
android:label="Sync details"/>
|
|
||||||
<activity
|
|
||||||
android:name=".activities.UploadActivity"
|
|
||||||
android:configChanges="orientation|screenSize"
|
|
||||||
android:label="Upload" />
|
|
||||||
<activity android:name=".activities.PreferenceActivity" />
|
|
||||||
<activity android:name=".activities.StartUpActivity">
|
<activity android:name=".activities.StartUpActivity">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN"/>
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
@ -29,16 +24,33 @@
|
||||||
<category android:name="android.intent.category.LAUNCHER"/>
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
|
||||||
android:name=".activities.HomeActivity"
|
|
||||||
android:label="@string/home" />
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".activities.LoginActivity"
|
android:name=".activities.LoginActivity"
|
||||||
android:label="@string/login"/>
|
android:label="@string/login"/>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".activities.HomeActivity"
|
||||||
|
android:label="@string/app_name"/>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".activities.SyncActivity"
|
android:name=".activities.SyncActivity"
|
||||||
android:configChanges="orientation|screenSize"
|
android:configChanges="orientation|screenSize"
|
||||||
android:label="@string/sync"
|
android:parentActivityName=".activities.HomeActivity"
|
||||||
|
android:screenOrientation="portrait"
|
||||||
|
android:theme="@style/AppTheme.Translucent"/>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".activities.UploadInfoActivity"
|
||||||
|
android:parentActivityName=".activities.HomeActivity"/>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".activities.UploadActivity"
|
||||||
|
android:configChanges="orientation|screenSize"
|
||||||
|
android:label="Upload"
|
||||||
|
android:parentActivityName=".activities.HomeActivity"/>
|
||||||
|
<activity
|
||||||
|
android:name=".activities.PreferenceActivity"
|
||||||
android:parentActivityName=".activities.HomeActivity"/>
|
android:parentActivityName=".activities.HomeActivity"/>
|
||||||
<activity
|
<activity
|
||||||
android:name=".activities.ProfileActivity"
|
android:name=".activities.ProfileActivity"
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
package lu.circl.mispbump;
|
|
||||||
|
|
||||||
import android.animation.Animator;
|
|
||||||
import android.animation.ValueAnimator;
|
|
||||||
import android.transition.Transition;
|
|
||||||
import android.transition.TransitionValues;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
|
|
||||||
public class RecyclerViewItemTransition extends Transition {
|
|
||||||
|
|
||||||
private static final String PROPNAME_ELEVATION = "customtransition:change_elevation:toolbar";
|
|
||||||
|
|
||||||
private void captureTransitionValues(TransitionValues transitionValues) {
|
|
||||||
transitionValues.values.put(PROPNAME_ELEVATION, transitionValues.view.getElevation());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void captureStartValues(@NonNull TransitionValues transitionValues) {
|
|
||||||
captureTransitionValues(transitionValues);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void captureEndValues(@NonNull TransitionValues transitionValues) {
|
|
||||||
captureTransitionValues(transitionValues);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues, TransitionValues endValues) {
|
|
||||||
if (null == startValues || null == endValues) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final View view = endValues.view;
|
|
||||||
|
|
||||||
int startElevation = 0;
|
|
||||||
int endElevation = 6;
|
|
||||||
|
|
||||||
ValueAnimator anim = ValueAnimator.ofFloat(startElevation, endElevation);
|
|
||||||
|
|
||||||
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
|
||||||
@Override
|
|
||||||
public void onAnimationUpdate(ValueAnimator animation) {
|
|
||||||
float t = (float) animation.getAnimatedValue();
|
|
||||||
view.setElevation(t);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return anim;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,12 +2,12 @@ package lu.circl.mispbump.activities;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.appcompat.app.ActionBar;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.appcompat.widget.Toolbar;
|
import androidx.appcompat.widget.Toolbar;
|
||||||
import androidx.core.app.ActivityOptionsCompat;
|
import androidx.core.app.ActivityOptionsCompat;
|
||||||
|
@ -15,7 +15,6 @@ import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
import com.google.gson.Gson;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -27,11 +26,13 @@ import lu.circl.mispbump.models.UploadInformation;
|
||||||
|
|
||||||
public class HomeActivity extends AppCompatActivity {
|
public class HomeActivity extends AppCompatActivity {
|
||||||
|
|
||||||
private View rootView;
|
public static String EXTRA_UPLOAD_INFO = "uploadInformation";
|
||||||
private PreferenceManager preferenceManager;
|
|
||||||
|
|
||||||
|
private List<UploadInformation> uploadInformationList;
|
||||||
|
private PreferenceManager preferenceManager;
|
||||||
private RecyclerView recyclerView;
|
private RecyclerView recyclerView;
|
||||||
private UploadInfoAdapter uploadInfoAdapter;
|
private UploadInfoAdapter uploadInfoAdapter;
|
||||||
|
private TextView emptyRecyclerView;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
@ -40,76 +41,10 @@ public class HomeActivity extends AppCompatActivity {
|
||||||
|
|
||||||
preferenceManager = PreferenceManager.getInstance(this);
|
preferenceManager = PreferenceManager.getInstance(this);
|
||||||
|
|
||||||
init();
|
initViews();
|
||||||
initRecyclerView();
|
initRecyclerView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void init() {
|
|
||||||
rootView = findViewById(R.id.rootLayout);
|
|
||||||
|
|
||||||
// populate Toolbar (Actionbar)
|
|
||||||
Toolbar myToolbar = findViewById(R.id.toolbar);
|
|
||||||
setSupportActionBar(myToolbar);
|
|
||||||
|
|
||||||
ActionBar ab = getSupportActionBar();
|
|
||||||
if (ab != null) {
|
|
||||||
ab.setDisplayHomeAsUpEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
FloatingActionButton sync_fab = findViewById(R.id.home_fab);
|
|
||||||
sync_fab.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
startActivity(new Intent(HomeActivity.this, SyncActivity.class));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initRecyclerView() {
|
|
||||||
recyclerView = findViewById(R.id.recyclerView);
|
|
||||||
recyclerView.setLayoutManager(new LinearLayoutManager(HomeActivity.this));
|
|
||||||
|
|
||||||
uploadInfoAdapter = new UploadInfoAdapter(HomeActivity.this);
|
|
||||||
|
|
||||||
uploadInfoAdapter.setOnRecyclerItemClickListener(new OnRecyclerItemClickListener<UploadInformation>() {
|
|
||||||
@Override
|
|
||||||
public void onClick(final View v, UploadInformation item) {
|
|
||||||
Intent i = new Intent(HomeActivity.this, UploadInformationActivity.class);
|
|
||||||
i.putExtra(UploadInformationActivity.EXTRA_UPLOAD_INFO_KEY, new Gson().toJson(item));
|
|
||||||
|
|
||||||
ActivityOptionsCompat options = ActivityOptionsCompat.makeClipRevealAnimation(v.findViewById(R.id.rootLayout), (int) v.getX(), (int) v.getY(), v.getWidth(), v.getHeight());
|
|
||||||
startActivity(i, options.toBundle());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
recyclerView.setAdapter(uploadInfoAdapter);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void refreshRecyclerView() {
|
|
||||||
List<UploadInformation> uploadInformationList = preferenceManager.getUploadInformation();
|
|
||||||
TextView empty = findViewById(R.id.empty);
|
|
||||||
|
|
||||||
// no sync information available
|
|
||||||
if (uploadInformationList == null) {
|
|
||||||
empty.setVisibility(View.VISIBLE);
|
|
||||||
recyclerView.setVisibility(View.GONE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// sync information available
|
|
||||||
empty.setVisibility(View.GONE);
|
|
||||||
recyclerView.setVisibility(View.VISIBLE);
|
|
||||||
uploadInfoAdapter.setItems(uploadInformationList);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
refreshRecyclerView();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
getMenuInflater().inflate(R.menu.main_menu, menu);
|
getMenuInflater().inflate(R.menu.main_menu, menu);
|
||||||
|
@ -131,4 +66,63 @@ public class HomeActivity extends AppCompatActivity {
|
||||||
// invoke superclass to handle unrecognized item (eg. homeAsUp)
|
// invoke superclass to handle unrecognized item (eg. homeAsUp)
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
Log.d("DEBUG", "onResume()");
|
||||||
|
|
||||||
|
refreshRecyclerView();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void initViews() {
|
||||||
|
emptyRecyclerView = findViewById(R.id.empty);
|
||||||
|
|
||||||
|
Toolbar myToolbar = findViewById(R.id.toolbar);
|
||||||
|
setSupportActionBar(myToolbar);
|
||||||
|
|
||||||
|
FloatingActionButton syncFab = findViewById(R.id.home_fab);
|
||||||
|
syncFab.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
startActivity(new Intent(HomeActivity.this, SyncActivity.class));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initRecyclerView() {
|
||||||
|
recyclerView = findViewById(R.id.recyclerView);
|
||||||
|
recyclerView.setLayoutManager(new LinearLayoutManager(HomeActivity.this));
|
||||||
|
uploadInfoAdapter = new UploadInfoAdapter(HomeActivity.this);
|
||||||
|
uploadInfoAdapter.setOnRecyclerPositionClickListener(onRecyclerItemClickListener());
|
||||||
|
recyclerView.setAdapter(uploadInfoAdapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshRecyclerView() {
|
||||||
|
uploadInformationList = preferenceManager.getUploadInformationList();
|
||||||
|
|
||||||
|
if (uploadInformationList.isEmpty()) {
|
||||||
|
emptyRecyclerView.setVisibility(View.VISIBLE);
|
||||||
|
recyclerView.setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
emptyRecyclerView.setVisibility(View.GONE);
|
||||||
|
recyclerView.setVisibility(View.VISIBLE);
|
||||||
|
uploadInfoAdapter.setItems(uploadInformationList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private OnRecyclerItemClickListener<Integer> onRecyclerItemClickListener() {
|
||||||
|
return new OnRecyclerItemClickListener<Integer>() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v, Integer index) {
|
||||||
|
Intent i = new Intent(HomeActivity.this, UploadInfoActivity.class);
|
||||||
|
i.putExtra(UploadInfoActivity.EXTRA_UPLOAD_INFO_UUID, uploadInformationList.get(index).getUuid());
|
||||||
|
|
||||||
|
ActivityOptionsCompat options = ActivityOptionsCompat.makeClipRevealAnimation(v.findViewById(R.id.rootLayout), (int) v.getX(), (int) v.getY(), v.getWidth(), v.getHeight());
|
||||||
|
startActivity(i, options.toBundle());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,10 @@ import androidx.appcompat.app.AppCompatActivity;
|
||||||
import lu.circl.mispbump.auxiliary.PreferenceManager;
|
import lu.circl.mispbump.auxiliary.PreferenceManager;
|
||||||
import lu.circl.mispbump.models.restModels.User;
|
import lu.circl.mispbump.models.restModels.User;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This activity navigates to the next activity base on the user status.
|
||||||
|
* This is the first activity that gets loaded when the user starts the app.
|
||||||
|
*/
|
||||||
public class StartUpActivity extends AppCompatActivity {
|
public class StartUpActivity extends AppCompatActivity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
package lu.circl.mispbump.activities;
|
package lu.circl.mispbump.activities;
|
||||||
|
|
||||||
import android.animation.Animator;
|
|
||||||
import android.animation.AnimatorListenerAdapter;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.res.ColorStateList;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.animation.AccelerateInterpolator;
|
import android.widget.FrameLayout;
|
||||||
import android.view.animation.BounceInterpolator;
|
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
@ -17,7 +15,6 @@ import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
import androidx.fragment.app.FragmentTransaction;
|
import androidx.fragment.app.FragmentTransaction;
|
||||||
|
|
||||||
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
|
||||||
import com.google.android.material.snackbar.Snackbar;
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.JsonSyntaxException;
|
import com.google.gson.JsonSyntaxException;
|
||||||
|
@ -25,309 +22,308 @@ import com.google.gson.JsonSyntaxException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
import java.security.spec.InvalidKeySpecException;
|
import java.security.spec.InvalidKeySpecException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import lu.circl.mispbump.R;
|
import lu.circl.mispbump.R;
|
||||||
|
import lu.circl.mispbump.auxiliary.DialogManager;
|
||||||
import lu.circl.mispbump.auxiliary.PreferenceManager;
|
import lu.circl.mispbump.auxiliary.PreferenceManager;
|
||||||
import lu.circl.mispbump.auxiliary.QrCodeGenerator;
|
import lu.circl.mispbump.auxiliary.QrCodeGenerator;
|
||||||
import lu.circl.mispbump.auxiliary.RandomString;
|
import lu.circl.mispbump.auxiliary.RandomString;
|
||||||
import lu.circl.mispbump.fragments.CameraFragment;
|
import lu.circl.mispbump.fragments.CameraFragment;
|
||||||
import lu.circl.mispbump.customViews.ExtendedBottomSheetBehavior;
|
import lu.circl.mispbump.fragments.UploadSettingsFragment;
|
||||||
import lu.circl.mispbump.fragments.SyncOptionsFragment;
|
|
||||||
import lu.circl.mispbump.models.SyncInformation;
|
import lu.circl.mispbump.models.SyncInformation;
|
||||||
import lu.circl.mispbump.models.UploadInformation;
|
import lu.circl.mispbump.models.UploadInformation;
|
||||||
import lu.circl.mispbump.security.DiffieHellman;
|
import lu.circl.mispbump.security.DiffieHellman;
|
||||||
|
|
||||||
/**
|
|
||||||
* This class provides the sync functionality.
|
|
||||||
* It collects the necessary information, guides through the process and finally completes with
|
|
||||||
* the upload to the misp instance.
|
|
||||||
*/
|
|
||||||
public class SyncActivity extends AppCompatActivity {
|
public class SyncActivity extends AppCompatActivity {
|
||||||
|
|
||||||
// rootLayout
|
enum SyncState {
|
||||||
private CoordinatorLayout rootLayout;
|
PUBLIC_KEY,
|
||||||
private ImageView qrCodeView, bottomSheetIcon;
|
DATA
|
||||||
private TextView bottomSheetText;
|
}
|
||||||
private ImageButton prevButton, nextButton;
|
|
||||||
private ExtendedBottomSheetBehavior bottomSheetBehavior;
|
enum UiState {
|
||||||
|
PUBLIC_KEY_SHOW,
|
||||||
|
PUBLIC_KEY_SHOW_AND_RECEIVED,
|
||||||
|
SYNC_INFO_SHOW,
|
||||||
|
SYNC_INFO_SHOW_AND_RECEIVED
|
||||||
|
}
|
||||||
|
|
||||||
|
private SyncState currentSyncState;
|
||||||
|
|
||||||
// dependencies
|
|
||||||
private PreferenceManager preferenceManager;
|
private PreferenceManager preferenceManager;
|
||||||
|
private UploadInformation uploadInformation;
|
||||||
|
private QrCodeGenerator qrCodeGenerator;
|
||||||
private DiffieHellman diffieHellman;
|
private DiffieHellman diffieHellman;
|
||||||
|
|
||||||
private UploadInformation uploadInformation;
|
private boolean foreignPublicKeyReceived, foreignSyncInfoReceived;
|
||||||
|
|
||||||
// fragments
|
// Fragments
|
||||||
private CameraFragment cameraFragment;
|
private CameraFragment cameraFragment;
|
||||||
private SyncOptionsFragment syncOptionsFragment;
|
|
||||||
|
|
||||||
// qr codes
|
// Views
|
||||||
private QrCodeGenerator qrCodeGenerator;
|
private CoordinatorLayout rootLayout;
|
||||||
private Bitmap publicKeyQr, syncInfoQr;
|
private FrameLayout qrFrame;
|
||||||
|
private ImageView qrCode;
|
||||||
|
private TextView qrHint;
|
||||||
|
private ImageButton prevButton, nextButton;
|
||||||
|
|
||||||
private SyncState currentSyncState = SyncState.settings;
|
private Bitmap publicKeyQrCode, syncInfoQrCode;
|
||||||
|
|
||||||
private enum SyncState {
|
|
||||||
settings(0),
|
|
||||||
publicKeyExchange(1),
|
|
||||||
dataExchange(2);
|
|
||||||
|
|
||||||
|
|
||||||
private final int value;
|
|
||||||
|
|
||||||
SyncState(final int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_sync);
|
setContentView(R.layout.activity_sync);
|
||||||
initializeViews();
|
|
||||||
|
init();
|
||||||
|
initViews();
|
||||||
|
|
||||||
|
switchState(SyncState.PUBLIC_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeViews() {
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
super.onBackPressed();
|
||||||
|
|
||||||
|
switch (currentSyncState) {
|
||||||
|
case PUBLIC_KEY:
|
||||||
|
// TODO warn that sync is maybe not complete ... ?
|
||||||
|
break;
|
||||||
|
case DATA:
|
||||||
|
switchState(SyncState.PUBLIC_KEY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
preferenceManager = PreferenceManager.getInstance(SyncActivity.this);
|
||||||
|
diffieHellman = DiffieHellman.getInstance();
|
||||||
|
|
||||||
|
qrCodeGenerator = new QrCodeGenerator(SyncActivity.this);
|
||||||
|
publicKeyQrCode = qrCodeGenerator.generateQrCode(DiffieHellman.publicKeyToString(diffieHellman.getPublicKey()));
|
||||||
|
|
||||||
|
uploadInformation = new UploadInformation();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initViews() {
|
||||||
rootLayout = findViewById(R.id.rootLayout);
|
rootLayout = findViewById(R.id.rootLayout);
|
||||||
|
|
||||||
// prev button
|
qrFrame = findViewById(R.id.qrFrame);
|
||||||
|
qrCode = findViewById(R.id.qrCode);
|
||||||
|
qrHint = findViewById(R.id.qrHint);
|
||||||
|
|
||||||
prevButton = findViewById(R.id.prevButton);
|
prevButton = findViewById(R.id.prevButton);
|
||||||
prevButton.setOnClickListener(onPrevClicked);
|
prevButton.setOnClickListener(onPrevClicked);
|
||||||
|
|
||||||
// next button
|
|
||||||
nextButton = findViewById(R.id.nextButton);
|
nextButton = findViewById(R.id.nextButton);
|
||||||
nextButton.setOnClickListener(onNextClicked);
|
nextButton.setOnClickListener(onNextClicked);
|
||||||
|
|
||||||
// QR Code View
|
|
||||||
qrCodeView = findViewById(R.id.qrcode);
|
|
||||||
qrCodeGenerator = new QrCodeGenerator(SyncActivity.this);
|
|
||||||
|
|
||||||
bottomSheetIcon = findViewById(R.id.bottomSheetIcon);
|
|
||||||
bottomSheetText = findViewById(R.id.bottomSheetText);
|
|
||||||
|
|
||||||
diffieHellman = DiffieHellman.getInstance();
|
|
||||||
preferenceManager = PreferenceManager.getInstance(this);
|
|
||||||
|
|
||||||
View bottomSheet = findViewById(R.id.bottomSheet);
|
|
||||||
bottomSheetBehavior = (ExtendedBottomSheetBehavior) BottomSheetBehavior.from(bottomSheet);
|
|
||||||
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
|
|
||||||
bottomSheetBehavior.setSwipeable(false);
|
|
||||||
bottomSheetBehavior.setHideable(false);
|
|
||||||
|
|
||||||
publicKeyQr = generatePublicKeyQr();
|
|
||||||
|
|
||||||
switchState(SyncState.settings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void switchState(SyncState state) {
|
||||||
* Called when "next button" is pressed
|
switchFragment(state);
|
||||||
*/
|
displayQr(state);
|
||||||
private View.OnClickListener onNextClicked = new View.OnClickListener() {
|
|
||||||
|
switch (state) {
|
||||||
|
case PUBLIC_KEY:
|
||||||
|
if (foreignPublicKeyReceived) {
|
||||||
|
switchUiState(UiState.PUBLIC_KEY_SHOW_AND_RECEIVED);
|
||||||
|
cameraFragment.setReadQrEnabled(false);
|
||||||
|
} else {
|
||||||
|
switchUiState(UiState.PUBLIC_KEY_SHOW);
|
||||||
|
cameraFragment.setReadQrEnabled(true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DATA:
|
||||||
|
if (foreignSyncInfoReceived) {
|
||||||
|
switchUiState(UiState.SYNC_INFO_SHOW_AND_RECEIVED);
|
||||||
|
cameraFragment.setReadQrEnabled(false);
|
||||||
|
} else {
|
||||||
|
switchUiState(UiState.SYNC_INFO_SHOW);
|
||||||
|
cameraFragment.setReadQrEnabled(true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentSyncState = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void switchFragment(SyncState state) {
|
||||||
|
FragmentManager fragmentManager = getSupportFragmentManager();
|
||||||
|
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
|
||||||
|
|
||||||
|
String camTag = CameraFragment.class.getSimpleName();
|
||||||
|
String settingsTag = UploadSettingsFragment.class.getSimpleName();
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case PUBLIC_KEY:
|
||||||
|
case DATA:
|
||||||
|
cameraFragment = (CameraFragment) fragmentManager.findFragmentByTag(camTag);
|
||||||
|
if (cameraFragment != null) {
|
||||||
|
fragmentTransaction.show(cameraFragment);
|
||||||
|
} else {
|
||||||
|
cameraFragment = new CameraFragment();
|
||||||
|
cameraFragment.setOnQrAvailableListener(onReadQrCode);
|
||||||
|
fragmentTransaction.add(R.id.fragmentContainer, cameraFragment, camTag);
|
||||||
|
}
|
||||||
|
|
||||||
|
UploadSettingsFragment uploadSettingsFragment = (UploadSettingsFragment) fragmentManager.findFragmentByTag(settingsTag);
|
||||||
|
if (uploadSettingsFragment != null) {
|
||||||
|
fragmentTransaction.hide(uploadSettingsFragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
fragmentTransaction.commit();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void displayQr(SyncState state) {
|
||||||
|
switch (state) {
|
||||||
|
case PUBLIC_KEY:
|
||||||
|
qrCode.setImageBitmap(publicKeyQrCode);
|
||||||
|
qrFrame.setVisibility(View.VISIBLE);
|
||||||
|
break;
|
||||||
|
case DATA:
|
||||||
|
qrCode.setImageBitmap(syncInfoQrCode);
|
||||||
|
qrFrame.setVisibility(View.VISIBLE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void switchUiState(final UiState state) {
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void run() {
|
||||||
switch (currentSyncState) {
|
switch (state) {
|
||||||
case settings:
|
case PUBLIC_KEY_SHOW:
|
||||||
uploadInformation = new UploadInformation();
|
prevButton.setImageDrawable(getDrawable(R.drawable.ic_close));
|
||||||
uploadInformation.setAllowSelfSigned(syncOptionsFragment.getAllowSelfSigned());
|
prevButton.setVisibility(View.VISIBLE);
|
||||||
uploadInformation.setPush(syncOptionsFragment.getPush());
|
nextButton.setVisibility(View.INVISIBLE);
|
||||||
uploadInformation.setPull(syncOptionsFragment.getPull());
|
qrReceivedFeedback(false);
|
||||||
uploadInformation.setCached(syncOptionsFragment.getCache());
|
|
||||||
|
|
||||||
switchState(SyncState.publicKeyExchange);
|
|
||||||
break;
|
break;
|
||||||
|
case PUBLIC_KEY_SHOW_AND_RECEIVED:
|
||||||
case publicKeyExchange:
|
prevButton.setImageDrawable(getDrawable(R.drawable.ic_close));
|
||||||
switchState(SyncState.dataExchange);
|
nextButton.setImageDrawable(getDrawable(R.drawable.ic_arrow_forward));
|
||||||
|
prevButton.setVisibility(View.VISIBLE);
|
||||||
|
nextButton.setVisibility(View.VISIBLE);
|
||||||
|
cameraFragment.disablePreview();
|
||||||
|
qrReceivedFeedback(true);
|
||||||
break;
|
break;
|
||||||
|
case SYNC_INFO_SHOW:
|
||||||
case dataExchange:
|
prevButton.setImageDrawable(getDrawable(R.drawable.ic_arrow_back));
|
||||||
Intent upload = new Intent(SyncActivity.this, UploadActivity.class);
|
nextButton.setImageDrawable(getDrawable(R.drawable.ic_arrow_forward));
|
||||||
upload.putExtra(UploadActivity.EXTRA_UPLOAD_INFO, new Gson().toJson(uploadInformation));
|
nextButton.setVisibility(View.INVISIBLE);
|
||||||
startActivity(upload);
|
prevButton.setVisibility(View.VISIBLE);
|
||||||
overridePendingTransition(R.anim.slide_in_right, android.R.anim.slide_out_right);
|
cameraFragment.enablePreview();
|
||||||
finish();
|
qrReceivedFeedback(false);
|
||||||
|
break;
|
||||||
|
case SYNC_INFO_SHOW_AND_RECEIVED:
|
||||||
|
prevButton.setImageDrawable(getDrawable(R.drawable.ic_arrow_back));
|
||||||
|
nextButton.setImageDrawable(getDrawable(R.drawable.ic_check));
|
||||||
|
nextButton.setVisibility(View.VISIBLE);
|
||||||
|
prevButton.setVisibility(View.VISIBLE);
|
||||||
|
cameraFragment.disablePreview();
|
||||||
|
qrReceivedFeedback(true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// listener
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when "prev button" is clicked
|
|
||||||
*/
|
|
||||||
private View.OnClickListener onPrevClicked = new View.OnClickListener() {
|
private View.OnClickListener onPrevClicked = new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
switch (currentSyncState) {
|
switch (currentSyncState) {
|
||||||
case settings:
|
case PUBLIC_KEY:
|
||||||
finish();
|
finish();
|
||||||
break;
|
break;
|
||||||
|
case DATA:
|
||||||
case publicKeyExchange:
|
switchState(SyncState.PUBLIC_KEY);
|
||||||
switchState(SyncState.settings);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case dataExchange:
|
|
||||||
switchState(SyncState.publicKeyExchange);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
private View.OnClickListener onNextClicked = new View.OnClickListener() {
|
||||||
* Called when the camera fragment detects a qr code
|
@Override
|
||||||
*/
|
public void onClick(View v) {
|
||||||
private CameraFragment.QrScanCallback onQrCodeScanned = new CameraFragment.QrScanCallback() {
|
switch (currentSyncState) {
|
||||||
|
case PUBLIC_KEY:
|
||||||
|
switchState(SyncState.DATA);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DATA:
|
||||||
|
uploadInformation.setCurrentSyncStatus(UploadInformation.SyncStatus.PENDING);
|
||||||
|
preferenceManager.addUploadInformation(uploadInformation);
|
||||||
|
|
||||||
|
Intent i = new Intent(SyncActivity.this, UploadInfoActivity.class);
|
||||||
|
i.putExtra(UploadInfoActivity.EXTRA_UPLOAD_INFO_UUID, uploadInformation.getUuid());
|
||||||
|
startActivity(i);
|
||||||
|
finish();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private CameraFragment.QrScanCallback onReadQrCode = new CameraFragment.QrScanCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void qrScanResult(String qrData) {
|
public void qrScanResult(String qrData) {
|
||||||
cameraFragment.setReadQrEnabled(false);
|
cameraFragment.setReadQrEnabled(false);
|
||||||
switch (currentSyncState) {
|
switch (currentSyncState) {
|
||||||
case publicKeyExchange:
|
case PUBLIC_KEY:
|
||||||
try {
|
try {
|
||||||
final PublicKey pk = DiffieHellman.publicKeyFromString(qrData);
|
final PublicKey pk = DiffieHellman.publicKeyFromString(qrData);
|
||||||
diffieHellman.setForeignPublicKey(pk);
|
diffieHellman.setForeignPublicKey(pk);
|
||||||
|
syncInfoQrCode = generateSyncInfoQr();
|
||||||
syncInfoQr = generateSyncInfoQr();
|
switchUiState(UiState.PUBLIC_KEY_SHOW_AND_RECEIVED);
|
||||||
|
foreignPublicKeyReceived = true;
|
||||||
runOnUiThread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
nextButton.setVisibility(View.VISIBLE);
|
|
||||||
cameraFragment.disablePreview();
|
|
||||||
qrReceivedFeedback();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
|
} catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
|
||||||
Snackbar.make(rootLayout, "Invalid key", Snackbar.LENGTH_SHORT).show();
|
Snackbar.make(rootLayout, "Invalid key", Snackbar.LENGTH_SHORT).show();
|
||||||
cameraFragment.setReadQrEnabled(true);
|
switchUiState(UiState.PUBLIC_KEY_SHOW);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case dataExchange:
|
case DATA:
|
||||||
cameraFragment.setReadQrEnabled(false);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final SyncInformation remoteSyncInfo = new Gson().fromJson(diffieHellman.decrypt(qrData), SyncInformation.class);
|
final SyncInformation remoteSyncInfo = new Gson().fromJson(diffieHellman.decrypt(qrData), SyncInformation.class);
|
||||||
uploadInformation.setRemote(remoteSyncInfo);
|
|
||||||
|
|
||||||
runOnUiThread(new Runnable() {
|
List<UploadInformation> uploadInformationList = preferenceManager.getUploadInformationList();
|
||||||
|
|
||||||
|
if (uploadInformationList != null) {
|
||||||
|
for (final UploadInformation ui : uploadInformationList) {
|
||||||
|
if (ui.getRemote().organisation.uuid.equals(remoteSyncInfo.organisation.uuid)) {
|
||||||
|
DialogManager.syncAlreadyExistsDialog(SyncActivity.this, new DialogManager.IDialogFeedback() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void positive() {
|
||||||
cameraFragment.disablePreview();
|
uploadInformation.setUuid(ui.getUuid());
|
||||||
nextButton.setVisibility(View.VISIBLE);
|
}
|
||||||
qrReceivedFeedback();
|
|
||||||
|
@Override
|
||||||
|
public void negative() {
|
||||||
|
finish();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uploadInformation.setRemote(remoteSyncInfo);
|
||||||
|
switchUiState(UiState.SYNC_INFO_SHOW_AND_RECEIVED);
|
||||||
|
foreignSyncInfoReceived = true;
|
||||||
} catch (JsonSyntaxException e) {
|
} catch (JsonSyntaxException e) {
|
||||||
Snackbar.make(rootLayout, "Sync information unreadable", Snackbar.LENGTH_SHORT).show();
|
Snackbar.make(rootLayout, "Sync information unreadable", Snackbar.LENGTH_SHORT).show();
|
||||||
cameraFragment.setReadQrEnabled(true);
|
switchUiState(UiState.SYNC_INFO_SHOW);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// aux
|
||||||
|
|
||||||
private void switchUiState(SyncState state) {
|
private SyncInformation generateLocalSyncInfo() {
|
||||||
|
|
||||||
bottomSheetIcon.setVisibility(View.INVISIBLE);
|
|
||||||
bottomSheetBehavior.setSwipeable(false);
|
|
||||||
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
|
|
||||||
|
|
||||||
switch (state) {
|
|
||||||
case settings:
|
|
||||||
prevButton.setImageDrawable(getDrawable(R.drawable.ic_close));
|
|
||||||
prevButton.setVisibility(View.VISIBLE);
|
|
||||||
nextButton.setVisibility(View.VISIBLE);
|
|
||||||
hideQrCode();
|
|
||||||
break;
|
|
||||||
case publicKeyExchange:
|
|
||||||
prevButton.setImageDrawable(getDrawable(R.drawable.ic_arrow_back));
|
|
||||||
prevButton.setVisibility(View.VISIBLE);
|
|
||||||
|
|
||||||
nextButton.setImageDrawable(getDrawable(R.drawable.ic_arrow_forward));
|
|
||||||
nextButton.setVisibility(View.GONE);
|
|
||||||
showQrCode(publicKeyQr);
|
|
||||||
break;
|
|
||||||
case dataExchange:
|
|
||||||
prevButton.setImageDrawable(getDrawable(R.drawable.ic_arrow_back));
|
|
||||||
prevButton.setVisibility(View.VISIBLE);
|
|
||||||
|
|
||||||
nextButton.setImageDrawable(getDrawable(R.drawable.ic_cloud_upload));
|
|
||||||
nextButton.setVisibility(View.GONE);
|
|
||||||
|
|
||||||
cameraFragment.enablePreview();
|
|
||||||
cameraFragment.setReadQrEnabled(true);
|
|
||||||
showQrCode(syncInfoQr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void switchState(SyncState state) {
|
|
||||||
|
|
||||||
FragmentManager fragmentManager = getSupportFragmentManager();
|
|
||||||
FragmentTransaction transaction = fragmentManager.beginTransaction();
|
|
||||||
|
|
||||||
if (currentSyncState != state) {
|
|
||||||
if (state.value < currentSyncState.value) {
|
|
||||||
transaction.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
|
|
||||||
} else {
|
|
||||||
transaction.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
currentSyncState = state;
|
|
||||||
|
|
||||||
switchUiState(currentSyncState);
|
|
||||||
|
|
||||||
switch (currentSyncState) {
|
|
||||||
case settings:
|
|
||||||
String fragTag = SyncOptionsFragment.class.getSimpleName();
|
|
||||||
syncOptionsFragment = (SyncOptionsFragment) fragmentManager.findFragmentByTag(fragTag);
|
|
||||||
|
|
||||||
if (syncOptionsFragment == null) {
|
|
||||||
syncOptionsFragment = new SyncOptionsFragment();
|
|
||||||
}
|
|
||||||
|
|
||||||
transaction.replace(R.id.sync_fragment_container, syncOptionsFragment, fragTag);
|
|
||||||
transaction.commit();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case publicKeyExchange:
|
|
||||||
fragTag = CameraFragment.class.getSimpleName();
|
|
||||||
cameraFragment = (CameraFragment) fragmentManager.findFragmentByTag(fragTag);
|
|
||||||
|
|
||||||
if (cameraFragment == null) {
|
|
||||||
cameraFragment = new CameraFragment();
|
|
||||||
cameraFragment.setOnQrAvailableListener(onQrCodeScanned);
|
|
||||||
}
|
|
||||||
|
|
||||||
transaction.replace(R.id.sync_fragment_container, cameraFragment, fragTag);
|
|
||||||
transaction.commit();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case dataExchange:
|
|
||||||
fragTag = CameraFragment.class.getSimpleName();
|
|
||||||
cameraFragment = (CameraFragment) fragmentManager.findFragmentByTag(fragTag);
|
|
||||||
|
|
||||||
if (cameraFragment == null) {
|
|
||||||
cameraFragment = new CameraFragment();
|
|
||||||
cameraFragment.setOnQrAvailableListener(onQrCodeScanned);
|
|
||||||
}
|
|
||||||
|
|
||||||
transaction.replace(R.id.sync_fragment_container, cameraFragment, fragTag);
|
|
||||||
transaction.commit();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private Bitmap generatePublicKeyQr() {
|
|
||||||
return qrCodeGenerator.generateQrCode(DiffieHellman.publicKeyToString(diffieHellman.getPublicKey()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private Bitmap generateSyncInfoQr() {
|
|
||||||
SyncInformation syncInformation = new SyncInformation();
|
SyncInformation syncInformation = new SyncInformation();
|
||||||
syncInformation.organisation = preferenceManager.getUserOrganisation().toSyncOrganisation();
|
syncInformation.organisation = preferenceManager.getUserOrganisation().toSyncOrganisation();
|
||||||
syncInformation.syncUserAuthkey = new RandomString(40).nextString();
|
syncInformation.syncUserAuthkey = new RandomString(40).nextString();
|
||||||
|
@ -335,6 +331,12 @@ public class SyncActivity extends AppCompatActivity {
|
||||||
syncInformation.syncUserPassword = new RandomString(16).nextString();
|
syncInformation.syncUserPassword = new RandomString(16).nextString();
|
||||||
syncInformation.syncUserEmail = preferenceManager.getUserInfo().email;
|
syncInformation.syncUserEmail = preferenceManager.getUserInfo().email;
|
||||||
|
|
||||||
|
return syncInformation;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Bitmap generateSyncInfoQr() {
|
||||||
|
SyncInformation syncInformation = generateLocalSyncInfo();
|
||||||
|
|
||||||
uploadInformation.setLocal(syncInformation);
|
uploadInformation.setLocal(syncInformation);
|
||||||
|
|
||||||
// encrypt serialized content
|
// encrypt serialized content
|
||||||
|
@ -344,80 +346,18 @@ public class SyncActivity extends AppCompatActivity {
|
||||||
return qrCodeGenerator.generateQrCode(encrypted);
|
return qrCodeGenerator.generateQrCode(encrypted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void qrReceivedFeedback(final boolean done) {
|
||||||
private void showQrCode(final Bitmap bitmap) {
|
|
||||||
runOnUiThread(new Runnable() {
|
runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
if (done) {
|
||||||
qrCodeView.setImageBitmap(bitmap);
|
qrHint.setCompoundDrawablesWithIntrinsicBounds(getDrawable(R.drawable.ic_check_outline), null, null, null);
|
||||||
qrCodeView.setAlpha(0f);
|
qrHint.setCompoundDrawableTintList(ColorStateList.valueOf(getColor(R.color.status_green)));
|
||||||
qrCodeView.setVisibility(View.VISIBLE);
|
} else {
|
||||||
qrCodeView.setScaleX(0.9f);
|
qrHint.setCompoundDrawablesWithIntrinsicBounds(getDrawable(R.drawable.ic_info_outline), null, null, null);
|
||||||
qrCodeView.setScaleY(0.6f);
|
qrHint.setCompoundDrawableTintList(ColorStateList.valueOf(getColor(R.color.status_amber)));
|
||||||
qrCodeView.animate()
|
}
|
||||||
.scaleX(1f)
|
|
||||||
.scaleY(1f)
|
|
||||||
.alpha(1f)
|
|
||||||
.setDuration(250)
|
|
||||||
.setListener(new AnimatorListenerAdapter() {
|
|
||||||
@Override
|
|
||||||
public void onAnimationEnd(Animator animation) {
|
|
||||||
qrCodeView.setVisibility(View.VISIBLE);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void hideQrCode() {
|
|
||||||
|
|
||||||
if (qrCodeView.getVisibility() == View.GONE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
runOnUiThread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
qrCodeView.setAlpha(1f);
|
|
||||||
qrCodeView.setVisibility(View.VISIBLE);
|
|
||||||
qrCodeView.setScaleX(1f);
|
|
||||||
qrCodeView.setScaleY(1f);
|
|
||||||
qrCodeView.animate()
|
|
||||||
.scaleX(0f)
|
|
||||||
.scaleY(0f)
|
|
||||||
.alpha(0f)
|
|
||||||
.setDuration(250)
|
|
||||||
.setListener(new AnimatorListenerAdapter() {
|
|
||||||
@Override
|
|
||||||
public void onAnimationEnd(Animator animation) {
|
|
||||||
qrCodeView.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void qrReceivedFeedback() {
|
|
||||||
bottomSheetIcon.setScaleX(0f);
|
|
||||||
bottomSheetIcon.setScaleY(0f);
|
|
||||||
bottomSheetIcon.setVisibility(View.VISIBLE);
|
|
||||||
bottomSheetIcon.animate()
|
|
||||||
.scaleY(1f)
|
|
||||||
.scaleX(1f)
|
|
||||||
.setDuration(500);
|
|
||||||
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
|
|
||||||
bottomSheetBehavior.setSwipeable(true);
|
|
||||||
|
|
||||||
switch (currentSyncState) {
|
|
||||||
case publicKeyExchange:
|
|
||||||
bottomSheetText.setText("Received public key from partner");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case dataExchange:
|
|
||||||
bottomSheetText.setText("Received sync information from partner");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package lu.circl.mispbump.activities;
|
package lu.circl.mispbump.activities;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
@ -9,9 +10,7 @@ import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.appcompat.widget.Toolbar;
|
import androidx.appcompat.widget.Toolbar;
|
||||||
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
||||||
|
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
|
||||||
import com.google.android.material.snackbar.Snackbar;
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
import com.google.gson.Gson;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -29,34 +28,67 @@ import lu.circl.mispbump.models.restModels.User;
|
||||||
|
|
||||||
public class UploadActivity extends AppCompatActivity {
|
public class UploadActivity extends AppCompatActivity {
|
||||||
|
|
||||||
public static final String EXTRA_UPLOAD_INFO = "uploadInformation";
|
public static String EXTRA_UPLOAD_INFO = "uploadInformation";
|
||||||
|
|
||||||
private PreferenceManager preferenceManager;
|
private PreferenceManager preferenceManager;
|
||||||
private MispRestClient restClient;
|
|
||||||
private UploadInformation uploadInformation;
|
private UploadInformation uploadInformation;
|
||||||
|
|
||||||
private CoordinatorLayout rootLayout;
|
private CoordinatorLayout rootLayout;
|
||||||
|
private MispRestClient restClient;
|
||||||
private UploadAction availableAction, orgAction, userAction, serverAction;
|
private UploadAction availableAction, orgAction, userAction, serverAction;
|
||||||
|
|
||||||
|
private boolean errorWhileUpload;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_upload);
|
setContentView(R.layout.activity_upload);
|
||||||
|
|
||||||
|
preferenceManager = PreferenceManager.getInstance(UploadActivity.this);
|
||||||
|
restClient = MispRestClient.getInstance(this);
|
||||||
|
|
||||||
parseExtra();
|
parseExtra();
|
||||||
init();
|
initViews();
|
||||||
|
startUpload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
|
||||||
|
if (item.getItemId() == android.R.id.home) {
|
||||||
|
saveCurrentState();
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
super.onBackPressed();
|
||||||
|
saveCurrentState();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void parseExtra() {
|
private void parseExtra() {
|
||||||
String uploadInfoString = getIntent().getStringExtra(EXTRA_UPLOAD_INFO);
|
Intent i = getIntent();
|
||||||
uploadInformation = new Gson().fromJson(uploadInfoString, UploadInformation.class);
|
|
||||||
assert uploadInformation != null;
|
UUID currentUUID = (UUID) i.getSerializableExtra(EXTRA_UPLOAD_INFO);
|
||||||
|
|
||||||
|
for (UploadInformation ui : preferenceManager.getUploadInformationList()) {
|
||||||
|
if (ui.getUuid().compareTo(currentUUID) == 0) {
|
||||||
|
uploadInformation = ui;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void init() {
|
if (uploadInformation == null) {
|
||||||
restClient = MispRestClient.getInstance(this);
|
throw new RuntimeException("Could not find UploadInfo with UUID {" + currentUUID.toString() + "}");
|
||||||
preferenceManager = PreferenceManager.getInstance(this);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initViews() {
|
||||||
rootLayout = findViewById(R.id.rootLayout);
|
rootLayout = findViewById(R.id.rootLayout);
|
||||||
|
|
||||||
// toolbar
|
// toolbar
|
||||||
|
@ -68,32 +100,17 @@ public class UploadActivity extends AppCompatActivity {
|
||||||
ab.setDisplayHomeAsUpEnabled(true);
|
ab.setDisplayHomeAsUpEnabled(true);
|
||||||
ab.setHomeAsUpIndicator(R.drawable.ic_close);
|
ab.setHomeAsUpIndicator(R.drawable.ic_close);
|
||||||
|
|
||||||
// fab
|
|
||||||
FloatingActionButton fab = findViewById(R.id.fab);
|
|
||||||
fab.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
startUpload();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
availableAction = findViewById(R.id.availableAction);
|
availableAction = findViewById(R.id.availableAction);
|
||||||
orgAction = findViewById(R.id.orgAction);
|
orgAction = findViewById(R.id.orgAction);
|
||||||
userAction = findViewById(R.id.userAction);
|
userAction = findViewById(R.id.userAction);
|
||||||
serverAction = findViewById(R.id.serverAction);
|
serverAction = findViewById(R.id.serverAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void saveCurrentState() {
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
if (errorWhileUpload) {
|
||||||
switch (item.getItemId()) {
|
uploadInformation.setCurrentSyncStatus(UploadInformation.SyncStatus.FAILURE);
|
||||||
case android.R.id.home:
|
|
||||||
preferenceManager.addUploadInformation(uploadInformation);
|
|
||||||
finish();
|
|
||||||
return true;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
}
|
||||||
|
preferenceManager.addUploadInformation(uploadInformation);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -122,6 +139,7 @@ public class UploadActivity extends AppCompatActivity {
|
||||||
return syncUser;
|
return syncUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private MispRestClient.AvailableCallback availableCallback = new MispRestClient.AvailableCallback() {
|
private MispRestClient.AvailableCallback availableCallback = new MispRestClient.AvailableCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void available() {
|
public void available() {
|
||||||
|
@ -136,12 +154,15 @@ public class UploadActivity extends AppCompatActivity {
|
||||||
availableAction.setError(error);
|
availableAction.setError(error);
|
||||||
uploadInformation.setCurrentSyncStatus(UploadInformation.SyncStatus.FAILURE);
|
uploadInformation.setCurrentSyncStatus(UploadInformation.SyncStatus.FAILURE);
|
||||||
|
|
||||||
|
errorWhileUpload = true;
|
||||||
|
|
||||||
Snackbar sb = Snackbar.make(rootLayout, error, Snackbar.LENGTH_INDEFINITE);
|
Snackbar sb = Snackbar.make(rootLayout, error, Snackbar.LENGTH_INDEFINITE);
|
||||||
sb.setAction("Retry", new View.OnClickListener() {
|
sb.setAction("Retry", new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
availableAction.setError(null);
|
availableAction.setError(null);
|
||||||
availableAction.setCurrentUploadState(UploadAction.UploadState.LOADING);
|
availableAction.setCurrentUploadState(UploadAction.UploadState.LOADING);
|
||||||
|
errorWhileUpload = false;
|
||||||
startUpload();
|
startUpload();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -165,9 +186,9 @@ public class UploadActivity extends AppCompatActivity {
|
||||||
public void failure(String error) {
|
public void failure(String error) {
|
||||||
orgAction.setCurrentUploadState(UploadAction.UploadState.ERROR);
|
orgAction.setCurrentUploadState(UploadAction.UploadState.ERROR);
|
||||||
orgAction.setError(error);
|
orgAction.setError(error);
|
||||||
|
errorWhileUpload = true;
|
||||||
|
|
||||||
uploadInformation.setCurrentSyncStatus(UploadInformation.SyncStatus.FAILURE);
|
uploadInformation.setCurrentSyncStatus(UploadInformation.SyncStatus.FAILURE);
|
||||||
preferenceManager.addUploadInformation(uploadInformation);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -194,9 +215,9 @@ public class UploadActivity extends AppCompatActivity {
|
||||||
public void failure(String error) {
|
public void failure(String error) {
|
||||||
userAction.setCurrentUploadState(UploadAction.UploadState.ERROR);
|
userAction.setCurrentUploadState(UploadAction.UploadState.ERROR);
|
||||||
userAction.setError(error);
|
userAction.setError(error);
|
||||||
|
errorWhileUpload = true;
|
||||||
|
|
||||||
uploadInformation.setCurrentSyncStatus(UploadInformation.SyncStatus.FAILURE);
|
uploadInformation.setCurrentSyncStatus(UploadInformation.SyncStatus.FAILURE);
|
||||||
preferenceManager.addUploadInformation(uploadInformation);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -210,17 +231,16 @@ public class UploadActivity extends AppCompatActivity {
|
||||||
public void success(Server server) {
|
public void success(Server server) {
|
||||||
serverAction.setCurrentUploadState(UploadAction.UploadState.DONE);
|
serverAction.setCurrentUploadState(UploadAction.UploadState.DONE);
|
||||||
uploadInformation.setCurrentSyncStatus(UploadInformation.SyncStatus.COMPLETE);
|
uploadInformation.setCurrentSyncStatus(UploadInformation.SyncStatus.COMPLETE);
|
||||||
preferenceManager.addUploadInformation(uploadInformation);
|
saveCurrentState();
|
||||||
finish();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void failure(String error) {
|
public void failure(String error) {
|
||||||
serverAction.setCurrentUploadState(UploadAction.UploadState.ERROR);
|
serverAction.setCurrentUploadState(UploadAction.UploadState.ERROR);
|
||||||
serverAction.setError(error);
|
serverAction.setError(error);
|
||||||
|
errorWhileUpload = true;
|
||||||
|
|
||||||
uploadInformation.setCurrentSyncStatus(UploadInformation.SyncStatus.FAILURE);
|
uploadInformation.setCurrentSyncStatus(UploadInformation.SyncStatus.FAILURE);
|
||||||
preferenceManager.addUploadInformation(uploadInformation);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,243 @@
|
||||||
|
package lu.circl.mispbump.activities;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.res.ColorStateList;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.app.ActionBar;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
import androidx.fragment.app.FragmentPagerAdapter;
|
||||||
|
import androidx.viewpager.widget.ViewPager;
|
||||||
|
|
||||||
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
|
import com.google.android.material.tabs.TabLayout;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import lu.circl.mispbump.R;
|
||||||
|
import lu.circl.mispbump.auxiliary.PreferenceManager;
|
||||||
|
import lu.circl.mispbump.fragments.UploadInfoFragment;
|
||||||
|
import lu.circl.mispbump.fragments.UploadSettingsFragment;
|
||||||
|
import lu.circl.mispbump.models.UploadInformation;
|
||||||
|
|
||||||
|
public class UploadInfoActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
public static String EXTRA_UPLOAD_INFO_UUID = "uploadInformation";
|
||||||
|
|
||||||
|
private PreferenceManager preferenceManager;
|
||||||
|
private UploadInformation uploadInformation;
|
||||||
|
private ViewPagerAdapter viewPagerAdapter;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_upload_information_2);
|
||||||
|
|
||||||
|
preferenceManager = PreferenceManager.getInstance(UploadInfoActivity.this);
|
||||||
|
|
||||||
|
// tint statusBar
|
||||||
|
getWindow().setStatusBarColor(getColor(R.color.grey_light));
|
||||||
|
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
||||||
|
|
||||||
|
parseExtra();
|
||||||
|
initToolbar();
|
||||||
|
initViewPager();
|
||||||
|
initViews();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
getMenuInflater().inflate(R.menu.menu_upload_info, menu);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case R.id.delete:
|
||||||
|
// TODO delete
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case android.R.id.home:
|
||||||
|
saveCurrentSettings();
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
// refresh current uploadInformation
|
||||||
|
if (uploadInformation != null) {
|
||||||
|
uploadInformation = preferenceManager.getUploadInformation(uploadInformation.getUuid());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
super.onBackPressed();
|
||||||
|
saveCurrentSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void parseExtra() {
|
||||||
|
Intent i = getIntent();
|
||||||
|
|
||||||
|
UUID currentUUID = (UUID) i.getSerializableExtra(EXTRA_UPLOAD_INFO_UUID);
|
||||||
|
uploadInformation = preferenceManager.getUploadInformation(currentUUID);
|
||||||
|
|
||||||
|
if (uploadInformation == null) {
|
||||||
|
throw new RuntimeException("Could not find UploadInformation with UUID {" + currentUUID.toString() + "}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initToolbar() {
|
||||||
|
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||||
|
setSupportActionBar(toolbar);
|
||||||
|
|
||||||
|
ActionBar ab = getSupportActionBar();
|
||||||
|
assert ab != null;
|
||||||
|
|
||||||
|
|
||||||
|
TextView tv = findViewById(R.id.syncStatus);
|
||||||
|
int statusColor;
|
||||||
|
String statusText;
|
||||||
|
Drawable statusDrawable;
|
||||||
|
|
||||||
|
switch (uploadInformation.getCurrentSyncStatus()) {
|
||||||
|
case COMPLETE:
|
||||||
|
statusColor = getColor(R.color.status_green);
|
||||||
|
statusText = "Successfully uploaded";
|
||||||
|
statusDrawable = getDrawable(R.drawable.ic_check_outline);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FAILURE:
|
||||||
|
statusColor = getColor(R.color.status_red);
|
||||||
|
statusText = "Error while uploading";
|
||||||
|
statusDrawable = getDrawable(R.drawable.ic_error_outline);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PENDING:
|
||||||
|
statusColor = getColor(R.color.status_amber);
|
||||||
|
statusText = "Not uploaded yet";
|
||||||
|
statusDrawable = getDrawable(R.drawable.ic_pending);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
statusColor = getColor(R.color.status_green);
|
||||||
|
statusText = "Successfully uploaded";
|
||||||
|
statusDrawable = getDrawable(R.drawable.ic_check_outline);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
tv.setText(statusText);
|
||||||
|
tv.setTextColor(statusColor);
|
||||||
|
tv.setCompoundDrawablesWithIntrinsicBounds(null, null, statusDrawable, null);
|
||||||
|
tv.setCompoundDrawableTintList(ColorStateList.valueOf(statusColor));
|
||||||
|
|
||||||
|
ab.setTitle(uploadInformation.getRemote().organisation.name);
|
||||||
|
|
||||||
|
ab.setDisplayShowTitleEnabled(true);
|
||||||
|
ab.setDisplayShowCustomEnabled(false);
|
||||||
|
ab.setDisplayHomeAsUpEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initViewPager() {
|
||||||
|
ViewPager viewPager = findViewById(R.id.viewPager);
|
||||||
|
TabLayout tabLayout = findViewById(R.id.tabLayout);
|
||||||
|
|
||||||
|
viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager(), uploadInformation);
|
||||||
|
|
||||||
|
viewPager.setAdapter(viewPagerAdapter);
|
||||||
|
tabLayout.setupWithViewPager(viewPager);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initViews() {
|
||||||
|
FloatingActionButton fab = findViewById(R.id.fab);
|
||||||
|
|
||||||
|
fab.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
|
||||||
|
saveCurrentSettings();
|
||||||
|
|
||||||
|
Intent i = new Intent(UploadInfoActivity.this, UploadActivity.class);
|
||||||
|
i.putExtra(UploadActivity.EXTRA_UPLOAD_INFO, uploadInformation.getUuid());
|
||||||
|
startActivity(i);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveCurrentSettings() {
|
||||||
|
uploadInformation.setAllowSelfSigned(viewPagerAdapter.uploadSettingsFragment.getAllowSelfSigned());
|
||||||
|
uploadInformation.setPull(viewPagerAdapter.uploadSettingsFragment.getPull());
|
||||||
|
uploadInformation.setPush(viewPagerAdapter.uploadSettingsFragment.getPush());
|
||||||
|
uploadInformation.setCached(viewPagerAdapter.uploadSettingsFragment.getCache());
|
||||||
|
|
||||||
|
preferenceManager.addUploadInformation(uploadInformation);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ViewPagerAdapter extends FragmentPagerAdapter {
|
||||||
|
|
||||||
|
private UploadSettingsFragment uploadSettingsFragment;
|
||||||
|
private UploadInfoFragment uploadInfoFragment = new UploadInfoFragment();
|
||||||
|
|
||||||
|
ViewPagerAdapter(@NonNull FragmentManager fm, UploadInformation uploadInformation) {
|
||||||
|
super(fm, ViewPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
|
||||||
|
uploadSettingsFragment = new UploadSettingsFragment(uploadInformation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public Fragment getItem(int position) {
|
||||||
|
switch (position) {
|
||||||
|
case 0:
|
||||||
|
return uploadSettingsFragment;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
return uploadInfoFragment;
|
||||||
|
|
||||||
|
default:
|
||||||
|
uploadSettingsFragment = new UploadSettingsFragment();
|
||||||
|
return uploadSettingsFragment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public CharSequence getPageTitle(int position) {
|
||||||
|
switch (position) {
|
||||||
|
case 0:
|
||||||
|
return "Permissions";
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
return "Credentials";
|
||||||
|
|
||||||
|
default:
|
||||||
|
return "N/A";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,156 +0,0 @@
|
||||||
package lu.circl.mispbump.activities;
|
|
||||||
|
|
||||||
import android.animation.ValueAnimator;
|
|
||||||
import android.content.res.ColorStateList;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.drawable.ColorDrawable;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.appcompat.app.ActionBar;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
import androidx.appcompat.widget.Toolbar;
|
|
||||||
import androidx.core.widget.ImageViewCompat;
|
|
||||||
|
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
|
|
||||||
import lu.circl.mispbump.R;
|
|
||||||
import lu.circl.mispbump.models.UploadInformation;
|
|
||||||
|
|
||||||
public class UploadInformationActivity extends AppCompatActivity {
|
|
||||||
|
|
||||||
public static String EXTRA_UPLOAD_INFO_KEY = "uploadInformation";
|
|
||||||
|
|
||||||
private View rootLayout;
|
|
||||||
private ImageView syncStatusIcon;
|
|
||||||
|
|
||||||
private UploadInformation uploadInformation;
|
|
||||||
private FloatingActionButton fab;
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.activity_upload_information);
|
|
||||||
|
|
||||||
|
|
||||||
parseExtra();
|
|
||||||
init();
|
|
||||||
tintSystemBars();
|
|
||||||
populateContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void parseExtra() {
|
|
||||||
String uploadInfo = getIntent().getStringExtra(EXTRA_UPLOAD_INFO_KEY);
|
|
||||||
this.uploadInformation = new Gson().fromJson(uploadInfo, UploadInformation.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void init() {
|
|
||||||
rootLayout = findViewById(R.id.rootLayout);
|
|
||||||
|
|
||||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
|
||||||
setSupportActionBar(toolbar);
|
|
||||||
|
|
||||||
ActionBar actionBar = getSupportActionBar();
|
|
||||||
actionBar.setHomeAsUpIndicator(R.drawable.ic_close);
|
|
||||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
|
||||||
|
|
||||||
fab = findViewById(R.id.fab);
|
|
||||||
|
|
||||||
syncStatusIcon = findViewById(R.id.syncStatus);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void populateContent() {
|
|
||||||
switch (uploadInformation.getCurrentSyncStatus()) {
|
|
||||||
case COMPLETE:
|
|
||||||
ImageViewCompat.setImageTintList(syncStatusIcon, ColorStateList.valueOf(getColor(R.color.status_green)));
|
|
||||||
syncStatusIcon.setImageResource(R.drawable.ic_check_outline);
|
|
||||||
fab.hide();
|
|
||||||
break;
|
|
||||||
case FAILURE:
|
|
||||||
ImageViewCompat.setImageTintList(syncStatusIcon, ColorStateList.valueOf(getColor(R.color.status_red)));
|
|
||||||
syncStatusIcon.setImageResource(R.drawable.ic_error_outline);
|
|
||||||
break;
|
|
||||||
case PENDING:
|
|
||||||
ImageViewCompat.setImageTintList(syncStatusIcon, ColorStateList.valueOf(getColor(R.color.status_amber)));
|
|
||||||
syncStatusIcon.setImageResource(R.drawable.ic_info_outline);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
TextView name = findViewById(R.id.orgName);
|
|
||||||
name.setText(uploadInformation.getRemote().organisation.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostCreate(@Nullable Bundle savedInstanceState) {
|
|
||||||
super.onPostCreate(savedInstanceState);
|
|
||||||
|
|
||||||
fab.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void postponeEnterTransition() {
|
|
||||||
super.postponeEnterTransition();
|
|
||||||
fab.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void startPostponedEnterTransition() {
|
|
||||||
super.startPostponedEnterTransition();
|
|
||||||
fab.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void tintSystemBars() {
|
|
||||||
// Initial colors of each system bar.
|
|
||||||
final int statusBarColor = getColor(R.color.white);
|
|
||||||
final int toolbarColor = getColor(R.color.white);
|
|
||||||
|
|
||||||
// Desired final colors of each bar.
|
|
||||||
final int statusBarToColor = getColor(R.color.colorPrimary);
|
|
||||||
final int toolbarToColor = getColor(R.color.colorPrimary);
|
|
||||||
|
|
||||||
ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
|
|
||||||
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
|
||||||
@Override
|
|
||||||
public void onAnimationUpdate(ValueAnimator animation) {
|
|
||||||
// Use animation position to blend colors.
|
|
||||||
float position = animation.getAnimatedFraction();
|
|
||||||
|
|
||||||
// Apply blended color to the status bar.
|
|
||||||
int blended = blendColors(statusBarColor, statusBarToColor, position);
|
|
||||||
getWindow().setStatusBarColor(blended);
|
|
||||||
|
|
||||||
blended = blendColors(toolbarColor, toolbarToColor, position);
|
|
||||||
getSupportActionBar().setBackgroundDrawable(new ColorDrawable(blended));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
anim.setDuration(500).start();
|
|
||||||
}
|
|
||||||
|
|
||||||
private int blendColors(int from, int to, float ratio) {
|
|
||||||
final float inverseRatio = 1f - ratio;
|
|
||||||
|
|
||||||
final float r = Color.red(to) * ratio + Color.red(from) * inverseRatio;
|
|
||||||
final float g = Color.green(to) * ratio + Color.green(from) * inverseRatio;
|
|
||||||
final float b = Color.blue(to) * ratio + Color.blue(from) * inverseRatio;
|
|
||||||
|
|
||||||
return Color.rgb((int) r, (int) g, (int) b);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
|
||||||
switch (item.getItemId()) {
|
|
||||||
case android.R.id.home:
|
|
||||||
onBackPressed();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,6 +5,8 @@ import android.content.res.ColorStateList;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.core.widget.ImageViewCompat;
|
import androidx.core.widget.ImageViewCompat;
|
||||||
|
@ -15,34 +17,30 @@ import java.util.List;
|
||||||
import lu.circl.mispbump.R;
|
import lu.circl.mispbump.R;
|
||||||
import lu.circl.mispbump.interfaces.OnRecyclerItemClickListener;
|
import lu.circl.mispbump.interfaces.OnRecyclerItemClickListener;
|
||||||
import lu.circl.mispbump.models.UploadInformation;
|
import lu.circl.mispbump.models.UploadInformation;
|
||||||
import lu.circl.mispbump.viewholders.UploadInfoListViewHolder;
|
|
||||||
|
|
||||||
public class UploadInfoAdapter extends RecyclerView.Adapter<UploadInfoListViewHolder> {
|
public class UploadInfoAdapter extends RecyclerView.Adapter<UploadInfoAdapter.ViewHolder> {
|
||||||
|
|
||||||
private Context context;
|
private Context context;
|
||||||
private List<UploadInformation> items;
|
private List<UploadInformation> items;
|
||||||
|
|
||||||
private OnRecyclerItemClickListener<UploadInformation> onRecyclerItemClickListener;
|
private OnRecyclerItemClickListener<UploadInformation> onRecyclerItemClickListener;
|
||||||
|
private OnRecyclerItemClickListener<Integer> onRecyclerPositionClickListener;
|
||||||
|
|
||||||
|
|
||||||
public UploadInfoAdapter(Context context) {
|
public UploadInfoAdapter(Context context) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UploadInfoAdapter(Context context, List<UploadInformation> items) {
|
|
||||||
this.context = context;
|
|
||||||
this.items = items;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public UploadInfoListViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
|
public UploadInfoAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
|
||||||
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.row_upload_information, viewGroup, false);
|
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.row_upload_information, viewGroup, false);
|
||||||
return new UploadInfoListViewHolder(v);
|
return new UploadInfoAdapter.ViewHolder(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(@NonNull final UploadInfoListViewHolder holder, int position) {
|
public void onBindViewHolder(@NonNull final UploadInfoAdapter.ViewHolder holder, final int position) {
|
||||||
|
|
||||||
final UploadInformation item = items.get(position);
|
final UploadInformation item = items.get(position);
|
||||||
|
|
||||||
|
@ -60,7 +58,7 @@ public class UploadInfoAdapter extends RecyclerView.Adapter<UploadInfoListViewHo
|
||||||
break;
|
break;
|
||||||
case PENDING:
|
case PENDING:
|
||||||
ImageViewCompat.setImageTintList(holder.syncStatus, ColorStateList.valueOf(context.getColor(R.color.status_amber)));
|
ImageViewCompat.setImageTintList(holder.syncStatus, ColorStateList.valueOf(context.getColor(R.color.status_amber)));
|
||||||
holder.syncStatus.setImageResource(R.drawable.ic_info_outline);
|
holder.syncStatus.setImageResource(R.drawable.ic_pending);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,6 +68,13 @@ public class UploadInfoAdapter extends RecyclerView.Adapter<UploadInfoListViewHo
|
||||||
onRecyclerItemClickListener.onClick(view, item);
|
onRecyclerItemClickListener.onClick(view, item);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
holder.rootView.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
onRecyclerPositionClickListener.onClick(view, position);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -77,12 +82,37 @@ public class UploadInfoAdapter extends RecyclerView.Adapter<UploadInfoListViewHo
|
||||||
return items.size();
|
return items.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setItems(List<UploadInformation> items) {
|
public void setItems(List<UploadInformation> items) {
|
||||||
this.items = items;
|
this.items = items;
|
||||||
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// callbacks
|
||||||
|
|
||||||
public void setOnRecyclerItemClickListener(OnRecyclerItemClickListener<UploadInformation> onRecyclerItemClickListener) {
|
public void setOnRecyclerItemClickListener(OnRecyclerItemClickListener<UploadInformation> onRecyclerItemClickListener) {
|
||||||
this.onRecyclerItemClickListener = onRecyclerItemClickListener;
|
this.onRecyclerItemClickListener = onRecyclerItemClickListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setOnRecyclerPositionClickListener(OnRecyclerItemClickListener<Integer> onRecyclerPositionClickListener) {
|
||||||
|
this.onRecyclerPositionClickListener = onRecyclerPositionClickListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
// viewHolder
|
||||||
|
|
||||||
|
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
View rootView;
|
||||||
|
ImageView syncStatus;
|
||||||
|
TextView orgName, date;
|
||||||
|
|
||||||
|
ViewHolder(@NonNull View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
rootView = itemView;
|
||||||
|
orgName = itemView.findViewById(R.id.orgName);
|
||||||
|
date = itemView.findViewById(R.id.date);
|
||||||
|
syncStatus = itemView.findViewById(R.id.syncStatus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,40 @@ import lu.circl.mispbump.security.DiffieHellman;
|
||||||
public class DialogManager {
|
public class DialogManager {
|
||||||
|
|
||||||
|
|
||||||
|
public static void syncAlreadyExistsDialog(Context context, final IDialogFeedback callback) {
|
||||||
|
final AlertDialog.Builder adb = new AlertDialog.Builder(context);
|
||||||
|
|
||||||
|
adb.setTitle("Sync information already exists");
|
||||||
|
adb.setMessage("You already synced with this organisation, would you like to update the information?" +
|
||||||
|
"\nUpdating the information will reset the current authkey!");
|
||||||
|
adb.setPositiveButton("Update", new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
if (callback != null) {
|
||||||
|
callback.positive();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
adb.setNegativeButton("Exit", new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
if (callback != null) {
|
||||||
|
callback.negative();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Activity act = (Activity) context;
|
||||||
|
act.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
adb.create().show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void saveAndExitDialog(Context context, final IDialogFeedback callback) {
|
public static void saveAndExitDialog(Context context, final IDialogFeedback callback) {
|
||||||
final AlertDialog.Builder adb = new AlertDialog.Builder(context);
|
final AlertDialog.Builder adb = new AlertDialog.Builder(context);
|
||||||
|
|
||||||
|
|
|
@ -322,120 +322,104 @@ public class PreferenceManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setUploadInformationList(List<UploadInformation> uploadInformationList) {
|
private List<UploadInformation> cachedUploadInformationList;
|
||||||
KeyStoreWrapper ksw = new KeyStoreWrapper(KeyStoreWrapper.UPLOAD_INFORMATION_ALIAS);
|
|
||||||
|
|
||||||
try {
|
private void loadUploadInformationList() {
|
||||||
String cipherText = ksw.encrypt(new Gson().toJson(uploadInformationList));
|
|
||||||
SharedPreferences.Editor editor = preferences.edit();
|
|
||||||
editor.putString(UPLOAD_INFO, cipherText);
|
|
||||||
editor.apply();
|
|
||||||
} catch (NoSuchPaddingException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (InvalidKeyException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (BadPaddingException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IllegalBlockSizeException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<UploadInformation> getUploadInformation() {
|
|
||||||
KeyStoreWrapper ksw = new KeyStoreWrapper(KeyStoreWrapper.UPLOAD_INFORMATION_ALIAS);
|
KeyStoreWrapper ksw = new KeyStoreWrapper(KeyStoreWrapper.UPLOAD_INFORMATION_ALIAS);
|
||||||
String storedUploadInfoString = preferences.getString(UPLOAD_INFO, null);
|
String storedUploadInfoString = preferences.getString(UPLOAD_INFO, null);
|
||||||
|
|
||||||
Type type = new TypeToken<List<UploadInformation>>() {}.getType();
|
Type type = new TypeToken<List<UploadInformation>>() {}.getType();
|
||||||
|
|
||||||
if (storedUploadInfoString == null) {
|
if (storedUploadInfoString == null || storedUploadInfoString.isEmpty()) {
|
||||||
|
cachedUploadInformationList = new ArrayList<>();
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
storedUploadInfoString = ksw.decrypt(storedUploadInfoString);
|
||||||
|
cachedUploadInformationList = new Gson().fromJson(storedUploadInfoString, type);
|
||||||
|
} catch (IllegalBlockSizeException | BadPaddingException | InvalidKeyException | InvalidAlgorithmParameterException | NoSuchPaddingException | NoSuchAlgorithmException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveUploadInformationList() {
|
||||||
|
try {
|
||||||
|
KeyStoreWrapper ksw = new KeyStoreWrapper(KeyStoreWrapper.UPLOAD_INFORMATION_ALIAS);
|
||||||
|
String cipherText = ksw.encrypt(new Gson().toJson(cachedUploadInformationList));
|
||||||
|
SharedPreferences.Editor editor = preferences.edit();
|
||||||
|
editor.putString(UPLOAD_INFO, cipherText);
|
||||||
|
editor.apply();
|
||||||
|
} catch (IllegalBlockSizeException | BadPaddingException | InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<UploadInformation> getUploadInformationList() {
|
||||||
|
if (cachedUploadInformationList == null) {
|
||||||
|
loadUploadInformationList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return cachedUploadInformationList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUploadInformationList(List<UploadInformation> uploadInformationList) {
|
||||||
|
cachedUploadInformationList = uploadInformationList;
|
||||||
|
saveUploadInformationList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public UploadInformation getUploadInformation(UUID uuid) {
|
||||||
|
if (cachedUploadInformationList == null) {
|
||||||
|
loadUploadInformationList();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (UploadInformation ui : cachedUploadInformationList) {
|
||||||
|
if (ui.getUuid().compareTo(uuid) == 0) {
|
||||||
|
return ui;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
storedUploadInfoString = ksw.decrypt(storedUploadInfoString);
|
|
||||||
} catch (NoSuchPaddingException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (InvalidAlgorithmParameterException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (InvalidKeyException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (BadPaddingException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IllegalBlockSizeException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Gson().fromJson(storedUploadInfoString, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addUploadInformation(UploadInformation uploadInformation) {
|
public void addUploadInformation(UploadInformation uploadInformation) {
|
||||||
List<UploadInformation> uploadInformationList = getUploadInformation();
|
if (cachedUploadInformationList == null) {
|
||||||
|
loadUploadInformationList();
|
||||||
|
}
|
||||||
|
|
||||||
if (uploadInformationList == null) {
|
// update if exists
|
||||||
uploadInformationList = new ArrayList<>();
|
for (int i = 0; i < cachedUploadInformationList.size(); i++) {
|
||||||
uploadInformationList.add(uploadInformation);
|
if (cachedUploadInformationList.get(i).getUuid().compareTo(uploadInformation.getUuid()) == 0) {
|
||||||
setUploadInformationList(uploadInformationList);
|
cachedUploadInformationList.set(i, uploadInformation);
|
||||||
} else {
|
saveUploadInformationList();
|
||||||
|
|
||||||
// check if upload information already exists
|
|
||||||
for (int i = 0; i < uploadInformationList.size(); i++) {
|
|
||||||
if (uploadInformationList.get(i).getId().compareTo(uploadInformation.getId()) == 0) {
|
|
||||||
uploadInformationList.set(i, uploadInformation);
|
|
||||||
setUploadInformationList(uploadInformationList);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uploadInformationList.add(uploadInformation);
|
// else: add
|
||||||
setUploadInformationList(uploadInformationList);
|
cachedUploadInformationList.add(uploadInformation);
|
||||||
}
|
saveUploadInformationList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean containsUploadInformation(UUID uuid) {
|
public void removeUploadInformation(UUID uuid) {
|
||||||
List<UploadInformation> uploadInformationList = getUploadInformation();
|
if (cachedUploadInformationList == null) {
|
||||||
|
loadUploadInformationList();
|
||||||
if (uploadInformationList == null) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (UploadInformation ui : uploadInformationList) {
|
for (UploadInformation ui : cachedUploadInformationList) {
|
||||||
if (ui.getId().compareTo(uuid) == 0) {
|
if (ui.getUuid().compareTo(uuid) == 0) {
|
||||||
return true;
|
if (cachedUploadInformationList.size() == 1) {
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean removeUploadInformation(UUID uuid) {
|
|
||||||
Log.d("PREFS", "uuid to delete: " + uuid.toString());
|
|
||||||
|
|
||||||
List<UploadInformation> uploadInformationList = getUploadInformation();
|
|
||||||
|
|
||||||
for (UploadInformation ui : uploadInformationList) {
|
|
||||||
|
|
||||||
Log.d("PREFS", "checking uuid: " + ui.getId().toString());
|
|
||||||
|
|
||||||
if (ui.getId().compareTo(uuid) == 0) {
|
|
||||||
if (uploadInformationList.size() == 1) {
|
|
||||||
clearUploadInformation();
|
clearUploadInformation();
|
||||||
} else {
|
} else {
|
||||||
uploadInformationList.remove(ui);
|
cachedUploadInformationList.remove(ui);
|
||||||
setUploadInformationList(uploadInformationList);
|
saveUploadInformationList();
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearUploadInformation() {
|
public void clearUploadInformation() {
|
||||||
|
cachedUploadInformationList.clear();
|
||||||
|
|
||||||
KeyStoreWrapper keyStoreWrapper = new KeyStoreWrapper(KeyStoreWrapper.UPLOAD_INFORMATION_ALIAS);
|
KeyStoreWrapper keyStoreWrapper = new KeyStoreWrapper(KeyStoreWrapper.UPLOAD_INFORMATION_ALIAS);
|
||||||
keyStoreWrapper.deleteStoredKey();
|
keyStoreWrapper.deleteStoredKey();
|
||||||
|
|
||||||
|
|
|
@ -22,13 +22,10 @@ public class QrCodeGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bitmap generateQrCode(String content) {
|
public Bitmap generateQrCode(String content) {
|
||||||
Point displaySize = new Point();
|
int size = getDisplaySize().x;
|
||||||
callingActivity.getWindowManager().getDefaultDisplay().getSize(displaySize);
|
|
||||||
|
|
||||||
int size = displaySize.x;
|
if (size > getDisplaySize().y) {
|
||||||
|
size = getDisplaySize().y;
|
||||||
if (displaySize.x > displaySize.y) {
|
|
||||||
size = displaySize.y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size = (int)(size * 0.8);
|
size = (int)(size * 0.8);
|
||||||
|
@ -48,6 +45,13 @@ public class QrCodeGenerator {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Point getDisplaySize() {
|
||||||
|
Point displaySize = new Point();
|
||||||
|
callingActivity.getWindowManager().getDefaultDisplay().getSize(displaySize);
|
||||||
|
|
||||||
|
return displaySize;
|
||||||
|
}
|
||||||
|
|
||||||
private Bitmap createBitmap(BitMatrix matrix) {
|
private Bitmap createBitmap(BitMatrix matrix) {
|
||||||
int width = matrix.getWidth();
|
int width = matrix.getWidth();
|
||||||
int height = matrix.getHeight();
|
int height = matrix.getHeight();
|
||||||
|
@ -55,7 +59,7 @@ public class QrCodeGenerator {
|
||||||
for (int y = 0; y < height; y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
int offset = y * width;
|
int offset = y * width;
|
||||||
for (int x = 0; x < width; x++) {
|
for (int x = 0; x < width; x++) {
|
||||||
pixels[offset + x] = matrix.get(x, y) ? 0xFF000000 : 0x99FFFFFF;
|
pixels[offset + x] = matrix.get(x, y) ? 0xFF000000 : 0x00FFFFFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
package lu.circl.mispbump.customViews;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.viewpager.widget.ViewPager;
|
||||||
|
|
||||||
|
public class ExtendedViewPager extends ViewPager {
|
||||||
|
|
||||||
|
private boolean swipeEnabled;
|
||||||
|
|
||||||
|
public ExtendedViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
|
return swipeEnabled && super.onTouchEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onInterceptTouchEvent(MotionEvent event) {
|
||||||
|
return swipeEnabled && super.onTouchEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPagingEnabled(boolean enabled) {
|
||||||
|
this.swipeEnabled = enabled;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package lu.circl.mispbump.customViews;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Switch;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||||
|
|
||||||
|
import lu.circl.mispbump.R;
|
||||||
|
|
||||||
|
public class MaterialPreferenceSwitch extends ConstraintLayout {
|
||||||
|
|
||||||
|
private View rootView;
|
||||||
|
|
||||||
|
private TextView titleView, subTitleView;
|
||||||
|
private Switch switchView;
|
||||||
|
|
||||||
|
public MaterialPreferenceSwitch(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
|
||||||
|
View view = LayoutInflater.from(context).inflate(R.layout.material_preference_switch, this);
|
||||||
|
rootView = view.findViewById(R.id.rootLayout);
|
||||||
|
|
||||||
|
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.MaterialPreferenceSwitch);
|
||||||
|
String title = a.getString(R.styleable.MaterialPreferenceSwitch_title);
|
||||||
|
String subTitle = a.getString(R.styleable.MaterialPreferenceSwitch_subtitle);
|
||||||
|
a.recycle();
|
||||||
|
|
||||||
|
titleView = view.findViewById(R.id.material_preference_title);
|
||||||
|
titleView.setText(title);
|
||||||
|
|
||||||
|
subTitleView = view.findViewById(R.id.material_preference_subtitle);
|
||||||
|
subTitleView.setText(subTitle);
|
||||||
|
|
||||||
|
switchView = view.findViewById(R.id.material_preference_switch);
|
||||||
|
|
||||||
|
rootView.setOnClickListener(new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
if (switchView.isEnabled()) {
|
||||||
|
switchView.setChecked(!switchView.isChecked());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(boolean enabled) {
|
||||||
|
switchView.setEnabled(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChecked(boolean checked) {
|
||||||
|
switchView.setChecked(checked);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isChecked() {
|
||||||
|
return switchView.isChecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -11,11 +11,12 @@ import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.appcompat.widget.LinearLayoutCompat;
|
import androidx.appcompat.widget.LinearLayoutCompat;
|
||||||
|
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||||
import androidx.core.widget.ImageViewCompat;
|
import androidx.core.widget.ImageViewCompat;
|
||||||
|
|
||||||
import lu.circl.mispbump.R;
|
import lu.circl.mispbump.R;
|
||||||
|
|
||||||
public class UploadAction extends LinearLayoutCompat {
|
public class UploadAction extends ConstraintLayout {
|
||||||
|
|
||||||
private Context context;
|
private Context context;
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ public class UploadAction extends LinearLayoutCompat {
|
||||||
ERROR
|
ERROR
|
||||||
}
|
}
|
||||||
|
|
||||||
private TextView errorView;
|
private TextView titleView, errorView;
|
||||||
private UploadState currentUploadState;
|
private UploadState currentUploadState;
|
||||||
private ImageView stateView;
|
private ImageView stateView;
|
||||||
private ProgressBar progressBar;
|
private ProgressBar progressBar;
|
||||||
|
@ -41,20 +42,23 @@ public class UploadAction extends LinearLayoutCompat {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
|
||||||
|
View baseView = LayoutInflater.from(context).inflate(R.layout.view_upload_action_2, this);
|
||||||
|
|
||||||
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.UploadAction);
|
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.UploadAction);
|
||||||
String title = a.getString(R.styleable.UploadAction_description);
|
|
||||||
|
titleView = baseView.findViewById(R.id.title);
|
||||||
|
titleView.setText(a.getString(R.styleable.UploadAction_description));
|
||||||
|
|
||||||
a.recycle();
|
a.recycle();
|
||||||
|
|
||||||
LayoutInflater inflater = LayoutInflater.from(context);
|
errorView = baseView.findViewById(R.id.error);
|
||||||
View baseView = inflater.inflate(R.layout.view_upload_action, this);
|
stateView = baseView.findViewById(R.id.stateView);
|
||||||
|
progressBar = baseView.findViewById(R.id.progressBar);
|
||||||
|
}
|
||||||
|
|
||||||
errorView = findViewById(R.id.error);
|
|
||||||
|
|
||||||
TextView titleView = baseView.findViewById(R.id.title);
|
public void setTitle(String title) {
|
||||||
titleView.setText(title);
|
titleView.setText(title);
|
||||||
|
|
||||||
stateView = findViewById(R.id.stateView);
|
|
||||||
progressBar = findViewById(R.id.progressBar);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -75,12 +79,6 @@ public class UploadAction extends LinearLayoutCompat {
|
||||||
progressBar.setVisibility(GONE);
|
progressBar.setVisibility(GONE);
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case PENDING:
|
|
||||||
stateView.setVisibility(VISIBLE);
|
|
||||||
stateView.setImageResource(R.drawable.ic_info_outline);
|
|
||||||
ImageViewCompat.setImageTintList(stateView, ColorStateList.valueOf(context.getColor(R.color.status_amber)));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LOADING:
|
case LOADING:
|
||||||
stateView.setVisibility(GONE);
|
stateView.setVisibility(GONE);
|
||||||
progressBar.setVisibility(VISIBLE);
|
progressBar.setVisibility(VISIBLE);
|
||||||
|
@ -97,6 +95,12 @@ public class UploadAction extends LinearLayoutCompat {
|
||||||
stateView.setImageResource(R.drawable.ic_error_outline);
|
stateView.setImageResource(R.drawable.ic_error_outline);
|
||||||
ImageViewCompat.setImageTintList(stateView, ColorStateList.valueOf(context.getColor(R.color.status_red)));
|
ImageViewCompat.setImageTintList(stateView, ColorStateList.valueOf(context.getColor(R.color.status_red)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PENDING:
|
||||||
|
stateView.setVisibility(VISIBLE);
|
||||||
|
stateView.setImageResource(R.drawable.ic_info_outline);
|
||||||
|
ImageViewCompat.setImageTintList(stateView, ColorStateList.valueOf(context.getColor(R.color.status_amber)));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,10 +73,6 @@ public class CameraFragment extends Fragment implements ActivityCompat.OnRequest
|
||||||
private int lastAccessedIndex = 0;
|
private int lastAccessedIndex = 0;
|
||||||
private Bitmap[] processQueue = new Bitmap[10];
|
private Bitmap[] processQueue = new Bitmap[10];
|
||||||
|
|
||||||
ImageProcessingThread() {
|
|
||||||
Log.i(TAG, "Image worker thread created");
|
|
||||||
}
|
|
||||||
|
|
||||||
void addToQueue(Bitmap bitmap) {
|
void addToQueue(Bitmap bitmap) {
|
||||||
processQueue[lastAccessedIndex] = bitmap;
|
processQueue[lastAccessedIndex] = bitmap;
|
||||||
// circular array access
|
// circular array access
|
||||||
|
@ -167,7 +163,6 @@ public class CameraFragment extends Fragment implements ActivityCompat.OnRequest
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) {
|
public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) {
|
||||||
Log.i(TAG, "Width: " + width + "; height: " + height);
|
|
||||||
openCamera(width, height);
|
openCamera(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,7 +345,6 @@ public class CameraFragment extends Fragment implements ActivityCompat.OnRequest
|
||||||
} else if (notBigEnough.size() > 0) {
|
} else if (notBigEnough.size() > 0) {
|
||||||
return Collections.max(notBigEnough, new CompareSizesByArea());
|
return Collections.max(notBigEnough, new CompareSizesByArea());
|
||||||
} else {
|
} else {
|
||||||
Log.e(TAG, "Couldn't find any suitable preview size");
|
|
||||||
return choices[0];
|
return choices[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -359,8 +353,7 @@ public class CameraFragment extends Fragment implements ActivityCompat.OnRequest
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
View v = inflater.inflate(R.layout.fragment_camera, container, false);
|
View v = inflater.inflate(R.layout.fragment_camera, container, false);
|
||||||
|
|
||||||
hideCamView = v.findViewById(R.id.hideCam);
|
// hideCamView = v.findViewById(R.id.hideCam);
|
||||||
hideCamView.setVisibility(View.GONE);
|
|
||||||
|
|
||||||
initRenderScript();
|
initRenderScript();
|
||||||
setUpBarcodeDetector();
|
setUpBarcodeDetector();
|
||||||
|
@ -370,6 +363,7 @@ public class CameraFragment extends Fragment implements ActivityCompat.OnRequest
|
||||||
@Override
|
@Override
|
||||||
public void onViewCreated(final View view, Bundle savedInstanceState) {
|
public void onViewCreated(final View view, Bundle savedInstanceState) {
|
||||||
autoFitTextureView = view.findViewById(R.id.texture);
|
autoFitTextureView = view.findViewById(R.id.texture);
|
||||||
|
hideCamView = view.findViewById(R.id.hideCam);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -381,20 +375,6 @@ public class CameraFragment extends Fragment implements ActivityCompat.OnRequest
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
enablePreview();
|
enablePreview();
|
||||||
// startBackgroundThread();
|
|
||||||
//
|
|
||||||
// imageProcessingThread = new ImageProcessingThread();
|
|
||||||
// imageProcessingThread.start();
|
|
||||||
//
|
|
||||||
// // When the screen is turned off and turned back on, the SurfaceTexture is already
|
|
||||||
// // available, and "onSurfaceTextureAvailable" will not be called. In that case, we can open
|
|
||||||
// // a camera and start preview from here (otherwise, we wait until the surface is ready in
|
|
||||||
// // the SurfaceTextureListener).
|
|
||||||
// if (autoFitTextureView.isAvailable()) {
|
|
||||||
// openCamera(autoFitTextureView.getWidth(), autoFitTextureView.getHeight());
|
|
||||||
// } else {
|
|
||||||
// autoFitTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -511,10 +491,6 @@ public class CameraFragment extends Fragment implements ActivityCompat.OnRequest
|
||||||
|
|
||||||
Size[] sizes = map.getOutputSizes(SurfaceTexture.class);
|
Size[] sizes = map.getOutputSizes(SurfaceTexture.class);
|
||||||
|
|
||||||
for (Size size : sizes) {
|
|
||||||
Log.i(TAG, size.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Danger, W.R.! Attempting to use too large a preview size could exceed the camera
|
// Danger, W.R.! Attempting to use too large a preview size could exceed the camera
|
||||||
// bus' bandwidth limitation, resulting in gorgeous previews but the storage of
|
// bus' bandwidth limitation, resulting in gorgeous previews but the storage of
|
||||||
// garbage capture data.
|
// garbage capture data.
|
||||||
|
@ -802,12 +778,6 @@ public class CameraFragment extends Fragment implements ActivityCompat.OnRequest
|
||||||
public interface QrScanCallback {
|
public interface QrScanCallback {
|
||||||
void qrScanResult(String qrData);
|
void qrScanResult(String qrData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface CameraReadyCallback {
|
|
||||||
void ready();
|
|
||||||
}
|
|
||||||
|
|
||||||
private CameraReadyCallback cameraReadyCallback;
|
|
||||||
private boolean readQrEnabled = true;
|
private boolean readQrEnabled = true;
|
||||||
private BarcodeDetector barcodeDetector;
|
private BarcodeDetector barcodeDetector;
|
||||||
private RenderScript renderScript;
|
private RenderScript renderScript;
|
||||||
|
@ -865,6 +835,18 @@ public class CameraFragment extends Fragment implements ActivityCompat.OnRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disablePreview() {
|
public void disablePreview() {
|
||||||
|
|
||||||
|
if (hideCamView.getAlpha() == 1 && hideCamView.getVisibility() == View.VISIBLE) {
|
||||||
|
closeCamera();
|
||||||
|
stopBackgroundThread();
|
||||||
|
|
||||||
|
if (imageProcessingThread.isAlive()) {
|
||||||
|
imageProcessingThread.isRunning = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
hideCamView.setAlpha(0f);
|
hideCamView.setAlpha(0f);
|
||||||
hideCamView.setVisibility(View.VISIBLE);
|
hideCamView.setVisibility(View.VISIBLE);
|
||||||
hideCamView.animate()
|
hideCamView.animate()
|
||||||
|
@ -896,19 +878,15 @@ public class CameraFragment extends Fragment implements ActivityCompat.OnRequest
|
||||||
autoFitTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
|
autoFitTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
hideCamView.setAlpha(1f);
|
|
||||||
hideCamView.setVisibility(View.VISIBLE);
|
hideCamView.setVisibility(View.VISIBLE);
|
||||||
|
hideCamView.setAlpha(1f);
|
||||||
hideCamView.animate()
|
hideCamView.animate()
|
||||||
.alpha(0f)
|
.alpha(0f)
|
||||||
.setStartDelay(100)
|
|
||||||
.setDuration(1000)
|
.setDuration(1000)
|
||||||
.setListener(new AnimatorListenerAdapter() {
|
.setListener(new AnimatorListenerAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void onAnimationEnd(Animator animation) {
|
public void onAnimationEnd(Animator animation) {
|
||||||
hideCamView.setVisibility(View.GONE);
|
hideCamView.setVisibility(View.GONE);
|
||||||
if (cameraReadyCallback != null) {
|
|
||||||
cameraReadyCallback.ready();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -926,9 +904,5 @@ public class CameraFragment extends Fragment implements ActivityCompat.OnRequest
|
||||||
public void setOnQrAvailableListener(QrScanCallback callback) {
|
public void setOnQrAvailableListener(QrScanCallback callback) {
|
||||||
qrResultCallback = callback;
|
qrResultCallback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCameraReadyCallback(CameraReadyCallback callback) {
|
|
||||||
this.cameraReadyCallback = callback;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
package lu.circl.mispbump.fragments;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
import androidx.fragment.app.FragmentPagerAdapter;
|
||||||
|
|
||||||
|
public class SyncFragmentAdapter extends FragmentPagerAdapter {
|
||||||
|
|
||||||
|
public CameraFragment cameraFragment_1, cameraFragment_2;
|
||||||
|
private UploadSettingsFragment uploadSettingsFragment;
|
||||||
|
|
||||||
|
public SyncFragmentAdapter(@NonNull FragmentManager fm) {
|
||||||
|
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CameraFragment.QrScanCallback scanCallback;
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public Fragment getItem(int position) {
|
||||||
|
switch (position) {
|
||||||
|
case 0:
|
||||||
|
if (cameraFragment_1 == null) {
|
||||||
|
cameraFragment_1 = new CameraFragment();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scanCallback != null) {
|
||||||
|
cameraFragment_1.setOnQrAvailableListener(scanCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cameraFragment_1;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
if (cameraFragment_2 == null) {
|
||||||
|
cameraFragment_2 = new CameraFragment();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scanCallback != null) {
|
||||||
|
cameraFragment_1.setOnQrAvailableListener(scanCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cameraFragment_2;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
if (uploadSettingsFragment == null) {
|
||||||
|
uploadSettingsFragment = new UploadSettingsFragment();
|
||||||
|
}
|
||||||
|
|
||||||
|
return uploadSettingsFragment;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return new CameraFragment();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQrReceivedCallback(CameraFragment.QrScanCallback qrScanCallback) {
|
||||||
|
this.scanCallback = qrScanCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disableCameraPreview() {
|
||||||
|
if (cameraFragment_1 != null) {
|
||||||
|
cameraFragment_1.disablePreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cameraFragment_2 != null) {
|
||||||
|
cameraFragment_2.disablePreview();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package lu.circl.mispbump.fragments;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
|
import lu.circl.mispbump.R;
|
||||||
|
|
||||||
|
public class UploadInfoFragment extends Fragment {
|
||||||
|
|
||||||
|
public UploadInfoFragment () {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
|
View v = inflater.inflate(R.layout.fragment_upload_info, container, false);
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,36 +1,63 @@
|
||||||
package lu.circl.mispbump.fragments;
|
package lu.circl.mispbump.fragments;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import androidx.annotation.NonNull;
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Switch;
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
import lu.circl.mispbump.R;
|
import lu.circl.mispbump.R;
|
||||||
|
import lu.circl.mispbump.customViews.MaterialPreferenceSwitch;
|
||||||
|
import lu.circl.mispbump.models.UploadInformation;
|
||||||
|
|
||||||
public class SyncOptionsFragment extends Fragment {
|
public class UploadSettingsFragment extends Fragment {
|
||||||
|
|
||||||
private Switch allowSelfSigned, push, pull, cache;
|
private MaterialPreferenceSwitch allowSelfSigned, push, pull, cache;
|
||||||
|
private UploadInformation uploadInformation;
|
||||||
|
|
||||||
|
public UploadSettingsFragment() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public UploadSettingsFragment(UploadInformation uploadInformation) {
|
||||||
|
this.uploadInformation = uploadInformation;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
View v = inflater.inflate(R.layout.fragment_sync_options, container, false);
|
View v = inflater.inflate(R.layout.fragment_upload_settings, container, false);
|
||||||
|
|
||||||
allowSelfSigned = v.findViewById(R.id.self_signed_switch);
|
allowSelfSigned = v.findViewById(R.id.self_signed_switch);
|
||||||
push = v.findViewById(R.id.push_switch);
|
push = v.findViewById(R.id.push_switch);
|
||||||
pull = v.findViewById(R.id.pull_switch);
|
pull = v.findViewById(R.id.pull_switch);
|
||||||
cache = v.findViewById(R.id.cache_switch);
|
cache = v.findViewById(R.id.cache_switch);
|
||||||
|
|
||||||
|
populateContent();
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void populateContent() {
|
||||||
|
if (uploadInformation == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
allowSelfSigned.setChecked(uploadInformation.isAllowSelfSigned());
|
||||||
|
push.setChecked(uploadInformation.isPush());
|
||||||
|
pull.setChecked(uploadInformation.isPull());
|
||||||
|
cache.setChecked(uploadInformation.isCached());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUploadInfo(UploadInformation uploadInfo) {
|
||||||
|
this.uploadInformation = uploadInfo;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean getAllowSelfSigned() {
|
public boolean getAllowSelfSigned() {
|
||||||
return allowSelfSigned.isChecked();
|
return allowSelfSigned.isChecked();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAllowSelfSigned(boolean allowSelfSigned) {
|
public void setAllowSelfSigned(boolean allowSelfSigned) {
|
||||||
this.allowSelfSigned.setChecked(allowSelfSigned);
|
this.allowSelfSigned.setChecked(allowSelfSigned);
|
||||||
}
|
}
|
||||||
|
@ -38,6 +65,7 @@ public class SyncOptionsFragment extends Fragment {
|
||||||
public boolean getPush() {
|
public boolean getPush() {
|
||||||
return push.isChecked();
|
return push.isChecked();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPush(boolean push) {
|
public void setPush(boolean push) {
|
||||||
this.push.setChecked(push);
|
this.push.setChecked(push);
|
||||||
}
|
}
|
||||||
|
@ -45,6 +73,7 @@ public class SyncOptionsFragment extends Fragment {
|
||||||
public boolean getPull() {
|
public boolean getPull() {
|
||||||
return pull.isChecked();
|
return pull.isChecked();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPull(boolean pull) {
|
public void setPull(boolean pull) {
|
||||||
this.pull.setChecked(pull);
|
this.pull.setChecked(pull);
|
||||||
}
|
}
|
||||||
|
@ -52,6 +81,7 @@ public class SyncOptionsFragment extends Fragment {
|
||||||
public boolean getCache() {
|
public boolean getCache() {
|
||||||
return cache.isChecked();
|
return cache.isChecked();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCache(boolean cache) {
|
public void setCache(boolean cache) {
|
||||||
this.cache.setChecked(cache);
|
this.cache.setChecked(cache);
|
||||||
}
|
}
|
|
@ -2,14 +2,13 @@ package lu.circl.mispbump.models;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class UploadInformation implements Serializable {
|
public class UploadInformation {
|
||||||
|
|
||||||
public enum SyncStatus {
|
public enum SyncStatus {
|
||||||
COMPLETE,
|
COMPLETE,
|
||||||
|
@ -17,7 +16,7 @@ public class UploadInformation implements Serializable {
|
||||||
PENDING
|
PENDING
|
||||||
}
|
}
|
||||||
|
|
||||||
private UUID id;
|
private UUID uuid;
|
||||||
|
|
||||||
private SyncStatus currentSyncStatus = SyncStatus.PENDING;
|
private SyncStatus currentSyncStatus = SyncStatus.PENDING;
|
||||||
|
|
||||||
|
@ -29,19 +28,8 @@ public class UploadInformation implements Serializable {
|
||||||
private Date date;
|
private Date date;
|
||||||
|
|
||||||
public UploadInformation() {
|
public UploadInformation() {
|
||||||
this(null, null);
|
uuid = UUID.randomUUID();
|
||||||
}
|
|
||||||
|
|
||||||
public UploadInformation(SyncInformation local) {
|
|
||||||
this(local, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public UploadInformation(SyncInformation local, SyncInformation remote) {
|
|
||||||
id = UUID.randomUUID();
|
|
||||||
date = Calendar.getInstance().getTime();
|
date = Calendar.getInstance().getTime();
|
||||||
|
|
||||||
this.local = local;
|
|
||||||
this.remote = remote;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// getter and setter
|
// getter and setter
|
||||||
|
@ -67,11 +55,11 @@ public class UploadInformation implements Serializable {
|
||||||
return remote;
|
return remote;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UUID getId() {
|
public UUID getUuid() {
|
||||||
return id;
|
return uuid;
|
||||||
}
|
}
|
||||||
public void setId(UUID id) {
|
public void setUuid(UUID uuid) {
|
||||||
this.id = id;
|
this.uuid = uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDate() {
|
public void setDate() {
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
package lu.circl.mispbump.viewholders;
|
|
||||||
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
|
|
||||||
import lu.circl.mispbump.R;
|
|
||||||
|
|
||||||
public class UploadInfoListViewHolder extends RecyclerView.ViewHolder {
|
|
||||||
|
|
||||||
public View rootView;
|
|
||||||
public ImageView syncStatus;
|
|
||||||
public TextView orgName, date;
|
|
||||||
|
|
||||||
public UploadInfoListViewHolder(@NonNull View itemView) {
|
|
||||||
super(itemView);
|
|
||||||
|
|
||||||
rootView = itemView;
|
|
||||||
|
|
||||||
orgName = itemView.findViewById(R.id.orgName);
|
|
||||||
date = itemView.findViewById(R.id.date);
|
|
||||||
syncStatus = itemView.findViewById(R.id.syncStatus);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,9 @@
|
||||||
<vector android:height="24dp" android:tint="#B4B4B4"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
android:width="24dp"
|
||||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:height="24dp"
|
||||||
<path android:fillColor="#FF000000" android:pathData="M12,6v3l4,-4 -4,-4v3c-4.42,0 -8,3.58 -8,8 0,1.57 0.46,3.03 1.24,4.26L6.7,14.8c-0.45,-0.83 -0.7,-1.79 -0.7,-2.8 0,-3.31 2.69,-6 6,-6zM18.76,7.74L17.3,9.2c0.44,0.84 0.7,1.79 0.7,2.8 0,3.31 -2.69,6 -6,6v-3l-4,4 4,4v-3c4.42,0 8,-3.58 8,-8 0,-1.57 -0.46,-3.03 -1.24,-4.26z"/>
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M12,6v1.79c0,0.45 0.54,0.67 0.85,0.35l2.79,-2.79c0.2,-0.2 0.2,-0.51 0,-0.71l-2.79,-2.79c-0.31,-0.31 -0.85,-0.09 -0.85,0.36L12,4c-4.42,0 -8,3.58 -8,8 0,1.04 0.2,2.04 0.57,2.95 0.27,0.67 1.13,0.85 1.64,0.34 0.27,-0.27 0.38,-0.68 0.23,-1.04C6.15,13.56 6,12.79 6,12c0,-3.31 2.69,-6 6,-6zM17.79,8.71c-0.27,0.27 -0.38,0.69 -0.23,1.04 0.28,0.7 0.44,1.46 0.44,2.25 0,3.31 -2.69,6 -6,6v-1.79c0,-0.45 -0.54,-0.67 -0.85,-0.35l-2.79,2.79c-0.2,0.2 -0.2,0.51 0,0.71l2.79,2.79c0.31,0.31 0.85,0.09 0.85,-0.35L12,20c4.42,0 8,-3.58 8,-8 0,-1.04 -0.2,-2.04 -0.57,-2.95 -0.27,-0.67 -1.13,-0.85 -1.64,-0.34z"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<vector android:height="24dp" android:tint="#FFFFFF"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
android:width="24dp"
|
||||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:height="24dp"
|
||||||
<path android:fillColor="#FFF" android:pathData="M11,15h2v2h-2zM11,7h2v6h-2zM11.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,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z"/>
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFF"
|
||||||
|
android:pathData="M12,7c0.55,0 1,0.45 1,1v4c0,0.55 -0.45,1 -1,1s-1,-0.45 -1,-1L11,8c0,-0.55 0.45,-1 1,-1zM11.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,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8zM13,17h-2v-2h2v2z"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFF"
|
||||||
|
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,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8zM11.78,7h-0.06c-0.4,0 -0.72,0.32 -0.72,0.72v4.72c0,0.35 0.18,0.68 0.49,0.86l4.15,2.49c0.34,0.2 0.78,0.1 0.98,-0.24 0.21,-0.34 0.1,-0.79 -0.25,-0.99l-3.87,-2.3L12.5,7.72c0,-0.4 -0.32,-0.72 -0.72,-0.72z"/>
|
||||||
|
</vector>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<solid android:color="@color/white"/>
|
||||||
|
<corners android:radius="12dp"/>
|
||||||
|
</shape>
|
|
@ -4,6 +4,6 @@
|
||||||
android:color="@color/white"/>
|
android:color="@color/white"/>
|
||||||
|
|
||||||
<corners
|
<corners
|
||||||
android:topLeftRadius="10dp"
|
android:topLeftRadius="12dp"
|
||||||
android:topRightRadius="10dp"/>
|
android:topRightRadius="12dp"/>
|
||||||
</shape>
|
</shape>
|
|
@ -4,8 +4,7 @@
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:id="@+id/rootLayout"
|
android:id="@+id/rootLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent">
|
||||||
android:animateLayoutChanges="true">
|
|
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -15,25 +14,23 @@
|
||||||
android:id="@+id/toolbar"
|
android:id="@+id/toolbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
|
android:theme="@style/ToolbarTheme"
|
||||||
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
|
app:popupTheme="@style/PopupTheme" />
|
||||||
android:background="@color/colorPrimary" />
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/recyclerView"
|
android:id="@+id/recyclerView"
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent" />
|
||||||
android:animateLayoutChanges="true"/>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/empty"
|
android:id="@+id/empty"
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:drawableTop="@drawable/ic_sync_black_24dp"
|
android:layout_gravity="center"
|
||||||
android:gravity="center"
|
android:layout_marginBottom="64dp"
|
||||||
android:text="@string/no_syncs_hint"/>
|
android:text="@string/no_syncs_hint"/>
|
||||||
|
|
||||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
android:tint="@color/white"
|
android:tint="@color/white"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/toolbar" />
|
app:layout_constraintTop_toBottomOf="@id/toolbar" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/orgName"
|
android:id="@+id/orgName"
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
@ -8,71 +7,89 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<FrameLayout
|
||||||
|
android:id="@+id/fragmentContainer"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"/>
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/sync_fragment_container"
|
android:id="@+id/qrFrame"
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" >
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/qrcode"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="64dp"
|
android:layout_gravity="center"
|
||||||
android:contentDescription="@string/qr_code"
|
android:background="@drawable/rect_rounded"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:backgroundTint="#99FFFFFF"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
android:padding="8dp"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
tools:layout_height="256dp"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
tools:layout_width="256dp">
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
app:layout_behavior=".customViews.ExtendedBottomSheetBehavior"
|
android:layout_width="wrap_content"
|
||||||
android:id="@+id/bottomSheet"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:background="@drawable/rounded_rect"
|
android:gravity="center_vertical">
|
||||||
android:backgroundTint="@color/colorPrimary"
|
|
||||||
app:behavior_peekHeight="64dp">
|
<ImageView
|
||||||
|
android:id="@+id/qrCode"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/qrHint"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:drawableStart="@drawable/ic_info_outline"
|
||||||
|
android:drawablePadding="8dp"
|
||||||
|
android:drawableTint="@color/status_amber"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:padding="8dp"
|
||||||
|
android:text="Scan your partners QR code"
|
||||||
|
android:textColor="@color/colorPrimaryDark"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/qrHint2"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:drawableStart="@drawable/ic_info_outline"
|
||||||
|
android:drawablePadding="8dp"
|
||||||
|
android:drawableTint="@color/colorPrimaryDark"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:padding="8dp"
|
||||||
|
android:lines="2"
|
||||||
|
android:text="Continue if your partner also scanned this QR code"
|
||||||
|
android:textColor="@color/colorPrimaryDark"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="horizontal"
|
android:id="@+id/bottom"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="56dp"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:background="@drawable/rect_rounded_top"
|
||||||
|
android:backgroundTint="@color/colorPrimary"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/prevButton"
|
android:id="@+id/prevButton"
|
||||||
android:layout_width="64dp"
|
android:layout_width="56dp"
|
||||||
android:layout_height="64dp"
|
android:layout_height="56dp"
|
||||||
android:background="?attr/selectableItemBackground"
|
android:background="?attr/selectableItemBackground"
|
||||||
android:padding="8dp"
|
android:padding="8dp"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:srcCompat="@drawable/ic_arrow_back"/>
|
app:srcCompat="@drawable/ic_arrow_back"/>
|
||||||
|
|
||||||
<ImageView
|
<View
|
||||||
android:visibility="invisible"
|
|
||||||
android:id="@+id/bottomSheetIcon"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="32dp"
|
android:layout_height="0dp"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_weight="1"/>
|
||||||
android:src="@drawable/ic_check_outline" />
|
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/nextButton"
|
android:id="@+id/nextButton"
|
||||||
android:layout_width="64dp"
|
android:layout_width="56dp"
|
||||||
android:layout_height="64dp"
|
android:layout_height="56dp"
|
||||||
android:background="?attr/selectableItemBackground"
|
android:background="?attr/selectableItemBackground"
|
||||||
android:padding="8dp"
|
android:padding="8dp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
@ -81,17 +98,62 @@
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView
|
<!--<LinearLayout-->
|
||||||
android:id="@+id/bottomSheetText"
|
<!--app:layout_behavior=".customViews.ExtendedBottomSheetBehavior"-->
|
||||||
android:layout_width="wrap_content"
|
<!--android:id="@+id/bottomSheet"-->
|
||||||
android:layout_height="wrap_content"
|
<!--android:layout_width="match_parent"-->
|
||||||
android:paddingStart="16dp"
|
<!--android:layout_height="wrap_content"-->
|
||||||
android:paddingEnd="16dp"
|
<!--android:orientation="vertical"-->
|
||||||
android:paddingBottom="16dp"
|
<!--android:background="@drawable/rect_rounded_top"-->
|
||||||
android:gravity="top"
|
<!--android:backgroundTint="@color/colorPrimary"-->
|
||||||
android:layout_gravity="center"
|
<!--app:behavior_peekHeight="64dp">-->
|
||||||
android:text="Received public key from partner"
|
|
||||||
android:textColor="@color/white" />
|
<!--<LinearLayout-->
|
||||||
</LinearLayout>
|
<!--android:orientation="horizontal"-->
|
||||||
|
<!--android:layout_width="match_parent"-->
|
||||||
|
<!--android:layout_height="wrap_content">-->
|
||||||
|
|
||||||
|
<!--<ImageButton-->
|
||||||
|
<!--android:id="@+id/prevButton"-->
|
||||||
|
<!--android:layout_width="64dp"-->
|
||||||
|
<!--android:layout_height="64dp"-->
|
||||||
|
<!--android:background="?attr/selectableItemBackground"-->
|
||||||
|
<!--android:padding="8dp"-->
|
||||||
|
<!--app:layout_constraintStart_toStartOf="parent"-->
|
||||||
|
<!--app:layout_constraintTop_toTopOf="parent"-->
|
||||||
|
<!--app:srcCompat="@drawable/ic_arrow_back" />-->
|
||||||
|
|
||||||
|
<!--<ImageView-->
|
||||||
|
<!--android:visibility="invisible"-->
|
||||||
|
<!--android:id="@+id/bottomSheetIcon"-->
|
||||||
|
<!--android:layout_weight="1"-->
|
||||||
|
<!--android:layout_width="0dp"-->
|
||||||
|
<!--android:layout_height="32dp"-->
|
||||||
|
<!--android:layout_gravity="center_vertical"-->
|
||||||
|
<!--android:src="@drawable/ic_check_outline" />-->
|
||||||
|
|
||||||
|
<!--<ImageButton-->
|
||||||
|
<!--android:id="@+id/nextButton"-->
|
||||||
|
<!--android:layout_width="64dp"-->
|
||||||
|
<!--android:layout_height="64dp"-->
|
||||||
|
<!--android:background="?attr/selectableItemBackground"-->
|
||||||
|
<!--android:padding="8dp"-->
|
||||||
|
<!--app:layout_constraintEnd_toEndOf="parent"-->
|
||||||
|
<!--app:layout_constraintTop_toTopOf="parent"-->
|
||||||
|
<!--app:srcCompat="@drawable/ic_arrow_forward" />-->
|
||||||
|
<!--</LinearLayout>-->
|
||||||
|
|
||||||
|
<!--<TextView-->
|
||||||
|
<!--android:id="@+id/bottomSheetText"-->
|
||||||
|
<!--android:layout_width="wrap_content"-->
|
||||||
|
<!--android:layout_height="wrap_content"-->
|
||||||
|
<!--android:paddingStart="16dp"-->
|
||||||
|
<!--android:paddingEnd="16dp"-->
|
||||||
|
<!--android:paddingBottom="16dp"-->
|
||||||
|
<!--android:gravity="top"-->
|
||||||
|
<!--android:layout_gravity="center"-->
|
||||||
|
<!--android:text="Received public key from partner"-->
|
||||||
|
<!--android:textColor="@color/white" />-->
|
||||||
|
<!--</LinearLayout>-->
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -34,10 +34,10 @@
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="16dp"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="16dp"
|
||||||
android:layout_marginEnd="16dp"
|
android:layout_marginEnd="16dp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:title="Check if instance is available" />
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:description="Check if instance is available" />
|
||||||
|
|
||||||
<lu.circl.mispbump.customViews.UploadAction
|
<lu.circl.mispbump.customViews.UploadAction
|
||||||
android:id="@+id/orgAction"
|
android:id="@+id/orgAction"
|
||||||
|
@ -46,10 +46,10 @@
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="16dp"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="16dp"
|
||||||
android:layout_marginEnd="16dp"
|
android:layout_marginEnd="16dp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:title="Add organisation" />
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:description="Add organisation" />
|
||||||
|
|
||||||
<lu.circl.mispbump.customViews.UploadAction
|
<lu.circl.mispbump.customViews.UploadAction
|
||||||
android:id="@+id/userAction"
|
android:id="@+id/userAction"
|
||||||
|
@ -61,7 +61,7 @@
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:title="Add sync user" />
|
app:description="Add sync user" />
|
||||||
|
|
||||||
<lu.circl.mispbump.customViews.UploadAction
|
<lu.circl.mispbump.customViews.UploadAction
|
||||||
android:id="@+id/serverAction"
|
android:id="@+id/serverAction"
|
||||||
|
@ -73,18 +73,18 @@
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:title="Add sync server" />
|
app:description="Add sync server" />
|
||||||
|
|
||||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||||
|
|
||||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
<!--<com.google.android.material.floatingactionbutton.FloatingActionButton-->
|
||||||
android:id="@+id/fab"
|
<!--android:id="@+id/fab"-->
|
||||||
android:layout_width="wrap_content"
|
<!--android:layout_width="wrap_content"-->
|
||||||
android:layout_height="wrap_content"
|
<!--android:layout_height="wrap_content"-->
|
||||||
android:layout_gravity="bottom|end"
|
<!--android:layout_gravity="bottom|end"-->
|
||||||
android:layout_margin="16dp"
|
<!--android:layout_margin="16dp"-->
|
||||||
app:backgroundTint="@color/colorAccent"
|
<!--app:backgroundTint="@color/colorAccent"-->
|
||||||
android:tint="@color/white"
|
<!--android:tint="@color/white"-->
|
||||||
android:src="@drawable/ic_cloud_upload"/>
|
<!--android:src="@drawable/ic_cloud_upload"/>-->
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -1,71 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/rootLayout"
|
|
||||||
android:transitionName="root"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:elevation="6dp"
|
|
||||||
app:elevation="6dp">
|
|
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.Toolbar
|
|
||||||
android:id="@+id/toolbar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="?attr/actionBarSize"
|
|
||||||
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
|
|
||||||
app:popupTheme="@style/ThemeOverlay.AppCompat"
|
|
||||||
android:background="@color/white" />
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/syncStatus"
|
|
||||||
android:transitionName="icon"
|
|
||||||
android:transformPivotX="32dp"
|
|
||||||
android:transformPivotY="32dp"
|
|
||||||
android:layout_width="64dp"
|
|
||||||
android:layout_height="64dp"
|
|
||||||
android:tint="@color/status_green"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:src="@drawable/ic_check_outline"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/orgName"
|
|
||||||
android:transitionName="title"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:textAppearance="@style/Text.Title"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/syncStatus"
|
|
||||||
tools:text="Organisation Title" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
|
||||||
android:id="@+id/fab"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="bottom|end"
|
|
||||||
android:layout_margin="16dp"
|
|
||||||
android:src="@drawable/ic_cloud_upload"/>
|
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/rootLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@color/white">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.Toolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
app:popupTheme="@style/PopupTheme"
|
||||||
|
app:theme="@style/ToolbarTheme.Light"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/syncStatus"
|
||||||
|
android:layout_marginTop="-12dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
tools:text="Successfully uploaded"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Widget.ActionBar.Subtitle"
|
||||||
|
android:textColor="@color/status_green"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:layout_marginStart="72dp"
|
||||||
|
android:drawableEnd="@drawable/ic_check_outline"
|
||||||
|
android:drawableTint="@color/status_green"
|
||||||
|
android:drawablePadding="8dp"/>
|
||||||
|
|
||||||
|
<com.google.android.material.tabs.TabLayout
|
||||||
|
android:id="@+id/tabLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:tabGravity="fill"
|
||||||
|
app:tabMode="fixed"/>
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
<androidx.viewpager.widget.ViewPager
|
||||||
|
android:id="@+id/viewPager"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"/>
|
||||||
|
|
||||||
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
|
android:id="@+id/fab"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="end|bottom"
|
||||||
|
android:layout_margin="16dp"/>
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:drawablePadding="8dp"
|
||||||
|
android:lines="1"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
|
||||||
|
tools:drawableEnd="@drawable/ic_error_outline"
|
||||||
|
tools:drawableTint="@color/status_red"
|
||||||
|
tools:text="Sample title"/>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:src="@drawable/ic_error_outline"
|
||||||
|
android:tint="@color/status_red"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -1,147 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/allow_self_signed"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="32dp"
|
|
||||||
android:layout_marginTop="32dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:fontFamily="sans-serif"
|
|
||||||
android:text="Allow self signed certificates"
|
|
||||||
android:textColor="@android:color/primary_text_light"
|
|
||||||
android:textSize="14sp"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/self_signed_switch"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/share_events_desc"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="32dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:text="Server certificate must not be from a trusted CA (not recomended)"
|
|
||||||
android:textSize="12sp"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/self_signed_switch"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/allow_self_signed" />
|
|
||||||
|
|
||||||
<Switch
|
|
||||||
android:id="@+id/self_signed_switch"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_marginEnd="32dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/share_events_desc"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="@+id/allow_self_signed" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/push_title"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="32dp"
|
|
||||||
android:layout_marginTop="24dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:fontFamily="sans-serif"
|
|
||||||
android:text="Push"
|
|
||||||
android:textColor="#000000"
|
|
||||||
android:textSize="14sp"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/push_switch"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/share_events_desc" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/push_desc"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="32dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:text="Allow the upload of events and their attributes"
|
|
||||||
android:textSize="12sp"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/push_switch"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/push_title" />
|
|
||||||
|
|
||||||
|
|
||||||
<Switch
|
|
||||||
android:id="@+id/push_switch"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_marginEnd="32dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/push_desc"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="@+id/push_title" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/pull_title"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="32dp"
|
|
||||||
android:layout_marginTop="24dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:text="Pull"
|
|
||||||
android:textColor="#000000"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/pull_switch"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/push_desc" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/pull_desc"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="32dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:text="Allow the download of events and their attributes"
|
|
||||||
android:textSize="12sp"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/pull_switch"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/pull_title" />
|
|
||||||
|
|
||||||
<Switch
|
|
||||||
android:id="@+id/pull_switch"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_marginEnd="32dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/pull_desc"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="@+id/pull_title" />
|
|
||||||
|
|
||||||
<Switch
|
|
||||||
android:id="@+id/cache_switch"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_marginEnd="32dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/cache_desc"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="@+id/cache_title" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/cache_title"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="32dp"
|
|
||||||
android:layout_marginTop="24dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:text="Caching"
|
|
||||||
android:textColor="#000000"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/cache_switch"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/pull_desc" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/cache_desc"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="32dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:text="Allow the caching of events and their attributes"
|
|
||||||
android:textSize="12sp"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/cache_switch"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/cache_title" />
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -0,0 +1,72 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/rootLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:text="This Organisation will have the following rights on your MISP instance"
|
||||||
|
android:textAppearance="@style/Text.Title"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"/>
|
||||||
|
|
||||||
|
<lu.circl.mispbump.customViews.MaterialPreferenceSwitch
|
||||||
|
android:id="@+id/self_signed_switch"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/text"
|
||||||
|
app:subtitle="Server certificate must not be from a trusted CA (not recomended)"
|
||||||
|
app:title="Allow self signed certificates"/>
|
||||||
|
|
||||||
|
<lu.circl.mispbump.customViews.MaterialPreferenceSwitch
|
||||||
|
android:id="@+id/push_switch"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/self_signed_switch"
|
||||||
|
app:subtitle="Allow the upload of events and their attributes"
|
||||||
|
app:title="Push"/>
|
||||||
|
|
||||||
|
<lu.circl.mispbump.customViews.MaterialPreferenceSwitch
|
||||||
|
android:id="@+id/pull_switch"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/push_switch"
|
||||||
|
app:subtitle="Allow the download of events and their attributes"
|
||||||
|
app:title="Pull"/>
|
||||||
|
|
||||||
|
<lu.circl.mispbump.customViews.MaterialPreferenceSwitch
|
||||||
|
android:id="@+id/cache_switch"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/pull_switch"
|
||||||
|
app:subtitle="Allow the caching of events and their attributes"
|
||||||
|
app:title="Cache"/>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -0,0 +1,58 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/rootLayout"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="false"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:foreground="?attr/selectableItemBackground">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/material_preference_title"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:clickable="false"
|
||||||
|
android:focusable="false"
|
||||||
|
android:focusableInTouchMode="false"
|
||||||
|
android:textAppearance="@style/Text.Title"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/material_preference_switch"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:text="Title" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/material_preference_subtitle"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:clickable="false"
|
||||||
|
android:focusable="false"
|
||||||
|
android:focusableInTouchMode="false"
|
||||||
|
android:textAppearance="@style/Text.SubTitle"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/material_preference_switch"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/material_preference_title"
|
||||||
|
tools:text="Subtitle" />
|
||||||
|
|
||||||
|
<Switch
|
||||||
|
android:id="@+id/material_preference_switch"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/material_preference_subtitle"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/material_preference_title" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -13,11 +13,13 @@
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/title"
|
android:id="@+id/title"
|
||||||
android:textAppearance="@style/Text.Title"
|
android:text="000"
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:textAppearance="@style/Text.Title"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginEnd="8dp" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/stateView"
|
android:id="@+id/stateView"
|
||||||
|
@ -36,6 +38,7 @@
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/error"
|
android:id="@+id/error"
|
||||||
|
android:text="000"
|
||||||
android:textAppearance="@style/Text.SubTitle"
|
android:textAppearance="@style/Text.SubTitle"
|
||||||
android:textColor="@color/status_red"
|
android:textColor="@color/status_red"
|
||||||
android:layout_marginEnd="24dp"
|
android:layout_marginEnd="24dp"
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:foreground="?attr/selectableItemBackground">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/stateView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:src="@drawable/ic_error_outline"
|
||||||
|
android:tint="@color/black"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:visibility="gone"
|
||||||
|
android:id="@+id/progressBar"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="2dp"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:text="Title (upload action)" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:visibility="gone"
|
||||||
|
android:id="@+id/error"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/title"
|
||||||
|
tools:text="Error" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -2,8 +2,8 @@
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
<item
|
<item
|
||||||
android:id="@+id/bla"
|
android:id="@+id/delete"
|
||||||
android:icon="@drawable/ic_delete_forever"
|
android:icon="@drawable/ic_delete_forever"
|
||||||
android:title="delete"
|
android:title="Remove"
|
||||||
app:showAsAction="ifRoom"/>
|
app:showAsAction="never"/>
|
||||||
</menu>
|
</menu>
|
|
@ -1,8 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<changeBounds/>
|
|
||||||
<!--<fade-->
|
|
||||||
<!--android:fadingMode="fade_in_out"/>-->
|
|
||||||
|
|
||||||
<!--<transition class="lu.circl.mispbump.RecyclerViewItemTransition"/>-->
|
|
||||||
</transitionSet>
|
|
|
@ -1,9 +1,18 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<declare-styleable name="MaterialPreferenceText">
|
|
||||||
<attr name="pref_icon" format="integer"/>
|
|
||||||
<attr name="title" format="string"/>
|
<attr name="title" format="string"/>
|
||||||
<attr name="subtitle" format="string"/>
|
<attr name="subtitle" format="string"/>
|
||||||
|
|
||||||
|
<declare-styleable name="MaterialPreferenceText">
|
||||||
|
<attr name="pref_icon" format="integer"/>
|
||||||
|
<attr name="title"/>
|
||||||
|
<attr name="subtitle"/>
|
||||||
|
</declare-styleable>
|
||||||
|
|
||||||
|
<declare-styleable name="MaterialPreferenceSwitch">
|
||||||
|
<attr name="title"/>
|
||||||
|
<attr name="subtitle"/>
|
||||||
</declare-styleable>
|
</declare-styleable>
|
||||||
|
|
||||||
<declare-styleable name="UploadAction">
|
<declare-styleable name="UploadAction">
|
||||||
|
|
|
@ -2,17 +2,17 @@
|
||||||
<resources>
|
<resources>
|
||||||
<color name="colorPrimary">#047EB4</color>
|
<color name="colorPrimary">#047EB4</color>
|
||||||
<color name="colorPrimaryDark">#023850</color>
|
<color name="colorPrimaryDark">#023850</color>
|
||||||
<!--<color name="colorPrimaryDark">#047EB4</color>-->
|
|
||||||
<color name="colorAccent">#12B3FA</color>
|
<color name="colorAccent">#12B3FA</color>
|
||||||
<color name="colorAccent_50">#8012B3FA</color>
|
|
||||||
|
|
||||||
<color name="dividerColor">#33000000</color>
|
<color name="dividerColor">#33000000</color>
|
||||||
|
|
||||||
<!-- colors -->
|
|
||||||
<color name="white">#FFFFFF</color>
|
<color name="white">#FFFFFF</color>
|
||||||
<color name="white_50">#80FFFFFF</color>
|
<color name="white_50">#80FFFFFF</color>
|
||||||
|
|
||||||
<color name="grey">#BDBDBD</color>
|
<color name="grey">#BDBDBD</color>
|
||||||
|
<color name="grey_light">#F0F0F0</color>
|
||||||
|
|
||||||
|
<color name="black">#000</color>
|
||||||
|
|
||||||
<color name="status_green">#4CAF50</color>
|
<color name="status_green">#4CAF50</color>
|
||||||
<color name="status_amber">#FB8C00</color>
|
<color name="status_amber">#FB8C00</color>
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
<string name="misp_automation_hint">MISP Automation Key</string>
|
<string name="misp_automation_hint">MISP Automation Key</string>
|
||||||
<string name="no_information">No Information</string>
|
<string name="no_information">No Information</string>
|
||||||
<string name="save_automation_key_hint">Save Automation Key</string>
|
<string name="save_automation_key_hint">Save Automation Key</string>
|
||||||
<string name="home" translatable="false">Home</string>
|
|
||||||
<string name="menu_login_help_label">Help</string>
|
<string name="menu_login_help_label">Help</string>
|
||||||
<string name="login_help_text"><b>MISP Server URL</b>\nPublic MISP URL\n\n<b>MISP Automation key</b>\nZu finden unter ...</string>
|
<string name="login_help_text"><b>MISP Server URL</b>\nPublic MISP URL\n\n<b>MISP Automation key</b>\nZu finden unter ...</string>
|
||||||
<string name="ok" translatable="false">Okay</string>
|
<string name="ok" translatable="false">Okay</string>
|
||||||
|
|
|
@ -1,21 +1,8 @@
|
||||||
<resources>
|
<resources>
|
||||||
<!-- Theme.MaterialComponents.Light.NoActionBar || Theme.AppCompat.Light.NoActionBar -->
|
|
||||||
|
|
||||||
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
|
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
|
||||||
<item name="colorPrimary">@color/colorPrimary</item>
|
<item name="colorPrimary">@color/colorPrimary</item>
|
||||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||||
<item name="colorAccent">@color/colorAccent</item>
|
<item name="colorAccent">@color/colorAccent</item>
|
||||||
|
|
||||||
<item name="android:windowContentTransitions">true</item>
|
|
||||||
|
|
||||||
<!-- specify enter and exit transitions -->
|
|
||||||
<!-- options are: explode, slide, fade -->
|
|
||||||
<!--<item name="android:windowEnterTransition">@transition/simple</item>-->
|
|
||||||
<!--<item name="android:windowExitTransition">@transition/simple</item>-->
|
|
||||||
|
|
||||||
<!--specify shared element transitions -->
|
|
||||||
<item name="android:windowSharedElementEnterTransition">@transition/simple</item>
|
|
||||||
<item name="android:windowSharedElementExitTransition">@transition/simple</item>
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="AppTheme.Translucent">
|
<style name="AppTheme.Translucent">
|
||||||
|
@ -23,13 +10,14 @@
|
||||||
<item name="android:windowTranslucentStatus">true</item>
|
<item name="android:windowTranslucentStatus">true</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="AppTheme.FullScreenDialog" parent="Theme.MaterialComponents.Light.DialogWhenLarge">
|
<style name="PopupTheme" parent="ThemeOverlay.MaterialComponents.Light"/>
|
||||||
<item name="android:statusBarColor">@color/colorPrimaryDark</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style name="DialogAnimation">
|
<style name="ToolbarTheme" parent="ThemeOverlay.MaterialComponents.Dark.ActionBar"/>
|
||||||
<item name="android:windowEnterAnimation">@anim/fade_in</item>
|
|
||||||
<item name="android:windowExitAnimation">@anim/fade_out</item>
|
<style name="ToolbarTheme.Light" parent="@style/ThemeOverlay.MaterialComponents.ActionBar">
|
||||||
|
<item name="android:background">@color/white</item>
|
||||||
|
<item name="colorControlNormal">#000</item>
|
||||||
|
<item name="android:tint">#000</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="Text"/>
|
<style name="Text"/>
|
||||||
|
|
Loading…
Reference in New Issue