Fixed the 'full node' switch, activated the jack tools to support some Java 8 features, and fixed some lint issues
This commit is contained in:
parent
a5b3c33394
commit
2b1fb436a9
@ -5,10 +5,11 @@ ext {
|
||||
appName = "Abit"
|
||||
}
|
||||
if (project.hasProperty("project.configs")
|
||||
&& new File(project.property("project.configs") + appName + ".gradle").exists()) {
|
||||
&& new File(project.property("project.configs") + appName + ".gradle").exists()) {
|
||||
apply from: project.property("project.configs") + appName + ".gradle";
|
||||
}
|
||||
|
||||
//noinspection GroovyMissingReturnStatement
|
||||
android {
|
||||
compileSdkVersion 24
|
||||
buildToolsVersion "24.0.3"
|
||||
@ -19,17 +20,23 @@ android {
|
||||
targetSdkVersion 24
|
||||
versionCode 9
|
||||
versionName "1.0-beta9"
|
||||
jackOptions.enabled = true
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
minifyEnabled true
|
||||
shrinkResources true
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
signingConfig signingConfigs.release
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ext.jabitVersion = '2.0.1'
|
||||
ext.jabitVersion = '2.0.2'
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
compile 'com.android.support:appcompat-v7:24.2.1'
|
||||
@ -58,8 +65,8 @@ dependencies {
|
||||
compile 'com.google.zxing:core:3.3.0'
|
||||
compile 'io.github.yavski:fab-speed-dial:1.0.4'
|
||||
compile 'com.github.amlcurran.showcaseview:library:5.4.3'
|
||||
compile ('com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:0.9.3@aar'){
|
||||
transitive=true
|
||||
compile('com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:0.9.3@aar') {
|
||||
transitive = true
|
||||
}
|
||||
compile 'com.github.angads25:filepicker:1.0.6'
|
||||
|
||||
|
@ -23,7 +23,6 @@ import android.view.View;
|
||||
import android.widget.ListView;
|
||||
|
||||
import ch.dissem.apps.abit.listener.ListSelectionListener;
|
||||
import ch.dissem.bitmessage.entity.valueobject.Label;
|
||||
|
||||
/**
|
||||
* @author Christian Basler
|
||||
@ -38,11 +37,7 @@ public abstract class AbstractItemListFragment<T> extends ListFragment implement
|
||||
* A dummy implementation of the {@link ListSelectionListener} interface that does
|
||||
* nothing. Used only when this fragment is not attached to an activity.
|
||||
*/
|
||||
private static ListSelectionListener<Object> dummyCallbacks = new
|
||||
ListSelectionListener<Object>() {
|
||||
@Override
|
||||
public void onItemSelected(Object plaintext) {
|
||||
}
|
||||
private static ListSelectionListener<Object> dummyCallbacks = plaintext -> {
|
||||
};
|
||||
/**
|
||||
* The fragment's current callback object, which is notified of list item
|
||||
@ -61,7 +56,7 @@ public abstract class AbstractItemListFragment<T> extends ListFragment implement
|
||||
|
||||
// Restore the previously serialized activated item position.
|
||||
if (savedInstanceState != null
|
||||
&& savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) {
|
||||
&& savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) {
|
||||
setActivatedPosition(savedInstanceState.getInt(STATE_ACTIVATED_POSITION));
|
||||
}
|
||||
}
|
||||
@ -73,8 +68,8 @@ public abstract class AbstractItemListFragment<T> extends ListFragment implement
|
||||
// When setting CHOICE_MODE_SINGLE, ListView will automatically
|
||||
// give items the 'activated' state when touched.
|
||||
getListView().setChoiceMode(activateOnItemClick
|
||||
? ListView.CHOICE_MODE_SINGLE
|
||||
: ListView.CHOICE_MODE_NONE);
|
||||
? ListView.CHOICE_MODE_SINGLE
|
||||
: ListView.CHOICE_MODE_NONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -129,8 +124,8 @@ public abstract class AbstractItemListFragment<T> extends ListFragment implement
|
||||
// When setting CHOICE_MODE_SINGLE, ListView will automatically
|
||||
// give items the 'activated' state when touched.
|
||||
getListView().setChoiceMode(activateOnItemClick
|
||||
? ListView.CHOICE_MODE_SINGLE
|
||||
: ListView.CHOICE_MODE_NONE);
|
||||
? ListView.CHOICE_MODE_SINGLE
|
||||
: ListView.CHOICE_MODE_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,6 @@ package ch.dissem.apps.abit;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Bundle;
|
||||
@ -31,7 +30,6 @@ import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Switch;
|
||||
import android.widget.TextView;
|
||||
@ -131,19 +129,15 @@ public class AddressDetailFragment extends Fragment {
|
||||
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);
|
||||
MainActivity mainActivity = MainActivity.getInstance();
|
||||
if (item.getPrivateKey() != null && mainActivity != null) {
|
||||
mainActivity.removeIdentityEntry(item);
|
||||
}
|
||||
item = null;
|
||||
ctx.onBackPressed();
|
||||
}
|
||||
})
|
||||
.setPositiveButton(android.R.string.yes, (dialog, 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;
|
||||
@ -151,22 +145,18 @@ public class AddressDetailFragment extends Fragment {
|
||||
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));
|
||||
}
|
||||
})
|
||||
.setPositiveButton(android.R.string.yes, (dialog, 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;
|
||||
@ -216,12 +206,8 @@ public class AddressDetailFragment extends Fragment {
|
||||
if (item.getPrivateKey() == null) {
|
||||
Switch active = (Switch) rootView.findViewById(R.id.active);
|
||||
active.setChecked(item.isSubscribed());
|
||||
active.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
item.setSubscribed(isChecked);
|
||||
}
|
||||
});
|
||||
active.setOnCheckedChangeListener((buttonView, isChecked) ->
|
||||
item.setSubscribed(isChecked));
|
||||
|
||||
ImageView pubkeyAvailableImg = (ImageView) rootView.findViewById(R.id
|
||||
.pubkey_available);
|
||||
|
@ -20,6 +20,7 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
@ -32,7 +33,6 @@ import android.widget.TextView;
|
||||
import com.google.zxing.integration.android.IntentIntegrator;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import ch.dissem.apps.abit.listener.ActionBarListener;
|
||||
@ -55,59 +55,53 @@ public class AddressListFragment extends AbstractItemListFragment<BitmessageAddr
|
||||
|
||||
public void updateList() {
|
||||
List<BitmessageAddress> addresses = Singleton.getAddressRepository(getContext())
|
||||
.getContacts();
|
||||
Collections.sort(addresses, new Comparator<BitmessageAddress>() {
|
||||
/**
|
||||
* Yields the following order:
|
||||
* <ol>
|
||||
* <li>Subscribed addresses come first</li>
|
||||
* <li>Addresses with Aliases (alphabetically)</li>
|
||||
* <li>Addresses (alphabetically)</li>
|
||||
* </ol>
|
||||
*/
|
||||
@Override
|
||||
public int compare(BitmessageAddress lhs, BitmessageAddress rhs) {
|
||||
if (lhs.isSubscribed() == rhs.isSubscribed()) {
|
||||
if (lhs.getAlias() != null) {
|
||||
if (rhs.getAlias() != null) {
|
||||
return lhs.getAlias().compareTo(rhs.getAlias());
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else if (rhs.getAlias() != null) {
|
||||
return 1;
|
||||
.getContacts();
|
||||
Collections.sort(addresses, (lhs, rhs) -> {
|
||||
// Yields the following order:
|
||||
// * Subscribed addresses come first
|
||||
// * Addresses with Aliases (alphabetically)
|
||||
// * Addresses (alphabetically)
|
||||
if (lhs.isSubscribed() == rhs.isSubscribed()) {
|
||||
if (lhs.getAlias() != null) {
|
||||
if (rhs.getAlias() != null) {
|
||||
return lhs.getAlias().compareTo(rhs.getAlias());
|
||||
} else {
|
||||
return lhs.getAddress().compareTo(rhs.getAddress());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (lhs.isSubscribed()) {
|
||||
return -1;
|
||||
} else {
|
||||
} else if (rhs.getAlias() != null) {
|
||||
return 1;
|
||||
} else {
|
||||
return lhs.getAddress().compareTo(rhs.getAddress());
|
||||
}
|
||||
}
|
||||
if (lhs.isSubscribed()) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
setListAdapter(new ArrayAdapter<BitmessageAddress>(
|
||||
getActivity(),
|
||||
android.R.layout.simple_list_item_activated_1,
|
||||
android.R.id.text1,
|
||||
addresses) {
|
||||
getActivity(),
|
||||
android.R.layout.simple_list_item_activated_1,
|
||||
android.R.id.text1,
|
||||
addresses) {
|
||||
@NonNull
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
public View getView(int position, View convertView, @NonNull ViewGroup parent) {
|
||||
if (convertView == null) {
|
||||
LayoutInflater inflater = LayoutInflater.from(getContext());
|
||||
convertView = inflater.inflate(R.layout.subscription_row, null, false);
|
||||
convertView = inflater.inflate(R.layout.subscription_row, parent, false);
|
||||
}
|
||||
BitmessageAddress item = getItem(position);
|
||||
((ImageView) convertView.findViewById(R.id.avatar)).setImageDrawable(new
|
||||
Identicon(item));
|
||||
Identicon(item));
|
||||
TextView name = (TextView) convertView.findViewById(R.id.name);
|
||||
name.setText(item.toString());
|
||||
TextView streamNumber = (TextView) convertView.findViewById(R.id.stream_number);
|
||||
streamNumber.setText(getContext().getString(R.string.stream_number, item
|
||||
.getStream()));
|
||||
.getStream()));
|
||||
convertView.findViewById(R.id.subscribed).setVisibility(item.isSubscribed() ?
|
||||
View.VISIBLE : View.INVISIBLE);
|
||||
View.VISIBLE : View.INVISIBLE);
|
||||
return convertView;
|
||||
}
|
||||
});
|
||||
@ -124,7 +118,7 @@ public class AddressListFragment extends AbstractItemListFragment<BitmessageAddr
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
|
||||
savedInstanceState) {
|
||||
savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_address_list, container, false);
|
||||
|
||||
FabSpeedDial fabSpeedDial = (FabSpeedDial) view.findViewById(R.id.fab_add_contact);
|
||||
@ -134,8 +128,8 @@ public class AddressListFragment extends AbstractItemListFragment<BitmessageAddr
|
||||
switch (menuItem.getItemId()) {
|
||||
case R.id.action_read_qr_code:
|
||||
IntentIntegrator.forSupportFragment(AddressListFragment.this)
|
||||
.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE_TYPES)
|
||||
.initiateScan();
|
||||
.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE_TYPES)
|
||||
.initiateScan();
|
||||
return true;
|
||||
case R.id.action_create_contact:
|
||||
Intent intent = new Intent(getActivity(), CreateAddressActivity.class);
|
||||
|
@ -18,7 +18,6 @@ package ch.dissem.apps.abit;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.text.Selection;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
@ -90,12 +89,9 @@ public class ComposeMessageFragment extends Fragment {
|
||||
recipientInput = (AutoCompleteTextView) rootView.findViewById(R.id.recipient);
|
||||
final ContactAdapter adapter = new ContactAdapter(getContext());
|
||||
recipientInput.setAdapter(adapter);
|
||||
recipientInput.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
recipient = adapter.getItem(position);
|
||||
}
|
||||
});
|
||||
recipientInput.setOnItemClickListener(
|
||||
(parent, view, position, id) -> recipient = adapter.getItem(position)
|
||||
);
|
||||
recipientInput.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
|
@ -42,9 +42,6 @@ import ch.dissem.bitmessage.wif.WifImporter;
|
||||
|
||||
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;
|
||||
|
||||
@ -53,14 +50,15 @@ public class ImportIdentitiesFragment extends Fragment {
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
|
||||
savedInstanceState) {
|
||||
String wifData = getArguments().getString(WIF_DATA);
|
||||
bmc = Singleton.getBitmessageContext(getActivity());
|
||||
BitmessageContext 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,
|
||||
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity(),
|
||||
LinearLayoutManager.VERTICAL,
|
||||
false);
|
||||
recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
|
||||
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
|
||||
recyclerView.setLayoutManager(layoutManager);
|
||||
recyclerView.setAdapter(adapter);
|
||||
|
||||
@ -69,18 +67,15 @@ public class ImportIdentitiesFragment extends Fragment {
|
||||
} 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);
|
||||
}
|
||||
view.findViewById(R.id.finish).setOnClickListener(v -> {
|
||||
importer.importAll(adapter.getSelected());
|
||||
MainActivity mainActivity = MainActivity.getInstance();
|
||||
if (mainActivity != null) {
|
||||
for (BitmessageAddress selected : adapter.getSelected()) {
|
||||
mainActivity.addIdentityEntry(selected);
|
||||
}
|
||||
getActivity().finish();
|
||||
}
|
||||
getActivity().finish();
|
||||
});
|
||||
return view;
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ package ch.dissem.apps.abit;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.graphics.Point;
|
||||
@ -34,7 +33,6 @@ import android.widget.CompoundButton;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import com.github.amlcurran.showcaseview.ShowcaseView;
|
||||
import com.github.amlcurran.showcaseview.targets.Target;
|
||||
import com.mikepenz.community_material_typeface_library.CommunityMaterial;
|
||||
import com.mikepenz.google_material_typeface_library.GoogleMaterial;
|
||||
import com.mikepenz.iconics.IconicsDrawable;
|
||||
@ -42,7 +40,6 @@ import com.mikepenz.materialdrawer.AccountHeader;
|
||||
import com.mikepenz.materialdrawer.AccountHeaderBuilder;
|
||||
import com.mikepenz.materialdrawer.Drawer;
|
||||
import com.mikepenz.materialdrawer.DrawerBuilder;
|
||||
import com.mikepenz.materialdrawer.interfaces.OnCheckedChangeListener;
|
||||
import com.mikepenz.materialdrawer.model.DividerDrawerItem;
|
||||
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem;
|
||||
import com.mikepenz.materialdrawer.model.ProfileDrawerItem;
|
||||
@ -102,7 +99,8 @@ public class MainActivity extends AppCompatActivity
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MainActivity.class);
|
||||
private static final int ADD_IDENTITY = 1;
|
||||
private static final int MANAGE_IDENTITY = 2;
|
||||
private static final int ADD_CHAN = 3;
|
||||
|
||||
private static final long ID_NODE_SWITCH = 1;
|
||||
|
||||
private static WeakReference<MainActivity> instance;
|
||||
|
||||
@ -134,7 +132,7 @@ public class MainActivity extends AppCompatActivity
|
||||
private AccountHeader accountHeader;
|
||||
|
||||
private Drawer drawer;
|
||||
private ShowcaseView showcaseView;
|
||||
private SwitchDrawerItem nodeSwitch;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@ -152,7 +150,9 @@ public class MainActivity extends AppCompatActivity
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
MessageListFragment listFragment = new MessageListFragment();
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.item_list, listFragment)
|
||||
getSupportFragmentManager()
|
||||
.beginTransaction()
|
||||
.replace(R.id.item_list, listFragment)
|
||||
.commit();
|
||||
|
||||
if (findViewById(R.id.message_detail_container) != null) {
|
||||
@ -189,27 +189,23 @@ public class MainActivity extends AppCompatActivity
|
||||
int margin = ((Number) (getResources().getDisplayMetrics().density * 12)).intValue();
|
||||
lps.setMargins(margin, margin, margin, margin);
|
||||
|
||||
showcaseView = new ShowcaseView.Builder(this)
|
||||
new ShowcaseView.Builder(this)
|
||||
.withMaterialShowcase()
|
||||
.setStyle(R.style.CustomShowcaseTheme)
|
||||
.setContentTitle(R.string.full_node)
|
||||
.setContentText(R.string.full_node_description)
|
||||
.setTarget(new Target() {
|
||||
@Override
|
||||
public Point getPoint() {
|
||||
View view = drawer.getStickyFooter();
|
||||
int[] location = new int[2];
|
||||
view.getLocationInWindow(location);
|
||||
int x = location[0] + 7 * view.getWidth() / 8;
|
||||
int y = location[1] + view.getHeight() / 2;
|
||||
return new Point(x, y);
|
||||
}
|
||||
}
|
||||
)
|
||||
.setTarget(() -> {
|
||||
View view = drawer.getStickyFooter();
|
||||
int[] location = new int[2];
|
||||
view.getLocationInWindow(location);
|
||||
int x = location[0] + 7 * view.getWidth() / 8;
|
||||
int y = location[1] + view.getHeight() / 2;
|
||||
return new Point(x, y);
|
||||
})
|
||||
.replaceEndButton(R.layout.showcase_button)
|
||||
.hideOnTouchOutside()
|
||||
.build();
|
||||
showcaseView.setButtonPosition(lps);
|
||||
.build()
|
||||
.setButtonPosition(lps);
|
||||
}
|
||||
}
|
||||
|
||||
@ -268,32 +264,28 @@ public class MainActivity extends AppCompatActivity
|
||||
.withActivity(this)
|
||||
.withHeaderBackground(R.drawable.header)
|
||||
.withProfiles(profiles)
|
||||
.withOnAccountHeaderListener(new AccountHeader.OnAccountHeaderListener() {
|
||||
@Override
|
||||
public boolean onProfileChanged(View view, IProfile profile, boolean
|
||||
currentProfile) {
|
||||
switch ((int) profile.getIdentifier()) {
|
||||
case ADD_IDENTITY:
|
||||
addIdentityDialog();
|
||||
break;
|
||||
case MANAGE_IDENTITY:
|
||||
Intent show = new Intent(MainActivity.this,
|
||||
AddressDetailActivity.class);
|
||||
show.putExtra(AddressDetailFragment.ARG_ITEM,
|
||||
Singleton.getIdentity(getApplicationContext()));
|
||||
startActivity(show);
|
||||
break;
|
||||
default:
|
||||
if (profile instanceof ProfileDrawerItem) {
|
||||
Object tag = ((ProfileDrawerItem) profile).getTag();
|
||||
if (tag instanceof BitmessageAddress) {
|
||||
Singleton.setIdentity((BitmessageAddress) tag);
|
||||
}
|
||||
.withOnAccountHeaderListener((view, profile, currentProfile) -> {
|
||||
switch ((int) profile.getIdentifier()) {
|
||||
case ADD_IDENTITY:
|
||||
addIdentityDialog();
|
||||
break;
|
||||
case MANAGE_IDENTITY:
|
||||
Intent show = new Intent(MainActivity.this,
|
||||
AddressDetailActivity.class);
|
||||
show.putExtra(AddressDetailFragment.ARG_ITEM,
|
||||
Singleton.getIdentity(getApplicationContext()));
|
||||
startActivity(show);
|
||||
break;
|
||||
default:
|
||||
if (profile instanceof ProfileDrawerItem) {
|
||||
Object tag = ((ProfileDrawerItem) profile).getTag();
|
||||
if (tag instanceof BitmessageAddress) {
|
||||
Singleton.setIdentity((BitmessageAddress) tag);
|
||||
}
|
||||
}
|
||||
// false if it should close the drawer
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// false if it should close the drawer
|
||||
return false;
|
||||
})
|
||||
.build();
|
||||
if (profiles.size() > 2) { // There's always the add and manage identity items
|
||||
@ -346,62 +338,55 @@ public class MainActivity extends AppCompatActivity
|
||||
.withName(R.string.settings)
|
||||
.withIcon(GoogleMaterial.Icon.gmd_settings));
|
||||
|
||||
nodeSwitch = new SwitchDrawerItem()
|
||||
.withIdentifier(ID_NODE_SWITCH)
|
||||
.withName(R.string.full_node)
|
||||
.withIcon(CommunityMaterial.Icon.cmd_cloud_outline)
|
||||
.withChecked(isRunning())
|
||||
.withOnCheckedChangeListener((drawerItem, buttonView, isChecked) -> {
|
||||
if (isChecked) {
|
||||
checkAndStartNode(buttonView);
|
||||
} else {
|
||||
service.shutdownNode();
|
||||
}
|
||||
});
|
||||
|
||||
drawer = new DrawerBuilder()
|
||||
.withActivity(this)
|
||||
.withToolbar(toolbar)
|
||||
.withAccountHeader(accountHeader)
|
||||
.withDrawerItems(drawerItems)
|
||||
.addStickyDrawerItems(
|
||||
new SwitchDrawerItem()
|
||||
.withName(R.string.full_node)
|
||||
.withIcon(CommunityMaterial.Icon.cmd_cloud_outline)
|
||||
.withChecked(isRunning())
|
||||
.withOnCheckedChangeListener(new OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(IDrawerItem drawerItem,
|
||||
CompoundButton buttonView,
|
||||
boolean isChecked) {
|
||||
if (isChecked) {
|
||||
checkAndStartNode(buttonView);
|
||||
} else {
|
||||
service.shutdownNode();
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
.withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() {
|
||||
@Override
|
||||
public boolean onItemClick(View view, int position, IDrawerItem item) {
|
||||
if (item.getTag() instanceof Label) {
|
||||
selectedLabel = (Label) item.getTag();
|
||||
showSelectedLabel();
|
||||
return false;
|
||||
} else if (item instanceof Nameable<?>) {
|
||||
Nameable<?> ni = (Nameable<?>) item;
|
||||
switch (ni.getName().getTextRes()) {
|
||||
case R.string.contacts_and_subscriptions:
|
||||
if (!(getSupportFragmentManager().findFragmentById(R.id
|
||||
.item_list) instanceof AddressListFragment)) {
|
||||
changeList(new AddressListFragment());
|
||||
} else {
|
||||
((AddressListFragment) getSupportFragmentManager()
|
||||
.findFragmentById(R.id.item_list)).updateList();
|
||||
}
|
||||
break;
|
||||
case R.string.settings:
|
||||
startActivity(new Intent(MainActivity.this, SettingsActivity
|
||||
.class));
|
||||
break;
|
||||
case R.string.archive:
|
||||
selectedLabel = null;
|
||||
showSelectedLabel();
|
||||
break;
|
||||
case R.string.full_node:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
.addStickyDrawerItems(nodeSwitch)
|
||||
.withOnDrawerItemClickListener((view, position, item) -> {
|
||||
if (item.getTag() instanceof Label) {
|
||||
selectedLabel = (Label) item.getTag();
|
||||
showSelectedLabel();
|
||||
return false;
|
||||
} else if (item instanceof Nameable<?>) {
|
||||
Nameable<?> ni = (Nameable<?>) item;
|
||||
switch (ni.getName().getTextRes()) {
|
||||
case R.string.contacts_and_subscriptions:
|
||||
if (!(getSupportFragmentManager().findFragmentById(R.id
|
||||
.item_list) instanceof AddressListFragment)) {
|
||||
changeList(new AddressListFragment());
|
||||
} else {
|
||||
((AddressListFragment) getSupportFragmentManager()
|
||||
.findFragmentById(R.id.item_list)).updateList();
|
||||
}
|
||||
break;
|
||||
case R.string.settings:
|
||||
startActivity(new Intent(MainActivity.this, SettingsActivity
|
||||
.class));
|
||||
break;
|
||||
case R.string.archive:
|
||||
selectedLabel = null;
|
||||
showSelectedLabel();
|
||||
break;
|
||||
case R.string.full_node:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
})
|
||||
.withShowDrawerOnFirstLaunch(true)
|
||||
.build();
|
||||
@ -415,6 +400,7 @@ public class MainActivity extends AppCompatActivity
|
||||
@Override
|
||||
protected void onResume() {
|
||||
updateUnread();
|
||||
updateNodeSwitch();
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
@ -470,18 +456,14 @@ public class MainActivity extends AppCompatActivity
|
||||
} else {
|
||||
new AlertDialog.Builder(MainActivity.this)
|
||||
.setMessage(R.string.full_node_warning)
|
||||
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
service.startupNode();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
buttonView.setChecked(false);
|
||||
}
|
||||
})
|
||||
.setPositiveButton(
|
||||
android.R.string.yes,
|
||||
(dialog, which) -> service.startupNode()
|
||||
)
|
||||
.setNegativeButton(
|
||||
android.R.string.no,
|
||||
(dialog, which) -> updateNodeSwitch()
|
||||
)
|
||||
.show();
|
||||
}
|
||||
}
|
||||
@ -501,6 +483,13 @@ public class MainActivity extends AppCompatActivity
|
||||
}
|
||||
}
|
||||
|
||||
public void updateNodeSwitch() {
|
||||
runOnUiThread(() -> {
|
||||
nodeSwitch.withChecked(bmc.isRunning());
|
||||
drawer.updateStickyFooterItem(nodeSwitch);
|
||||
});
|
||||
}
|
||||
|
||||
private void showSelectedLabel() {
|
||||
if (getSupportFragmentManager().findFragmentById(R.id.item_list) instanceof
|
||||
MessageListFragment) {
|
||||
|
@ -1,8 +1,6 @@
|
||||
package ch.dissem.apps.abit;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
|
||||
/**
|
||||
* @author Christian Basler
|
||||
|
@ -20,7 +20,6 @@ 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;
|
||||
@ -41,7 +40,6 @@ import ch.dissem.bitmessage.entity.payload.Pubkey;
|
||||
/**
|
||||
* @author Christian Basler
|
||||
*/
|
||||
|
||||
public class DeterministicIdentityDialogFragment extends AppCompatDialogFragment {
|
||||
private BitmessageContext bmc;
|
||||
|
||||
@ -58,76 +56,68 @@ public class DeterministicIdentityDialogFragment extends AppCompatDialogFragment
|
||||
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);
|
||||
.setOnClickListener(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;
|
||||
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) {
|
||||
messageRes = R.string.toast_identity_created;
|
||||
identity.setAlias(label);
|
||||
} else {
|
||||
messageRes = R.string.toast_identities_created;
|
||||
identity.setAlias(label + " (" + i + ")");
|
||||
}
|
||||
Toast.makeText(context,
|
||||
messageRes,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
MainActivity mainActivity = MainActivity.getInstance();
|
||||
if (mainActivity != null) {
|
||||
for (BitmessageAddress identity : identities) {
|
||||
mainActivity.addIdentityEntry(identity);
|
||||
}
|
||||
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()
|
||||
);
|
||||
}
|
||||
}
|
||||
}.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();
|
||||
}
|
||||
});
|
||||
.setOnClickListener(v -> dismiss());
|
||||
return view;
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,6 @@
|
||||
package ch.dissem.apps.abit.notification;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Notification;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@ -28,7 +27,7 @@ import java.util.TimerTask;
|
||||
|
||||
import ch.dissem.apps.abit.MainActivity;
|
||||
import ch.dissem.apps.abit.R;
|
||||
import ch.dissem.bitmessage.BitmessageContext;
|
||||
import ch.dissem.apps.abit.service.BitmessageService;
|
||||
import ch.dissem.bitmessage.utils.Property;
|
||||
|
||||
/**
|
||||
@ -37,31 +36,32 @@ import ch.dissem.bitmessage.utils.Property;
|
||||
public class NetworkNotification extends AbstractNotification {
|
||||
public static final int ONGOING_NOTIFICATION_ID = 2;
|
||||
|
||||
private final BitmessageContext bmc;
|
||||
private NotificationCompat.Builder builder;
|
||||
|
||||
public NetworkNotification(Context ctx, BitmessageContext bmc) {
|
||||
public NetworkNotification(Context ctx) {
|
||||
super(ctx);
|
||||
this.bmc = bmc;
|
||||
Intent showMessageIntent = new Intent(ctx, MainActivity.class);
|
||||
PendingIntent pendingIntent = PendingIntent.getActivity(ctx, 1, showMessageIntent, 0);
|
||||
builder = new NotificationCompat.Builder(ctx);
|
||||
builder.setSmallIcon(R.drawable.ic_notification_full_node)
|
||||
.setContentTitle(ctx.getString(R.string.bitmessage_full_node))
|
||||
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Notification getNotification() {
|
||||
update();
|
||||
return notification;
|
||||
.setContentTitle(ctx.getString(R.string.bitmessage_full_node))
|
||||
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
||||
.setShowWhen(false)
|
||||
.setContentIntent(pendingIntent);
|
||||
}
|
||||
|
||||
@SuppressLint("StringFormatMatches")
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
private boolean update() {
|
||||
boolean running = bmc.isRunning();
|
||||
boolean running = BitmessageService.isRunning();
|
||||
builder.setOngoing(running);
|
||||
Property connections = bmc.status().getProperty("network").getProperty("connections");
|
||||
Property connections = BitmessageService.getStatus().getProperty("network", "connections");
|
||||
if (!running) {
|
||||
builder.setContentText(ctx.getString(R.string.connection_info_disconnected));
|
||||
MainActivity mainActivity = MainActivity.getInstance();
|
||||
if (mainActivity != null) {
|
||||
mainActivity.updateNodeSwitch();
|
||||
}
|
||||
} else if (connections.getProperties().length == 0) {
|
||||
builder.setContentText(ctx.getString(R.string.connection_info_pending));
|
||||
} else {
|
||||
@ -71,29 +71,24 @@ public class NetworkNotification extends AbstractNotification {
|
||||
Integer nodeCount = (Integer) stream.getProperty("nodes").getValue();
|
||||
if (nodeCount == 1) {
|
||||
info.append(ctx.getString(R.string.connection_info_1,
|
||||
streamNumber));
|
||||
streamNumber));
|
||||
} else {
|
||||
info.append(ctx.getString(R.string.connection_info_n,
|
||||
streamNumber, nodeCount));
|
||||
streamNumber, nodeCount));
|
||||
}
|
||||
info.append('\n');
|
||||
}
|
||||
builder.setContentText(info);
|
||||
}
|
||||
Intent showMessageIntent = new Intent(ctx, MainActivity.class);
|
||||
PendingIntent pendingIntent = PendingIntent.getActivity(ctx, 1, showMessageIntent, 0);
|
||||
builder.setContentIntent(pendingIntent);
|
||||
notification = builder.build();
|
||||
return running;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show() {
|
||||
update();
|
||||
super.show();
|
||||
|
||||
final Timer timer = new Timer();
|
||||
timer.schedule(new TimerTask() {
|
||||
new Timer().schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!update()) {
|
||||
@ -108,4 +103,10 @@ public class NetworkNotification extends AbstractNotification {
|
||||
protected int getNotificationId() {
|
||||
return ONGOING_NOTIFICATION_ID;
|
||||
}
|
||||
|
||||
public void connecting() {
|
||||
builder.setOngoing(true);
|
||||
builder.setContentText(ctx.getString(R.string.connection_info_pending));
|
||||
notification = builder.build();
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ import ch.dissem.bitmessage.entity.Plaintext;
|
||||
import static ch.dissem.apps.abit.util.Drawables.toBitmap;
|
||||
|
||||
public class NewMessageNotification extends AbstractNotification {
|
||||
public static final int NEW_MESSAGE_NOTIFICATION_ID = 1;
|
||||
private static final int NEW_MESSAGE_NOTIFICATION_ID = 1;
|
||||
private static final StyleSpan SPAN_EMPHASIS = new StyleSpan(Typeface.BOLD);
|
||||
|
||||
public NewMessageNotification(Context ctx) {
|
||||
@ -62,6 +62,7 @@ public class NewMessageNotification extends AbstractNotification {
|
||||
PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
builder.setContentIntent(pendingIntent);
|
||||
|
||||
// TODO: add proper intents to reply/delete
|
||||
builder.addAction(R.drawable.ic_action_reply, ctx.getString(R.string.reply), pendingIntent);
|
||||
builder.addAction(R.drawable.ic_action_delete, ctx.getString(R.string.delete),
|
||||
pendingIntent);
|
||||
|
@ -196,7 +196,9 @@ public class AndroidAddressRepository implements AddressRepository {
|
||||
SQLiteDatabase db = sql.getWritableDatabase();
|
||||
// Create a new map of values, where column names are the keys
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(COLUMN_ALIAS, address.getAlias());
|
||||
if (address.getAlias() != null) {
|
||||
values.put(COLUMN_ALIAS, address.getAlias());
|
||||
}
|
||||
if (address.getPubkey() != null) {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
address.getPubkey().writeUnencrypted(out);
|
||||
@ -207,7 +209,9 @@ public class AndroidAddressRepository implements AddressRepository {
|
||||
if (address.getPrivateKey() != null) {
|
||||
values.put(COLUMN_PRIVATE_KEY, Encode.bytes(address.getPrivateKey()));
|
||||
}
|
||||
values.put(COLUMN_CHAN, address.isChan());
|
||||
if (address.isChan()) {
|
||||
values.put(COLUMN_CHAN, true);
|
||||
}
|
||||
values.put(COLUMN_SUBSCRIBED, address.isSubscribed());
|
||||
|
||||
int update = db.update(TABLE_NAME, values, "address=?",
|
||||
|
@ -33,7 +33,6 @@ import ch.dissem.bitmessage.entity.ObjectMessage;
|
||||
import ch.dissem.bitmessage.factory.Factory;
|
||||
import ch.dissem.bitmessage.ports.ProofOfWorkRepository;
|
||||
import ch.dissem.bitmessage.utils.Encode;
|
||||
import ch.dissem.bitmessage.utils.Strings;
|
||||
|
||||
import static ch.dissem.bitmessage.utils.Singleton.cryptography;
|
||||
import static ch.dissem.bitmessage.utils.Strings.hex;
|
||||
|
@ -21,11 +21,9 @@ import android.content.Intent;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ch.dissem.apps.abit.notification.NetworkNotification;
|
||||
import ch.dissem.bitmessage.BitmessageContext;
|
||||
import ch.dissem.bitmessage.utils.Property;
|
||||
|
||||
import static ch.dissem.apps.abit.notification.NetworkNotification.ONGOING_NOTIFICATION_ID;
|
||||
|
||||
@ -35,12 +33,7 @@ import static ch.dissem.apps.abit.notification.NetworkNotification.ONGOING_NOTIF
|
||||
* onPerformSync().
|
||||
*/
|
||||
public class BitmessageService extends Service {
|
||||
public static final Logger LOG = LoggerFactory.getLogger(BitmessageService.class);
|
||||
|
||||
// Object to use as a thread-safe lock
|
||||
private static final Object lock = new Object();
|
||||
|
||||
private static NetworkNotification notification = null;
|
||||
private NetworkNotification notification = null;
|
||||
private static BitmessageContext bmc = null;
|
||||
|
||||
private static volatile boolean running = false;
|
||||
@ -51,11 +44,11 @@ public class BitmessageService extends Service {
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
synchronized (lock) {
|
||||
synchronized (BitmessageService.class) {
|
||||
if (bmc == null) {
|
||||
bmc = Singleton.getBitmessageContext(this);
|
||||
notification = new NetworkNotification(this, bmc);
|
||||
}
|
||||
notification = new NetworkNotification(this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,7 +63,6 @@ public class BitmessageService extends Service {
|
||||
running = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return an object that allows the system to invoke
|
||||
* the sync adapter.
|
||||
@ -84,6 +76,7 @@ public class BitmessageService extends Service {
|
||||
public void startupNode() {
|
||||
startService(new Intent(BitmessageService.this, BitmessageService.class));
|
||||
running = true;
|
||||
notification.connecting();
|
||||
startForeground(ONGOING_NOTIFICATION_ID, notification.getNotification());
|
||||
if (!bmc.isRunning()) {
|
||||
bmc.startup();
|
||||
@ -96,8 +89,17 @@ public class BitmessageService extends Service {
|
||||
bmc.shutdown();
|
||||
}
|
||||
running = false;
|
||||
stopForeground(false);
|
||||
stopForeground(true);
|
||||
notification.show();
|
||||
stopSelf();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Property getStatus() {
|
||||
if (bmc != null) {
|
||||
return bmc.status();
|
||||
} else {
|
||||
return new Property("bitmessage context", null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ public class ProofOfWorkService extends Service {
|
||||
private static ProofOfWorkEngine engine = new MultiThreadedPOWEngine();
|
||||
private static boolean calculating;
|
||||
private static final Queue<PowItem> queue = new LinkedList<>();
|
||||
private static ProofOfWorkNotification notification;
|
||||
private ProofOfWorkNotification notification;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
@ -55,16 +55,18 @@ public class ProofOfWorkService extends Service {
|
||||
|
||||
public static class PowBinder extends Binder {
|
||||
private final ProofOfWorkService service;
|
||||
private final ProofOfWorkNotification notification;
|
||||
|
||||
private PowBinder(ProofOfWorkService service) {
|
||||
this.service = service;
|
||||
this.notification = service.notification;
|
||||
}
|
||||
|
||||
public void process(PowItem item) {
|
||||
void process(PowItem item) {
|
||||
synchronized (queue) {
|
||||
service.startService(new Intent(service, ProofOfWorkService.class));
|
||||
service.startForeground(ONGOING_NOTIFICATION_ID,
|
||||
notification.getNotification());
|
||||
notification.getNotification());
|
||||
if (!calculating) {
|
||||
calculating = true;
|
||||
service.calculateNonce(item);
|
||||
@ -90,28 +92,25 @@ public class ProofOfWorkService extends Service {
|
||||
}
|
||||
|
||||
private void calculateNonce(final PowItem item) {
|
||||
engine.calculateNonce(item.initialHash, item.targetValue, new ProofOfWorkEngine.Callback() {
|
||||
@Override
|
||||
public void onNonceCalculated(byte[] initialHash, byte[] nonce) {
|
||||
try {
|
||||
item.callback.onNonceCalculated(initialHash, nonce);
|
||||
} finally {
|
||||
PowItem item;
|
||||
synchronized (queue) {
|
||||
item = queue.poll();
|
||||
if (item == null) {
|
||||
calculating = false;
|
||||
stopForeground(true);
|
||||
stopSelf();
|
||||
} else {
|
||||
notification.update(queue.size()).show();
|
||||
}
|
||||
}
|
||||
if (item != null) {
|
||||
calculateNonce(item);
|
||||
engine.calculateNonce(item.initialHash, item.targetValue, (initialHash, nonce) -> {
|
||||
try {
|
||||
item.callback.onNonceCalculated(initialHash, nonce);
|
||||
} finally {
|
||||
PowItem next;
|
||||
synchronized (queue) {
|
||||
next = queue.poll();
|
||||
if (next == null) {
|
||||
calculating = false;
|
||||
stopForeground(true);
|
||||
stopSelf();
|
||||
} else {
|
||||
notification.update(queue.size()).show();
|
||||
}
|
||||
}
|
||||
if (next != null) {
|
||||
calculateNonce(next);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,6 @@ import static ch.dissem.bitmessage.utils.UnixTime.DAY;
|
||||
* Provides singleton objects across the application.
|
||||
*/
|
||||
public class Singleton {
|
||||
public static final Object lock = new Object();
|
||||
private static BitmessageContext bitmessageContext;
|
||||
private static MessageListener messageListener;
|
||||
private static BitmessageAddress identity;
|
||||
@ -54,28 +53,28 @@ public class Singleton {
|
||||
|
||||
public static BitmessageContext getBitmessageContext(Context context) {
|
||||
if (bitmessageContext == null) {
|
||||
synchronized (lock) {
|
||||
synchronized (Singleton.class) {
|
||||
if (bitmessageContext == null) {
|
||||
final Context ctx = context.getApplicationContext();
|
||||
SqlHelper sqlHelper = new SqlHelper(ctx);
|
||||
powRepo = new AndroidProofOfWorkRepository(sqlHelper);
|
||||
TTL.pubkey(2 * DAY);
|
||||
bitmessageContext = new BitmessageContext.Builder()
|
||||
.proofOfWorkEngine(new SwitchingProofOfWorkEngine(
|
||||
ctx, Constants.PREFERENCE_SERVER_POW,
|
||||
new ServerPowEngine(ctx),
|
||||
new ServicePowEngine(ctx)
|
||||
))
|
||||
.cryptography(new AndroidCryptography())
|
||||
.nodeRegistry(new AndroidNodeRegistry(sqlHelper))
|
||||
.inventory(new AndroidInventory(sqlHelper))
|
||||
.addressRepo(new AndroidAddressRepository(sqlHelper))
|
||||
.messageRepo(new AndroidMessageRepository(sqlHelper, ctx))
|
||||
.powRepo(powRepo)
|
||||
.networkHandler(new NioNetworkHandler())
|
||||
.listener(getMessageListener(ctx))
|
||||
.doNotSendPubkeyOnIdentityCreation()
|
||||
.build();
|
||||
.proofOfWorkEngine(new SwitchingProofOfWorkEngine(
|
||||
ctx, Constants.PREFERENCE_SERVER_POW,
|
||||
new ServerPowEngine(ctx),
|
||||
new ServicePowEngine(ctx)
|
||||
))
|
||||
.cryptography(new AndroidCryptography())
|
||||
.nodeRegistry(new AndroidNodeRegistry(sqlHelper))
|
||||
.inventory(new AndroidInventory(sqlHelper))
|
||||
.addressRepo(new AndroidAddressRepository(sqlHelper))
|
||||
.messageRepo(new AndroidMessageRepository(sqlHelper, ctx))
|
||||
.powRepo(powRepo)
|
||||
.networkHandler(new NioNetworkHandler())
|
||||
.listener(getMessageListener(ctx))
|
||||
.doNotSendPubkeyOnIdentityCreation()
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -108,11 +107,12 @@ public class Singleton {
|
||||
|
||||
public static BitmessageAddress getIdentity(Context ctx) {
|
||||
if (identity == null) {
|
||||
BitmessageContext bmc = getBitmessageContext(ctx);
|
||||
synchronized (Singleton.class) {
|
||||
if (identity == null) {
|
||||
BitmessageContext bmc = getBitmessageContext(ctx);
|
||||
// FIXME: this may block the UI, there must be a better way!
|
||||
List<BitmessageAddress> identities = bmc.addresses()
|
||||
.getIdentities();
|
||||
.getIdentities();
|
||||
if (identities.size() > 0) {
|
||||
identity = identities.get(0);
|
||||
} else {
|
||||
|
@ -25,7 +25,6 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import ch.dissem.apps.abit.R;
|
||||
import ch.dissem.apps.abit.listener.WifiReceiver;
|
||||
@ -39,8 +38,6 @@ import static ch.dissem.apps.abit.util.Constants.PREFERENCE_WIFI_ONLY;
|
||||
* @author Christian Basler
|
||||
*/
|
||||
public class Preferences {
|
||||
private static Logger LOG = LoggerFactory.getLogger(Preferences.class);
|
||||
|
||||
public static boolean useTrustedNode(Context ctx) {
|
||||
String trustedNode = getPreference(ctx, PREFERENCE_TRUSTED_NODE);
|
||||
return trustedNode != null && !trustedNode.trim().isEmpty();
|
||||
|
@ -51,7 +51,8 @@
|
||||
android:layout_margin="16dp"
|
||||
android:background="@color/contentBackground"
|
||||
android:elevation="2dp"
|
||||
tools:layout="@layout/fragment_message_detail"/>
|
||||
tools:layout="@layout/fragment_message_detail"
|
||||
tools:ignore="InconsistentLayout,UnusedAttribute"/>
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
@ -15,7 +15,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/to"
|
||||
android:inputType="textNoSuggestions"
|
||||
android:singleLine="true"/>
|
||||
android:maxLines="1"/>
|
||||
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
@ -43,4 +43,4 @@
|
||||
android:inputType="textMultiLine|textCapSentences"
|
||||
android:scrollbars="vertical"/>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
@ -1,14 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Button xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Got it"
|
||||
android:textStyle="bold"
|
||||
android:background="@drawable/material_showcase_button_bg"
|
||||
android:textSize="13sp"
|
||||
android:text="Got it"
|
||||
android:textAllCaps="true"
|
||||
android:textColor="@android:color/white"
|
||||
>
|
||||
|
||||
</Button>
|
||||
android:textSize="13sp"
|
||||
android:textStyle="bold">
|
||||
</Button>
|
||||
|
@ -34,10 +34,11 @@
|
||||
|
||||
<TextView
|
||||
android:id="@+id/name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignTop="@+id/avatar"
|
||||
android:layout_toEndOf="@+id/avatar"
|
||||
android:layout_toStartOf="@+id/subscribed"
|
||||
android:ellipsize="end"
|
||||
android:lines="1"
|
||||
android:paddingBottom="0dp"
|
||||
@ -60,7 +61,8 @@
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingRight="8dp"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
tools:text="Stream #"/>
|
||||
tools:text="Stream #"
|
||||
tools:ignore="RelativeOverlap"/>
|
||||
|
||||
<com.mikepenz.iconics.view.IconicsImageView
|
||||
android:id="@+id/subscribed"
|
||||
|
@ -5,19 +5,15 @@
|
||||
<string name="title_message_detail">Nachricht</string>
|
||||
<string name="title_subscription_detail">Abonnement</string>
|
||||
<string name="bitmessage_full_node">Bitmessage Netzknoten</string>
|
||||
<string name="wifi_mode">Art der WLAN-Verbindung</string>
|
||||
<string name="settings">Einstellungen</string>
|
||||
<string name="wifi_only">Nur WLAN</string>
|
||||
<string name="wifi_only_summary">Nicht mit Mobilfunknetz verbinden</string>
|
||||
<string name="subscriptions">Abonnements</string>
|
||||
<string name="to">An</string>
|
||||
<string name="subject">Betreff</string>
|
||||
<string name="manage_identity">Identität verwalten</string>
|
||||
<string name="add_identity">Identität hinzufügen</string>
|
||||
<string name="add_identity_summary">Eine neue Identität erstellen</string>
|
||||
<string name="create_identity">Erstellen</string>
|
||||
<string name="create_identity_description">Eine neue, zufällige Identität erstellen</string>
|
||||
<string name="import_identity">Importieren</string>
|
||||
<string name="import_identity_description">Eine existierende Identität von PyBitmessage oder einem Export importieren</string>
|
||||
<string name="add_deterministic_address">Deterministische Identität</string>
|
||||
<string name="add_deterministic_address_description">Eine deterministische Identität erstellen oder wiederherstellen</string>
|
||||
@ -25,11 +21,8 @@
|
||||
<string name="add_chan_description">Einen Chan erstellen oder einem beitreten</string>
|
||||
<string name="title_activity_open_bitmessage_link">Kontakt importieren</string>
|
||||
|
||||
<string name="action_settings">Einstellungen</string>
|
||||
<string name="connection_info_1">Stream %1$d: eine Verbindung</string>
|
||||
<string name="connection_info_n">Stream %1$d: %2$d Verbindungen</string>
|
||||
<string name="import_address">Adresse importieren</string>
|
||||
<string name="import_contact">Kontakt hinzufügen</string>
|
||||
<string name="label">Label</string>
|
||||
<string name="subscribe">Abonnieren</string>
|
||||
<string name="do_import">Importieren</string>
|
||||
@ -42,7 +35,6 @@
|
||||
<string name="archive">Archiv</string>
|
||||
<string name="empty_trash">Papierkorb leeren</string>
|
||||
<string name="stream_number">Stream %d</string>
|
||||
<string name="enabled">Aktiv</string>
|
||||
<string name="trusted_node">Vertrauenswürdiger Knoten</string>
|
||||
<string name="trusted_node_summary">Diese Adresse wird für die Synchronisation verwendet</string>
|
||||
<string name="sync_timeout">Zeitbeschränkung der Synchronisierung</string>
|
||||
@ -56,7 +48,6 @@
|
||||
<string name="proof_of_work_text_0">Arbeite am Versenden</string>
|
||||
<string name="proof_of_work_text_n">Arbeite am Versenden (%1$d in Warteschlange)</string>
|
||||
<string name="error_invalid_sync_port">Ungültiger Port in den Synchronisationseinstellungen: %s</string>
|
||||
<string name="error_invalid_sync_host">Synchronisation fehlgeschlagen: der vertrauenswürdige Knoten konnte nicht erreicht werden.</string>
|
||||
<string name="compose_body_hint">Nachricht schreiben</string>
|
||||
<string name="contacts_and_subscriptions">Kontakte</string>
|
||||
<string name="subscribed">Abonniert</string>
|
||||
@ -78,10 +69,9 @@
|
||||
<string name="delete_contact_warning">Bist Du sicher dass dieser Kontakt gelöscht werden soll?</string>
|
||||
<string name="scan_qr_code">QR-Code scannen</string>
|
||||
<string name="create_contact">Kontakt erfassen</string>
|
||||
<string name="full_node_description">Solange kein aktiver Knoten gestartet ist, werden keine Meldungen empfangen oder gesendet. Dies braucht jedoch viele Resourcen und Daten.
|
||||
<string name="full_node_description">Solange kein aktiver Knoten gestartet ist, werden keine Meldungen empfangen oder gesendet. Dies braucht jedoch viele Ressourcen und Daten.
|
||||
|
||||
Als Alternative kann in den Einstellungen ein vertrauenswürdiger Knoten konfiguriert werden, aber im Moment muss dieser selbst bereitgestellt werden.</string>
|
||||
<string name="got_it">Alles klar</string>
|
||||
<string name="address">Bitmessage-Adresse</string>
|
||||
<string name="error_illegal_address">Vielleicht hat es einen Tippfehler</string>
|
||||
<string name="export">Exportieren</string>
|
||||
@ -95,7 +85,7 @@ Als Alternative kann in den Einstellungen ein vertrauenswürdiger Knoten konfigu
|
||||
<string name="toast_identity_created">Identität erstellt</string>
|
||||
<string name="toast_identities_created">Identitäten erstellt</string>
|
||||
<string name="toast_chan_created">Chan erstellt</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="deterministic_address_warning">Merke dir diese Enstellungen und stelle sicher dass sie korrekt sind wenn du eine deterministische Adresse wiederherstellst.</string>
|
||||
<string name="number_of_identities">Anzahl zu generierender Identitäten</string>
|
||||
<string name="shorter">Kürzere Adressen suchen</string>
|
||||
<string name="wif_string">WIF / Inhalt von ‘keys.dat’</string>
|
||||
@ -106,5 +96,4 @@ Als Alternative kann in den Einstellungen ein vertrauenswürdiger Knoten konfigu
|
||||
<string name="select_file_title">Datei auswählen</string>
|
||||
<string name="select_identities_to_import">Bitte wähle die zu importierenden Identitäten:</string>
|
||||
<string name="import_input_description">Du kannst einfach den Inhalt eines Exports oder einer ‘keys.dat’-Datei einfügen</string>
|
||||
<string name="name">Name</string>
|
||||
</resources>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Palette generated by Material Palette - materialpalette.com/blue-grey/orange -->
|
||||
<resources>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="UnusedResources">
|
||||
<color name="colorPrimary">#FFC107</color>
|
||||
<color name="colorPrimaryDark">#FFA000</color>
|
||||
<color name="colorPrimaryDarkText">#DEFFFFFF</color>
|
||||
|
@ -15,7 +15,7 @@
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="UnusedResources">
|
||||
<string name="define_fab_speed_dial" translatable="false"/>
|
||||
<!-- Author section -->
|
||||
<string name="library_fab_speed_dial_author" translatable="false">Yavor Ivanov</string>
|
||||
|
@ -1,21 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<resources>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="UnusedResources">
|
||||
<string name="define_int_filepicker" translatable="false"/>
|
||||
<!-- Author section -->
|
||||
<string name="library_filepicker_author" translatable="false">Angad Singh</string>
|
||||
<string name="library_filepicker_authorWebsite" translatable="false">https://github.com/Angads25</string>
|
||||
<!-- Library section -->
|
||||
<string name="library_filepicker_libraryName" translatable="false">FilePicker</string>
|
||||
<string name="library_filepicker_libraryDescription">Android Library to select files/directories from Device Storage.</string>
|
||||
<string name="library_filepicker_libraryWebsite" translatable="false">https://github.com/Angads25/android-filepicker</string>
|
||||
<string name="library_filepicker_libraryVersion" translatable="false">1.0.6</string>
|
||||
<!-- OpenSource section -->
|
||||
<string name="library_filepicker_isOpenSource" translatable="false">true</string>
|
||||
<string name="library_filepicker_repositoryLink" translatable="false">https://github.com/Angads25/android-filepicker</string>
|
||||
<!-- ClassPath for autoDetect section -->
|
||||
<string name="library_filepicker_classPath" translatable="false">com.github.angads25.filepicker.view.FilePickerDialog</string>
|
||||
<!-- License section -->
|
||||
<string name="library_filepicker_licenseId" translatable="false">apache_2_0</string>
|
||||
<!-- Custom variables section -->
|
||||
<!-- Author section -->
|
||||
<string name="library_filepicker_author" translatable="false">Angad Singh</string>
|
||||
<string name="library_filepicker_authorWebsite" translatable="false">https://github.com/Angads25</string>
|
||||
<!-- Library section -->
|
||||
<string name="library_filepicker_libraryName" translatable="false">FilePicker</string>
|
||||
<string name="library_filepicker_libraryDescription">Android Library to select files/directories from Device Storage.</string>
|
||||
<string name="library_filepicker_libraryWebsite" translatable="false">https://github.com/Angads25/android-filepicker</string>
|
||||
<string name="library_filepicker_libraryVersion" translatable="false">1.0.6</string>
|
||||
<!-- OpenSource section -->
|
||||
<string name="library_filepicker_isOpenSource" translatable="false">true</string>
|
||||
<string name="library_filepicker_repositoryLink" translatable="false">https://github.com/Angads25/android-filepicker</string>
|
||||
<!-- ClassPath for autoDetect section -->
|
||||
<string name="library_filepicker_classPath" translatable="false">com.github.angads25.filepicker.view.FilePickerDialog</string>
|
||||
<!-- License section -->
|
||||
<string name="library_filepicker_licenseId" translatable="false">apache_2_0</string>
|
||||
<!-- Custom variables section -->
|
||||
</resources>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="UnusedResources">
|
||||
<string name="define_jabit" translatable="false"/>
|
||||
<!-- Author section -->
|
||||
<string name="library_jabit_author" translatable="false">Christian Basler</string>
|
||||
|
@ -15,7 +15,7 @@
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="UnusedResources">
|
||||
<string name="define_zxing" translatable="false"/>
|
||||
<!-- Author section -->
|
||||
<string name="library_zxing_author" translatable="false">Google, Inc.</string>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<resources>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="UnusedResources">
|
||||
<string name="define_int_zxingandroidembedded" translatable="false"/>
|
||||
<!-- Author section -->
|
||||
<string name="library_zxingandroidembedded_author" translatable="false">JourneyApps</string>
|
||||
|
@ -1,22 +1,18 @@
|
||||
<resources>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<string name="app_name">Abit</string>
|
||||
<string name="about_app">A Bitmessage client for Android</string>
|
||||
<string name="title_message_detail">Message Detail</string>
|
||||
<string name="title_subscription_detail">Subscription Detail</string>
|
||||
<string name="bitmessage_full_node">Bitmessage Node</string>
|
||||
<string name="wifi_mode">Wi-Fi Connection Mode</string>
|
||||
<string name="settings">Settings</string>
|
||||
<string name="wifi_only">Wi-Fi only</string>
|
||||
<string name="wifi_only_summary">Don\'t connect to the mobile network</string>
|
||||
<string name="subscriptions">Subscriptions</string>
|
||||
<string name="to">To</string>
|
||||
<string name="subject">Subject</string>
|
||||
<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="create_identity_description">Create a new, random identity</string>
|
||||
<string name="import_identity">Import existing</string>
|
||||
<string name="import_identity_description">Import an existing identity from PyBitmessage or from an export</string>
|
||||
<string name="add_deterministic_address">Deterministic identity</string>
|
||||
<string name="add_deterministic_address_description">Create or recreate a deterministic identity</string>
|
||||
@ -24,24 +20,20 @@
|
||||
<string name="add_chan_description">Create or join a chan</string>
|
||||
<string name="title_activity_open_bitmessage_link">Import Contact</string>
|
||||
|
||||
<string name="action_settings">Settings</string>
|
||||
<string name="connection_info_1">Stream #%1$d: one connection</string>
|
||||
<string name="connection_info_n">Stream #%1$d: %2$d connections</string>
|
||||
<string name="import_address">Import Address</string>
|
||||
<string name="import_contact">Add to contacts</string>
|
||||
<string name="connection_info_n" tools:ignore="PluralsCandidate">Stream #%1$d: %2$d connections</string>
|
||||
<string name="label">Label</string>
|
||||
<string name="subscribe">Subscribe</string>
|
||||
<string name="do_import">Import</string>
|
||||
<string name="cancel">Cancel</string>
|
||||
<string name="broadcast">Broadcast</string>
|
||||
<string name="n_new_messages">%d new messages</string>
|
||||
<string name="n_new_messages" tools:ignore="PluralsCandidate">%d new messages</string>
|
||||
<string name="reply">Reply</string>
|
||||
<string name="delete">Delete</string>
|
||||
<string name="mark_unread">Mark unread</string>
|
||||
<string name="archive">Archive</string>
|
||||
<string name="empty_trash">Empty Trash</string>
|
||||
<string name="stream_number">Stream #%d</string>
|
||||
<string name="enabled">Enabled</string>
|
||||
<string name="trusted_node">Trusted node</string>
|
||||
<string name="trusted_node_summary">Use this node for synchronization</string>
|
||||
<string name="sync_timeout">Synchronization Timeout</string>
|
||||
@ -53,9 +45,8 @@
|
||||
<string name="connection_info_pending">Connecting…</string>
|
||||
<string name="proof_of_work_title">Proof of Work</string>
|
||||
<string name="proof_of_work_text_0">Doing work to send message</string>
|
||||
<string name="proof_of_work_text_n">Doing work to send message (%1$d queued)</string>
|
||||
<string name="proof_of_work_text_n" tools:ignore="PluralsCandidate">Doing work to send message (%1$d queued)</string>
|
||||
<string name="error_invalid_sync_port">Invalid port in synchronization settings: %s</string>
|
||||
<string name="error_invalid_sync_host">Synchronization failed: Trusted node could not be reached.</string>
|
||||
<string name="compose_body_hint">Write message</string>
|
||||
<string name="contacts_and_subscriptions">Contacts</string>
|
||||
<string name="subscribed">Subscribed</string>
|
||||
@ -80,7 +71,6 @@
|
||||
<string name="full_node_description">You can\'t receive or send messages unless you start a full node. But be aware that this uses a lot of resources and internet traffic.
|
||||
|
||||
As an alternative you could configure a trusted node in the settings, but as of now you\'ll need to deploy your own.</string>
|
||||
<string name="got_it">Got it</string>
|
||||
<string name="address">Bitmessage Address</string>
|
||||
<string name="error_illegal_address">There might be a typo</string>
|
||||
<string name="export">Export</string>
|
||||
@ -105,5 +95,4 @@ As an alternative you could configure a trusted node in the settings, but as of
|
||||
<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>
|
||||
<string name="name">Name</string>
|
||||
</resources>
|
||||
|
@ -9,7 +9,7 @@ buildscript {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:2.2.0'
|
||||
classpath 'com.android.tools.build:gradle:2.2.1'
|
||||
|
||||
// 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