Refactored adding new identities
- add deterministic identities - import existing identities
This commit is contained in:
parent
c1d5af0034
commit
a18ef1ac29
@ -61,9 +61,11 @@ dependencies {
|
||||
compile ('com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:0.9.3@aar'){
|
||||
transitive=true
|
||||
}
|
||||
compile 'com.github.angads25:filepicker:1.0.6'
|
||||
|
||||
testCompile 'junit:junit:4.12'
|
||||
testCompile 'org.mockito:mockito-core:1.10.19'
|
||||
compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha8'
|
||||
}
|
||||
|
||||
idea.module {
|
||||
|
@ -18,7 +18,8 @@
|
||||
android:allowBackup="false"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme">
|
||||
android:theme="@style/AppTheme"
|
||||
tools:replace="android:allowBackup">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:label="@string/app_name">
|
||||
@ -103,6 +104,26 @@
|
||||
<category android:name="android.intent.category.BROWSABLE"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ImportIdentityActivity"
|
||||
android:label="@string/title_import_identity"
|
||||
android:parentActivityName=".MainActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".MainActivity"/>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.dat"
|
||||
android:scheme="file"/>
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<category android:name="android.intent.category.BROWSABLE"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<service android:name=".service.BitmessageService"/>
|
||||
<service android:name=".service.ProofOfWorkService"/>
|
||||
|
@ -106,8 +106,8 @@ public class AddressDetailFragment extends Fragment {
|
||||
Drawables.addIcon(getActivity(), menu, R.id.share, GoogleMaterial.Icon.gmd_share);
|
||||
Drawables.addIcon(getActivity(), menu, R.id.delete, GoogleMaterial.Icon.gmd_delete);
|
||||
Drawables.addIcon(getActivity(), menu, R.id.export,
|
||||
CommunityMaterial.Icon.cmd_export)
|
||||
.setVisible(item != null && item.getPrivateKey() != null);
|
||||
CommunityMaterial.Icon.cmd_export)
|
||||
.setVisible(item != null && item.getPrivateKey() != null);
|
||||
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
}
|
||||
@ -130,41 +130,45 @@ public class AddressDetailFragment extends Fragment {
|
||||
else
|
||||
warning = R.string.delete_contact_warning;
|
||||
new AlertDialog.Builder(ctx)
|
||||
.setMessage(warning)
|
||||
.setPositiveButton(android.R.string.yes, new
|
||||
DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
Singleton.getAddressRepository(ctx).remove(item);
|
||||
item = null;
|
||||
ctx.onBackPressed();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(android.R.string.no, null)
|
||||
.show();
|
||||
.setMessage(warning)
|
||||
.setPositiveButton(android.R.string.yes, new
|
||||
DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
Singleton.getAddressRepository(ctx).remove(item);
|
||||
MainActivity mainActivity = MainActivity.getInstance();
|
||||
if (item.getPrivateKey() != null && mainActivity != null) {
|
||||
mainActivity.removeIdentityEntry(item);
|
||||
}
|
||||
item = null;
|
||||
ctx.onBackPressed();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(android.R.string.no, null)
|
||||
.show();
|
||||
return true;
|
||||
}
|
||||
case R.id.export: {
|
||||
new AlertDialog.Builder(ctx)
|
||||
.setMessage(R.string.confirm_export)
|
||||
.setPositiveButton(android.R.string.yes, new
|
||||
DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
Intent shareIntent = new Intent(Intent.ACTION_SEND);
|
||||
shareIntent.setType("text/plain");
|
||||
shareIntent.putExtra(Intent.EXTRA_TITLE, item +
|
||||
EXPORT_POSTFIX);
|
||||
WifExporter exporter = new WifExporter(Singleton
|
||||
.getBitmessageContext(ctx));
|
||||
exporter.addIdentity(item);
|
||||
shareIntent.putExtra(Intent.EXTRA_TEXT, exporter.toString
|
||||
());
|
||||
startActivity(Intent.createChooser(shareIntent, null));
|
||||
}
|
||||
})
|
||||
.setNegativeButton(android.R.string.no, null)
|
||||
.show();
|
||||
.setMessage(R.string.confirm_export)
|
||||
.setPositiveButton(android.R.string.yes, new
|
||||
DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
Intent shareIntent = new Intent(Intent.ACTION_SEND);
|
||||
shareIntent.setType("text/plain");
|
||||
shareIntent.putExtra(Intent.EXTRA_TITLE, item +
|
||||
EXPORT_POSTFIX);
|
||||
WifExporter exporter = new WifExporter(Singleton
|
||||
.getBitmessageContext(ctx));
|
||||
exporter.addIdentity(item);
|
||||
shareIntent.putExtra(Intent.EXTRA_TEXT, exporter.toString
|
||||
());
|
||||
startActivity(Intent.createChooser(shareIntent, null));
|
||||
}
|
||||
})
|
||||
.setNegativeButton(android.R.string.no, null)
|
||||
.show();
|
||||
return true;
|
||||
}
|
||||
case R.id.share: {
|
||||
@ -208,7 +212,7 @@ public class AddressDetailFragment extends Fragment {
|
||||
address.setText(item.getAddress());
|
||||
address.setSelected(true);
|
||||
((TextView) rootView.findViewById(R.id.stream_number)).setText(getActivity()
|
||||
.getString(R.string.stream_number, item.getStream()));
|
||||
.getString(R.string.stream_number, item.getStream()));
|
||||
if (item.getPrivateKey() == null) {
|
||||
Switch active = (Switch) rootView.findViewById(R.id.active);
|
||||
active.setChecked(item.isSubscribed());
|
||||
@ -220,12 +224,12 @@ public class AddressDetailFragment extends Fragment {
|
||||
});
|
||||
|
||||
ImageView pubkeyAvailableImg = (ImageView) rootView.findViewById(R.id
|
||||
.pubkey_available);
|
||||
.pubkey_available);
|
||||
|
||||
if (item.getPubkey() == null) {
|
||||
pubkeyAvailableImg.setAlpha(0.3f);
|
||||
TextView pubkeyAvailableDesc = (TextView) rootView.findViewById(R.id
|
||||
.pubkey_available_desc);
|
||||
.pubkey_available_desc);
|
||||
pubkeyAvailableDesc.setText(R.string.pubkey_not_available);
|
||||
}
|
||||
} else {
|
||||
@ -251,7 +255,7 @@ public class AddressDetailFragment extends Fragment {
|
||||
BitMatrix result;
|
||||
try {
|
||||
result = new MultiFormatWriter().encode(link.toString(),
|
||||
BarcodeFormat.QR_CODE, QR_CODE_SIZE, QR_CODE_SIZE, null);
|
||||
BarcodeFormat.QR_CODE, QR_CODE_SIZE, QR_CODE_SIZE, null);
|
||||
} catch (WriterException e) {
|
||||
LOG.error(e.getMessage(), e);
|
||||
return null;
|
||||
|
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2016 Christian Basler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package ch.dissem.apps.abit;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.h6ah4i.android.widget.advrecyclerview.decoration.SimpleListDividerDecorator;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ch.dissem.apps.abit.adapter.AddressSelectorAdapter;
|
||||
import ch.dissem.apps.abit.service.Singleton;
|
||||
import ch.dissem.bitmessage.BitmessageContext;
|
||||
import ch.dissem.bitmessage.entity.BitmessageAddress;
|
||||
import ch.dissem.bitmessage.wif.WifImporter;
|
||||
|
||||
/**
|
||||
* @author Christian Basler
|
||||
*/
|
||||
|
||||
public class ImportIdentitiesFragment extends Fragment {
|
||||
public static final String WIF_DATA = "wif_data";
|
||||
private BitmessageContext bmc;
|
||||
private RecyclerView recyclerView;
|
||||
private LinearLayoutManager layoutManager;
|
||||
private AddressSelectorAdapter adapter;
|
||||
private WifImporter importer;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
|
||||
savedInstanceState) {
|
||||
String wifData = getArguments().getString(WIF_DATA);
|
||||
bmc = Singleton.getBitmessageContext(getActivity());
|
||||
View view = inflater.inflate(R.layout.fragment_import_select_identities, container, false);
|
||||
try {
|
||||
importer = new WifImporter(bmc, wifData);
|
||||
adapter = new AddressSelectorAdapter(importer.getIdentities());
|
||||
layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL,
|
||||
false);
|
||||
recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
|
||||
recyclerView.setLayoutManager(layoutManager);
|
||||
recyclerView.setAdapter(adapter);
|
||||
|
||||
recyclerView.addItemDecoration(new SimpleListDividerDecorator(
|
||||
ContextCompat.getDrawable(getActivity(), R.drawable.list_divider_h), true));
|
||||
} catch (IOException e) {
|
||||
return super.onCreateView(inflater, container, savedInstanceState);
|
||||
}
|
||||
view.findViewById(R.id.finish).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
importer.importAll(adapter.getSelected());
|
||||
MainActivity mainActivity = MainActivity.getInstance();
|
||||
if (mainActivity != null) {
|
||||
for (BitmessageAddress selected : adapter.getSelected()) {
|
||||
mainActivity.addIdentityEntry(selected);
|
||||
}
|
||||
}
|
||||
getActivity().finish();
|
||||
}
|
||||
});
|
||||
return view;
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2016 Christian Basler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package ch.dissem.apps.abit;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import static ch.dissem.apps.abit.ImportIdentitiesFragment.WIF_DATA;
|
||||
|
||||
/**
|
||||
* @author Christian Basler
|
||||
*/
|
||||
|
||||
public class ImportIdentityActivity extends DetailActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
String wifData;
|
||||
if (savedInstanceState == null) {
|
||||
wifData = null;
|
||||
} else {
|
||||
wifData = savedInstanceState.getString(WIF_DATA);
|
||||
}
|
||||
if (wifData == null) {
|
||||
getFragmentManager().beginTransaction()
|
||||
.replace(R.id.content, new InputWifFragment())
|
||||
.commit();
|
||||
} else {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(WIF_DATA, wifData);
|
||||
|
||||
ImportIdentitiesFragment fragment = new ImportIdentitiesFragment();
|
||||
fragment.setArguments(bundle);
|
||||
|
||||
getFragmentManager().beginTransaction()
|
||||
.replace(R.id.content, fragment)
|
||||
.commit();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
122
app/src/main/java/ch/dissem/apps/abit/InputWifFragment.java
Normal file
122
app/src/main/java/ch/dissem/apps/abit/InputWifFragment.java
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright 2016 Christian Basler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package ch.dissem.apps.abit;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.github.angads25.filepicker.controller.DialogSelectionListener;
|
||||
import com.github.angads25.filepicker.model.DialogConfigs;
|
||||
import com.github.angads25.filepicker.model.DialogProperties;
|
||||
import com.github.angads25.filepicker.view.FilePickerDialog;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static ch.dissem.apps.abit.ImportIdentitiesFragment.WIF_DATA;
|
||||
|
||||
/**
|
||||
* @author Christian Basler
|
||||
*/
|
||||
|
||||
public class InputWifFragment extends Fragment {
|
||||
private TextView wifData;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_import_input, container, false);
|
||||
wifData = (TextView) view.findViewById(R.id.wif_input);
|
||||
|
||||
view.findViewById(R.id.next).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(WIF_DATA, wifData.getText().toString());
|
||||
|
||||
ImportIdentitiesFragment fragment = new ImportIdentitiesFragment();
|
||||
fragment.setArguments(bundle);
|
||||
|
||||
getFragmentManager().beginTransaction()
|
||||
.replace(R.id.content, fragment)
|
||||
.commit();
|
||||
}
|
||||
});
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
inflater.inflate(R.menu.import_input_data, menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
DialogProperties properties = new DialogProperties();
|
||||
properties.selection_mode = DialogConfigs.SINGLE_MODE;
|
||||
properties.selection_type = DialogConfigs.FILE_SELECT;
|
||||
properties.root = new File(DialogConfigs.DEFAULT_DIR);
|
||||
properties.error_dir = new File(DialogConfigs.DEFAULT_DIR);
|
||||
properties.extensions = null;
|
||||
FilePickerDialog dialog = new FilePickerDialog(getActivity(), properties);
|
||||
dialog.setTitle(getString(R.string.select_file_title));
|
||||
dialog.setDialogSelectionListener(new DialogSelectionListener() {
|
||||
@Override
|
||||
public void onSelectedFilePaths(String[] files) {
|
||||
if (files.length > 0) {
|
||||
try (InputStream in = new FileInputStream(files[0])) {
|
||||
ByteArrayOutputStream data = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[1024];
|
||||
int length;
|
||||
//noinspection ConstantConditions
|
||||
while ((length = in.read(buffer)) != -1) {
|
||||
data.write(buffer, 0, length);
|
||||
}
|
||||
wifData.setText(data.toString("UTF-8"));
|
||||
} catch (IOException e) {
|
||||
Toast.makeText(
|
||||
getActivity(),
|
||||
R.string.error_loading_data,
|
||||
Toast.LENGTH_SHORT
|
||||
).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
dialog.show();
|
||||
return true;
|
||||
}
|
||||
}
|
@ -16,7 +16,6 @@
|
||||
|
||||
package ch.dissem.apps.abit;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
@ -24,7 +23,6 @@ import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.graphics.Point;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.support.v4.app.Fragment;
|
||||
@ -34,8 +32,6 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.github.amlcurran.showcaseview.ShowcaseView;
|
||||
import com.github.amlcurran.showcaseview.targets.Target;
|
||||
@ -65,6 +61,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import ch.dissem.apps.abit.dialog.AddIdentityDialogFragment;
|
||||
import ch.dissem.apps.abit.listener.ActionBarListener;
|
||||
import ch.dissem.apps.abit.listener.ListSelectionListener;
|
||||
import ch.dissem.apps.abit.service.BitmessageService;
|
||||
@ -75,7 +72,6 @@ import ch.dissem.apps.abit.util.Preferences;
|
||||
import ch.dissem.bitmessage.BitmessageContext;
|
||||
import ch.dissem.bitmessage.entity.BitmessageAddress;
|
||||
import ch.dissem.bitmessage.entity.Plaintext;
|
||||
import ch.dissem.bitmessage.entity.payload.Pubkey;
|
||||
import ch.dissem.bitmessage.entity.valueobject.Label;
|
||||
|
||||
import static ch.dissem.apps.abit.service.BitmessageService.isRunning;
|
||||
@ -143,6 +139,7 @@ public class MainActivity extends AppCompatActivity
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
instance = new WeakReference<>(this);
|
||||
bmc = Singleton.getBitmessageContext(this);
|
||||
List<Label> labels = bmc.messages().getLabels();
|
||||
if (selectedLabel == null) {
|
||||
@ -261,15 +258,6 @@ public class MainActivity extends AppCompatActivity
|
||||
.colorRes(R.color.icons))
|
||||
.withIdentifier(ADD_IDENTITY)
|
||||
);
|
||||
profiles.add(new ProfileSettingDrawerItem()
|
||||
.withName(getString(R.string.add_chan))
|
||||
.withDescription(getString(R.string.add_chan_summary))
|
||||
.withIcon(new IconicsDrawable(this, GoogleMaterial.Icon.gmd_add)
|
||||
.actionBar()
|
||||
.paddingDp(5)
|
||||
.colorRes(R.color.icons))
|
||||
.withIdentifier(ADD_CHAN)
|
||||
);
|
||||
profiles.add(new ProfileSettingDrawerItem()
|
||||
.withName(getString(R.string.manage_identity))
|
||||
.withIcon(GoogleMaterial.Icon.gmd_settings)
|
||||
@ -288,9 +276,6 @@ public class MainActivity extends AppCompatActivity
|
||||
case ADD_IDENTITY:
|
||||
addIdentityDialog();
|
||||
break;
|
||||
case ADD_CHAN:
|
||||
addChanDialog();
|
||||
break;
|
||||
case MANAGE_IDENTITY:
|
||||
Intent show = new Intent(MainActivity.this,
|
||||
AddressDetailActivity.class);
|
||||
@ -423,102 +408,45 @@ public class MainActivity extends AppCompatActivity
|
||||
}
|
||||
|
||||
private void addIdentityDialog() {
|
||||
new AlertDialog.Builder(MainActivity.this)
|
||||
.setMessage(R.string.add_identity_warning)
|
||||
.setPositiveButton(android.R.string.yes, new
|
||||
DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog,
|
||||
int which) {
|
||||
Toast.makeText(MainActivity.this,
|
||||
R.string.toast_long_running_operation,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
new AsyncTask<Void, Void, BitmessageAddress>() {
|
||||
@Override
|
||||
protected BitmessageAddress doInBackground(Void... args) {
|
||||
return bmc.createIdentity(false, Pubkey.Feature.DOES_ACK);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(BitmessageAddress chan) {
|
||||
Toast.makeText(MainActivity.this,
|
||||
R.string.toast_identity_created,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
addIdentityEntry(chan);
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(android.R.string.no, null)
|
||||
.show();
|
||||
}
|
||||
|
||||
private void addChanDialog() {
|
||||
@SuppressLint("InflateParams")
|
||||
final View dialogView = getLayoutInflater().inflate(R.layout.dialog_input_passphrase, null);
|
||||
new AlertDialog.Builder(MainActivity.this)
|
||||
.setMessage(R.string.add_chan)
|
||||
.setView(dialogView)
|
||||
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
TextView passphrase = (TextView) dialogView.findViewById(R.id.passphrase);
|
||||
Toast.makeText(MainActivity.this, R.string.toast_long_running_operation,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
new AsyncTask<String, Void, BitmessageAddress>() {
|
||||
@Override
|
||||
protected BitmessageAddress doInBackground(String... args) {
|
||||
String pass = args[0];
|
||||
BitmessageAddress chan = bmc.createChan(pass);
|
||||
chan.setAlias(pass);
|
||||
bmc.addresses().save(chan);
|
||||
return chan;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(BitmessageAddress chan) {
|
||||
Toast.makeText(MainActivity.this,
|
||||
R.string.toast_chan_created,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
addIdentityEntry(chan);
|
||||
}
|
||||
}.execute(passphrase.getText().toString());
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.show();
|
||||
AddIdentityDialogFragment dialog = new AddIdentityDialogFragment();
|
||||
dialog.show(getSupportFragmentManager(), "dialog");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
instance = new WeakReference<>(this);
|
||||
updateUnread();
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
private void addIdentityEntry(BitmessageAddress identity) {
|
||||
IProfile newProfile = new
|
||||
ProfileDrawerItem()
|
||||
public void addIdentityEntry(BitmessageAddress identity) {
|
||||
IProfile newProfile = new ProfileDrawerItem()
|
||||
.withIcon(new Identicon(identity))
|
||||
.withName(identity.toString())
|
||||
.withNameShown(true)
|
||||
.withEmail(identity.getAddress())
|
||||
.withTag(identity);
|
||||
if (accountHeader.getProfiles() != null) {
|
||||
// we know that there are 3 setting
|
||||
// we know that there are 2 setting
|
||||
// elements.
|
||||
// Set the new profile above them ;)
|
||||
accountHeader.addProfile(
|
||||
newProfile, accountHeader
|
||||
.getProfiles().size()
|
||||
- 3);
|
||||
- 2);
|
||||
} else {
|
||||
accountHeader.addProfiles(newProfile);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
instance = null;
|
||||
public void removeIdentityEntry(BitmessageAddress identity) {
|
||||
for (IProfile profile : accountHeader.getProfiles()) {
|
||||
if (profile instanceof ProfileDrawerItem) {
|
||||
if (identity.equals(((ProfileDrawerItem) profile).getTag())) {
|
||||
accountHeader.removeProfile(profile);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkAndStartNode(final CompoundButton buttonView) {
|
||||
|
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2016 Christian Basler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package ch.dissem.apps.abit.adapter;
|
||||
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import ch.dissem.apps.abit.R;
|
||||
import ch.dissem.bitmessage.entity.BitmessageAddress;
|
||||
|
||||
/**
|
||||
* @author Christian Basler
|
||||
*/
|
||||
|
||||
public class AddressSelectorAdapter
|
||||
extends RecyclerView.Adapter<AddressSelectorAdapter.ViewHolder> {
|
||||
|
||||
private final List<Selectable<BitmessageAddress>> data;
|
||||
|
||||
public AddressSelectorAdapter(List<BitmessageAddress> identities) {
|
||||
data = new ArrayList<>(identities.size());
|
||||
for (BitmessageAddress identity : identities) {
|
||||
data.add(new Selectable<>(identity));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
|
||||
final View v = inflater.inflate(R.layout.select_identity_row, parent, false);
|
||||
return new ViewHolder(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder holder, int position) {
|
||||
Selectable<BitmessageAddress> selectable = data.get(position);
|
||||
holder.data = selectable;
|
||||
holder.checkbox.setChecked(selectable.selected);
|
||||
holder.checkbox.setText(selectable.data.toString());
|
||||
holder.address.setText(selectable.data.getAddress());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return data.size();
|
||||
}
|
||||
|
||||
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
public Selectable<BitmessageAddress> data;
|
||||
public CheckBox checkbox;
|
||||
public TextView address;
|
||||
|
||||
private ViewHolder(View v) {
|
||||
super(v);
|
||||
checkbox = (CheckBox) v.findViewById(R.id.checkbox);
|
||||
address = (TextView) v.findViewById(R.id.address);
|
||||
checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
if (data != null) {
|
||||
data.selected = isChecked;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static class Selectable<T> {
|
||||
private final T data;
|
||||
private boolean selected = false;
|
||||
|
||||
private Selectable(T data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
|
||||
public List<BitmessageAddress> getSelected() {
|
||||
List<BitmessageAddress> result = new LinkedList<>();
|
||||
for (Selectable<BitmessageAddress> selectable : data) {
|
||||
if (selectable.selected) {
|
||||
result.add(selectable.data);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright 2016 Christian Basler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package ch.dissem.apps.abit.dialog;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AppCompatDialogFragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import ch.dissem.apps.abit.ImportIdentityActivity;
|
||||
import ch.dissem.apps.abit.MainActivity;
|
||||
import ch.dissem.apps.abit.R;
|
||||
import ch.dissem.apps.abit.service.Singleton;
|
||||
import ch.dissem.bitmessage.BitmessageContext;
|
||||
import ch.dissem.bitmessage.entity.BitmessageAddress;
|
||||
import ch.dissem.bitmessage.entity.payload.Pubkey;
|
||||
|
||||
import static android.app.Activity.RESULT_OK;
|
||||
|
||||
/**
|
||||
* @author Christian Basler
|
||||
*/
|
||||
|
||||
public class AddIdentityDialogFragment extends AppCompatDialogFragment {
|
||||
private static final int IMPORT_IDENTITY_RESULT_CODE = 1;
|
||||
private BitmessageContext bmc;
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
bmc = Singleton.getBitmessageContext(context);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
|
||||
savedInstanceState) {
|
||||
getDialog().setTitle(R.string.add_identity);
|
||||
View view = inflater.inflate(R.layout.dialog_add_identity, container, false);
|
||||
view.findViewById(R.id.create_identity)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dismiss();
|
||||
Toast.makeText(getActivity(),
|
||||
R.string.toast_long_running_operation,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
new AsyncTask<Void, Void, BitmessageAddress>() {
|
||||
@Override
|
||||
protected BitmessageAddress doInBackground(Void... args) {
|
||||
return bmc.createIdentity(false, Pubkey.Feature.DOES_ACK);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(BitmessageAddress chan) {
|
||||
Toast.makeText(getActivity(),
|
||||
R.string.toast_identity_created,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
MainActivity mainActivity = MainActivity.getInstance();
|
||||
if (mainActivity != null) {
|
||||
mainActivity.addIdentityEntry(chan);
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
});
|
||||
view.findViewById(R.id.import_identity)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dismiss();
|
||||
startActivity(new Intent(getActivity(), ImportIdentityActivity.class));
|
||||
}
|
||||
});
|
||||
view.findViewById(R.id.add_deterministic_address)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dismiss();
|
||||
new DeterministicIdentityDialogFragment().show(getFragmentManager(), "dialog");
|
||||
}
|
||||
});
|
||||
view.findViewById(R.id.add_chan)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dismiss();
|
||||
addChanDialog();
|
||||
}
|
||||
});
|
||||
view.findViewById(R.id.dismiss)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
return view;
|
||||
}
|
||||
|
||||
private void addChanDialog() {
|
||||
@SuppressLint("InflateParams")
|
||||
final View dialogView = getActivity().getLayoutInflater()
|
||||
.inflate(R.layout.dialog_input_passphrase, null);
|
||||
new AlertDialog.Builder(getActivity())
|
||||
.setTitle(R.string.add_chan)
|
||||
.setView(dialogView)
|
||||
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
TextView passphrase = (TextView) dialogView.findViewById(R.id.passphrase);
|
||||
Toast.makeText(getActivity(), R.string.toast_long_running_operation,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
new AsyncTask<String, Void, BitmessageAddress>() {
|
||||
@Override
|
||||
protected BitmessageAddress doInBackground(String... args) {
|
||||
String pass = args[0];
|
||||
BitmessageAddress chan = bmc.createChan(pass);
|
||||
chan.setAlias(pass);
|
||||
bmc.addresses().save(chan);
|
||||
return chan;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(BitmessageAddress chan) {
|
||||
Toast.makeText(getActivity(),
|
||||
R.string.toast_chan_created,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
MainActivity mainActivity = MainActivity.getInstance();
|
||||
if (mainActivity != null) {
|
||||
mainActivity.addIdentityEntry(chan);
|
||||
}
|
||||
}
|
||||
}.execute(passphrase.getText().toString());
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTheme() {
|
||||
return R.style.FixedDialog;
|
||||
}
|
||||
}
|
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright 2016 Christian Basler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package ch.dissem.apps.abit.dialog;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v7.app.AppCompatDialogFragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Switch;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import ch.dissem.apps.abit.MainActivity;
|
||||
import ch.dissem.apps.abit.R;
|
||||
import ch.dissem.apps.abit.service.Singleton;
|
||||
import ch.dissem.bitmessage.BitmessageContext;
|
||||
import ch.dissem.bitmessage.entity.BitmessageAddress;
|
||||
import ch.dissem.bitmessage.entity.payload.Pubkey;
|
||||
|
||||
/**
|
||||
* @author Christian Basler
|
||||
*/
|
||||
|
||||
public class DeterministicIdentityDialogFragment extends AppCompatDialogFragment {
|
||||
private BitmessageContext bmc;
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
bmc = Singleton.getBitmessageContext(context);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
|
||||
savedInstanceState) {
|
||||
getDialog().setTitle(R.string.add_deterministic_address);
|
||||
View view = inflater.inflate(R.layout.dialog_add_deterministic_identity, container, false);
|
||||
view.findViewById(R.id.ok)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dismiss();
|
||||
final Context context = getActivity().getBaseContext();
|
||||
View dialogView = getView();
|
||||
TextView label = (TextView) dialogView.findViewById(R.id.label);
|
||||
TextView passphrase = (TextView) dialogView.findViewById(R.id.passphrase);
|
||||
TextView numberOfAddresses = (TextView) dialogView.findViewById(R.id
|
||||
.number_of_identities);
|
||||
Switch shorter = (Switch) dialogView.findViewById(R.id.shorter);
|
||||
|
||||
Toast.makeText(context, R.string.toast_long_running_operation,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
new AsyncTask<Object, Void, List<BitmessageAddress>>() {
|
||||
@Override
|
||||
protected List<BitmessageAddress> doInBackground(Object... args) {
|
||||
String label = (String) args[0];
|
||||
String pass = (String) args[1];
|
||||
int numberOfAddresses = (int) args[2];
|
||||
boolean shorter = (boolean) args[3];
|
||||
List<BitmessageAddress> identities = bmc.createDeterministicAddresses
|
||||
(pass,
|
||||
numberOfAddresses, Pubkey.LATEST_VERSION, 1L, shorter);
|
||||
int i = 0;
|
||||
for (BitmessageAddress identity : identities) {
|
||||
i++;
|
||||
if (identities.size() == 1) {
|
||||
identity.setAlias(label);
|
||||
} else {
|
||||
identity.setAlias(label + " (" + i + ")");
|
||||
}
|
||||
bmc.addresses().save(identity);
|
||||
}
|
||||
return identities;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(List<BitmessageAddress> identities) {
|
||||
int messageRes;
|
||||
if (identities.size() == 1) {
|
||||
messageRes = R.string.toast_identity_created;
|
||||
} else {
|
||||
messageRes = R.string.toast_identities_created;
|
||||
}
|
||||
Toast.makeText(context,
|
||||
messageRes,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
MainActivity mainActivity = MainActivity.getInstance();
|
||||
if (mainActivity != null) {
|
||||
for (BitmessageAddress identity : identities) {
|
||||
mainActivity.addIdentityEntry(identity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}.execute(
|
||||
label.getText().toString(),
|
||||
passphrase.getText().toString(),
|
||||
Integer.valueOf(numberOfAddresses.getText().toString()),
|
||||
shorter.isChecked()
|
||||
);
|
||||
}
|
||||
});
|
||||
view.findViewById(R.id.dismiss)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTheme() {
|
||||
return R.style.FixedDialog;
|
||||
}
|
||||
}
|
25
app/src/main/res/drawable/ic_action_open_file.xml
Normal file
25
app/src/main/res/drawable/ic_action_open_file.xml
Normal file
@ -0,0 +1,25 @@
|
||||
<!--
|
||||
~ Copyright 2016 Christian Basler
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M20,6h-8l-2,-2L4,4c-1.1,0 -1.99,0.9 -1.99,2L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,8c0,-1.1 -0.9,-2 -2,-2zM20,18L4,18L4,8h16v10z"/>
|
||||
</vector>
|
118
app/src/main/res/layout/dialog_add_deterministic_identity.xml
Normal file
118
app/src/main/res/layout/dialog_add_deterministic_identity.xml
Normal file
@ -0,0 +1,118 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2016 Christian Basler
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<android.support.constraint.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="match_parent"
|
||||
android:paddingBottom="18dp"
|
||||
android:paddingEnd="24dp"
|
||||
android:paddingStart="24dp"
|
||||
android:paddingTop="18dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/deterministic_address_warning"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:layout_constraintLeft_creator="1"
|
||||
tools:layout_constraintTop_creator="1"/>
|
||||
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:id="@+id/label_wrapper"
|
||||
android:layout_marginTop="24dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/description">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/label"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/label"/>
|
||||
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:id="@+id/passphrase_wrapper"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/label_wrapper">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/passphrase"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/passphrase"
|
||||
android:inputType="textMultiLine"/>
|
||||
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:id="@+id/number_of_identities_wrapper"
|
||||
android:layout_width="312dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/passphrase_wrapper">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/number_of_identities"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10"
|
||||
android:hint="@string/number_of_identities"
|
||||
android:inputType="number"
|
||||
android:text="1"/>
|
||||
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
<Switch
|
||||
android:id="@+id/shorter"
|
||||
android:layout_width="312dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/shorter"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/number_of_identities_wrapper"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/ok"
|
||||
style="?android:attr/borderlessButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="24dp"
|
||||
android:text="@string/ok"
|
||||
android:textColor="@color/colorAccent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/shorter"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/dismiss"
|
||||
style="?android:attr/borderlessButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/cancel"
|
||||
android:textColor="@color/colorAccent"
|
||||
app:layout_constraintBottom_toBottomOf="@id/ok"
|
||||
app:layout_constraintRight_toLeftOf="@id/ok"/>
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
104
app/src/main/res/layout/dialog_add_identity.xml
Normal file
104
app/src/main/res/layout/dialog_add_identity.xml
Normal file
@ -0,0 +1,104 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2016 Christian Basler
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<android.support.constraint.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:paddingEnd="24dp"
|
||||
android:paddingStart="24dp"
|
||||
android:paddingTop="18dp"
|
||||
android:paddingBottom="18dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/add_identity_warning"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:layout_constraintLeft_creator="1"
|
||||
tools:layout_constraintTop_creator="1"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/create_identity"
|
||||
style="?android:attr/borderlessButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/create_identity"
|
||||
android:textColor="@color/colorAccent"
|
||||
app:layout_constraintHorizontal_bias="1.0"
|
||||
app:layout_constraintRight_toRightOf="@+id/description"
|
||||
app:layout_constraintTop_toBottomOf="@+id/description"
|
||||
tools:layout_constraintLeft_creator="1"
|
||||
tools:layout_constraintRight_creator="1"
|
||||
tools:layout_constraintTop_creator="1"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/import_identity"
|
||||
style="?android:attr/borderlessButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/import_identity"
|
||||
android:textColor="@color/colorAccent"
|
||||
app:layout_constraintHorizontal_bias="1.0"
|
||||
app:layout_constraintRight_toRightOf="@+id/create_identity"
|
||||
app:layout_constraintTop_toBottomOf="@+id/create_identity"
|
||||
tools:layout_constraintLeft_creator="1"
|
||||
tools:layout_constraintRight_creator="1"
|
||||
tools:layout_constraintTop_creator="1"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/add_deterministic_address"
|
||||
style="?android:attr/borderlessButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/add_deterministic_address"
|
||||
android:textColor="@color/colorAccent"
|
||||
app:layout_constraintHorizontal_bias="1.0"
|
||||
app:layout_constraintRight_toRightOf="@+id/import_identity"
|
||||
app:layout_constraintTop_toBottomOf="@+id/import_identity"
|
||||
tools:layout_constraintLeft_creator="1"
|
||||
tools:layout_constraintRight_creator="1"
|
||||
tools:layout_constraintTop_creator="1"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/add_chan"
|
||||
style="?android:attr/borderlessButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/add_chan"
|
||||
android:textColor="@color/colorAccent"
|
||||
app:layout_constraintHorizontal_bias="1.0"
|
||||
app:layout_constraintRight_toRightOf="@+id/add_deterministic_address"
|
||||
app:layout_constraintTop_toBottomOf="@+id/add_deterministic_address"
|
||||
tools:layout_constraintLeft_creator="1"
|
||||
tools:layout_constraintRight_creator="1"
|
||||
tools:layout_constraintTop_creator="1"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/dismiss"
|
||||
style="?android:attr/borderlessButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/cancel"
|
||||
android:textColor="@color/colorAccent"
|
||||
app:layout_constraintLeft_toLeftOf="@+id/description"
|
||||
app:layout_constraintTop_toBottomOf="@+id/add_deterministic_address"/>
|
||||
</android.support.constraint.ConstraintLayout>
|
@ -2,7 +2,11 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="18dp"
|
||||
android:paddingLeft="24dp"
|
||||
android:paddingRight="24dp"
|
||||
android:paddingTop="18dp">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/passphrase"
|
||||
@ -11,4 +15,4 @@
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:hint="@string/passphrase"
|
||||
android:inputType="textMultiLine"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
60
app/src/main/res/layout/fragment_import_input.xml
Normal file
60
app/src/main/res/layout/fragment_import_input.xml
Normal file
@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2016 Christian Basler
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<android.support.constraint.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"
|
||||
android:layout_marginBottom="64dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/description"
|
||||
android:layout_width="360dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/import_input_description"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/wif_input"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="24dp"
|
||||
android:gravity="start|top"
|
||||
android:hint="@string/wif_string"
|
||||
android:inputType="textMultiLine|text"
|
||||
app:layout_constraintBottom_toTopOf="@+id/next"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/description"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/next"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/next"
|
||||
android:textColor="@color/colorAccent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"/>
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2016 Christian Basler
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<android.support.constraint.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"
|
||||
android:layout_marginBottom="64dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/select_identities_to_import"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="24dp"
|
||||
android:inputType="textMultiLine|text"
|
||||
app:layout_constraintBottom_toTopOf="@+id/finish"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/description"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/finish"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/do_import"
|
||||
android:textColor="@color/colorAccent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"/>
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
52
app/src/main/res/layout/select_identity_row.xml
Normal file
52
app/src/main/res/layout/select_identity_row.xml
Normal file
@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2016 Christian Basler
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dp">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/checkbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:ellipsize="end"
|
||||
android:paddingBottom="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingTop="8dp"
|
||||
android:text="CheckBox"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
tools:text="Name"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/address"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:ellipsize="marquee"
|
||||
android:lines="1"
|
||||
android:paddingBottom="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:paddingStart="48dp"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
tools:text="BM-2cW0000000000000000000000000000000"/>
|
||||
|
||||
</RelativeLayout>
|
25
app/src/main/res/menu/import_input_data.xml
Normal file
25
app/src/main/res/menu/import_input_data.xml
Normal file
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2016 Christian Basler
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/open_file"
|
||||
android:title="@string/open_file"
|
||||
android:icon="@drawable/ic_action_open_file"
|
||||
app:showAsAction="ifRoom"/>
|
||||
</menu>
|
@ -81,4 +81,19 @@ Als Alternative kann in den Einstellungen ein vertrauenswürdiger Knoten konfigu
|
||||
<string name="toast_chan_created">Chan erstellt</string>
|
||||
<string name="toast_long_running_operation">Dies kann einige Minuten dauern</string>
|
||||
<string name="toast_identity_created">Identität erstellt</string>
|
||||
</resources>
|
||||
<string name="toast_identities_created">Identitäten erstellt</string>
|
||||
<string name="import_identity">Importieren</string>
|
||||
<string name="create_identity">Erstellen</string>
|
||||
<string name="add_deterministic_address">Deterministische Identität</string>
|
||||
<string name="deterministic_address_warning">Merke dir diese Enstellungen und stelle sicher dass sie korrekt sind wenn du eine deterministische Addresse wiederherstellst.</string>
|
||||
<string name="shorter">Kürzere Adressen suchen</string>
|
||||
<string name="number_of_identities">Anzahl zu generierender Identitäten</string>
|
||||
<string name="title_import_identity">Identität importieren</string>
|
||||
<string name="wif_string">WIF / Inhalt von \'keys.dat\'</string>
|
||||
<string name="select_identities_to_import">Bitte wähle die zu importierenden Identitäten:</string>
|
||||
<string name="select_file_title">Datei auswählen</string>
|
||||
<string name="open_file">Datei öffnen</string>
|
||||
<string name="next">Weiter</string>
|
||||
<string name="import_input_description">Du kannst einfach den Inhalt eines Exports oder einer \'keys.dat\'-Datei einfügen</string>
|
||||
<string name="error_loading_data">Fehler beim Laden der Daten</string>
|
||||
</resources>
|
||||
|
@ -14,6 +14,9 @@
|
||||
<string name="manage_identity">Manage Identity</string>
|
||||
<string name="add_identity">Add Identity</string>
|
||||
<string name="add_identity_summary">Create new identity</string>
|
||||
<string name="create_identity">Create new</string>
|
||||
<string name="import_identity">Import existing</string>
|
||||
<string name="add_deterministic_address">Deterministic identity</string>
|
||||
<string name="add_chan">Add Chan</string>
|
||||
<string name="add_chan_summary">Add or create a chan</string>
|
||||
<string name="title_activity_open_bitmessage_link">Import Contact</string>
|
||||
@ -80,8 +83,20 @@ As an alternative you could configure a trusted node in the settings, but as of
|
||||
<string name="export">Export</string>
|
||||
<string name="confirm_export">Do you really want to export your identity? The export will contain the unencrypted private keys.</string>
|
||||
<string name="compose_message">Compose</string>
|
||||
<string name="passphrase">passphrase</string>
|
||||
<string name="passphrase">Passphrase</string>
|
||||
<string name="toast_long_running_operation">This may take a few minutes</string>
|
||||
<string name="toast_identity_created">Identity created</string>
|
||||
<string name="toast_identities_created">Identities created</string>
|
||||
<string name="toast_chan_created">Chan created</string>
|
||||
<string name="deterministic_address_warning">Be sure to remember those settings correctly when recreating a deterministic address.</string>
|
||||
<string name="number_of_identities">Number of identities to create</string>
|
||||
<string name="shorter">Search for shorter addresses</string>
|
||||
<string name="wif_string">WIF / contents of \'keys.dat\'</string>
|
||||
<string name="next">Continue</string>
|
||||
<string name="title_import_identity">Import Identity</string>
|
||||
<string name="open_file">Open File</string>
|
||||
<string name="error_loading_data">Error loading data</string>
|
||||
<string name="select_file_title">Select a File</string>
|
||||
<string name="select_identities_to_import">Please select the identities you want to import:</string>
|
||||
<string name="import_input_description">You can just paste the contents of an export or a \'keys.dat\' file</string>
|
||||
</resources>
|
||||
|
@ -19,4 +19,7 @@
|
||||
<item name="android:textColor">@color/colorAccent</item>
|
||||
</style>
|
||||
|
||||
<style name="FixedDialog" parent="Theme.AppCompat.Light.Dialog">
|
||||
<item name="windowNoTitle">false</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
@ -9,7 +9,7 @@ buildscript {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:2.1.3'
|
||||
classpath 'com.android.tools.build:gradle:2.2.0'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
Loading…
Reference in New Issue
Block a user