Disabled Jack

I'd love to use Java 8 features, but Jack just isn't ready yet.
This commit is contained in:
Christian Basler 2016-11-03 23:04:41 +01:00
parent 9af80f008d
commit b34e678c68
20 changed files with 499 additions and 364 deletions

View File

@ -20,11 +20,11 @@ android {
targetSdkVersion 25 targetSdkVersion 25
versionCode 9 versionCode 9
versionName "1.0-beta9" versionName "1.0-beta9"
jackOptions.enabled = true jackOptions.enabled = false
} }
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_7
} }
buildTypes { buildTypes {
release { release {

View File

@ -37,8 +37,13 @@ public abstract class AbstractItemListFragment<T> extends ListFragment implement
* A dummy implementation of the {@link ListSelectionListener} interface that does * A dummy implementation of the {@link ListSelectionListener} interface that does
* nothing. Used only when this fragment is not attached to an activity. * nothing. Used only when this fragment is not attached to an activity.
*/ */
private static final ListSelectionListener<Object> dummyCallbacks = plaintext -> { private static final ListSelectionListener<Object> dummyCallbacks =
}; new ListSelectionListener<Object>() {
@Override
public void onItemSelected(Object item) {
// NO OP
}
};
/** /**
* The fragment's current callback object, which is notified of list item * The fragment's current callback object, which is notified of list item
* clicks. * clicks.

View File

@ -18,6 +18,7 @@ package ch.dissem.apps.abit;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.os.Bundle; import android.os.Bundle;
@ -31,6 +32,7 @@ import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.Switch; import android.widget.Switch;
import android.widget.TextView; import android.widget.TextView;
@ -137,14 +139,17 @@ public class AddressDetailFragment extends Fragment {
warning = R.string.delete_contact_warning; warning = R.string.delete_contact_warning;
new AlertDialog.Builder(ctx) new AlertDialog.Builder(ctx)
.setMessage(warning) .setMessage(warning)
.setPositiveButton(android.R.string.yes, (dialog, which) -> { .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
Singleton.getAddressRepository(ctx).remove(item); @Override
MainActivity mainActivity = MainActivity.getInstance(); public void onClick(DialogInterface dialog, int which) {
if (item.getPrivateKey() != null && mainActivity != null) { Singleton.getAddressRepository(ctx).remove(item);
mainActivity.removeIdentityEntry(item); MainActivity mainActivity = MainActivity.getInstance();
if (item.getPrivateKey() != null && mainActivity != null) {
mainActivity.removeIdentityEntry(item);
}
item = null;
ctx.onBackPressed();
} }
item = null;
ctx.onBackPressed();
}) })
.setNegativeButton(android.R.string.no, null) .setNegativeButton(android.R.string.no, null)
.show(); .show();
@ -153,17 +158,20 @@ public class AddressDetailFragment extends Fragment {
case R.id.export: { case R.id.export: {
new AlertDialog.Builder(ctx) new AlertDialog.Builder(ctx)
.setMessage(R.string.confirm_export) .setMessage(R.string.confirm_export)
.setPositiveButton(android.R.string.yes, (dialog, which) -> { .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
Intent shareIntent = new Intent(Intent.ACTION_SEND); @Override
shareIntent.setType("text/plain"); public void onClick(DialogInterface dialog, int which) {
shareIntent.putExtra(Intent.EXTRA_TITLE, item + Intent shareIntent = new Intent(Intent.ACTION_SEND);
EXPORT_POSTFIX); shareIntent.setType("text/plain");
WifExporter exporter = new WifExporter(Singleton shareIntent.putExtra(Intent.EXTRA_TITLE, item +
.getBitmessageContext(ctx)); EXPORT_POSTFIX);
exporter.addIdentity(item); WifExporter exporter = new WifExporter(Singleton
shareIntent.putExtra(Intent.EXTRA_TEXT, exporter.toString .getBitmessageContext(ctx));
()); exporter.addIdentity(item);
startActivity(Intent.createChooser(shareIntent, null)); shareIntent.putExtra(Intent.EXTRA_TEXT, exporter.toString
());
startActivity(Intent.createChooser(shareIntent, null));
}
}) })
.setNegativeButton(android.R.string.no, null) .setNegativeButton(android.R.string.no, null)
.show(); .show();
@ -225,8 +233,12 @@ public class AddressDetailFragment extends Fragment {
if (item.getPrivateKey() == null) { if (item.getPrivateKey() == null) {
Switch active = (Switch) rootView.findViewById(R.id.active); Switch active = (Switch) rootView.findViewById(R.id.active);
active.setChecked(item.isSubscribed()); active.setChecked(item.isSubscribed());
active.setOnCheckedChangeListener((buttonView, isChecked) -> active.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
item.setSubscribed(isChecked)); @Override
public void onCheckedChanged(CompoundButton button, boolean checked) {
item.setSubscribed(checked);
}
});
ImageView pubkeyAvailableImg = (ImageView) rootView.findViewById(R.id ImageView pubkeyAvailableImg = (ImageView) rootView.findViewById(R.id
.pubkey_available); .pubkey_available);

View File

@ -33,6 +33,7 @@ import android.widget.TextView;
import com.google.zxing.integration.android.IntentIntegrator; import com.google.zxing.integration.android.IntentIntegrator;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.List; import java.util.List;
import ch.dissem.apps.abit.listener.ActionBarListener; import ch.dissem.apps.abit.listener.ActionBarListener;
@ -56,28 +57,31 @@ public class AddressListFragment extends AbstractItemListFragment<BitmessageAddr
public void updateList() { public void updateList() {
List<BitmessageAddress> addresses = Singleton.getAddressRepository(getContext()) List<BitmessageAddress> addresses = Singleton.getAddressRepository(getContext())
.getContacts(); .getContacts();
Collections.sort(addresses, (lhs, rhs) -> { Collections.sort(addresses, new Comparator<BitmessageAddress>() {
// Yields the following order: @Override
// * Subscribed addresses come first public int compare(BitmessageAddress lhs, BitmessageAddress rhs) {
// * Addresses with Aliases (alphabetically) // Yields the following order:
// * Addresses (alphabetically) // * Subscribed addresses come first
if (lhs.isSubscribed() == rhs.isSubscribed()) { // * Addresses with Aliases (alphabetically)
if (lhs.getAlias() != null) { // * Addresses (alphabetically)
if (rhs.getAlias() != null) { if (lhs.isSubscribed() == rhs.isSubscribed()) {
return lhs.getAlias().compareTo(rhs.getAlias()); if (lhs.getAlias() != null) {
if (rhs.getAlias() != null) {
return lhs.getAlias().compareTo(rhs.getAlias());
} else {
return -1;
}
} else if (rhs.getAlias() != null) {
return 1;
} else { } else {
return -1; return lhs.getAddress().compareTo(rhs.getAddress());
} }
} else if (rhs.getAlias() != null) {
return 1;
} else {
return lhs.getAddress().compareTo(rhs.getAddress());
} }
} if (lhs.isSubscribed()) {
if (lhs.isSubscribed()) { return -1;
return -1; } else {
} else { return 1;
return 1; }
} }
}); });
setListAdapter(new ArrayAdapter<BitmessageAddress>( setListAdapter(new ArrayAdapter<BitmessageAddress>(

View File

@ -96,7 +96,12 @@ public class ComposeMessageFragment extends Fragment {
final ContactAdapter adapter = new ContactAdapter(getContext()); final ContactAdapter adapter = new ContactAdapter(getContext());
recipientInput.setAdapter(adapter); recipientInput.setAdapter(adapter);
recipientInput.setOnItemClickListener( recipientInput.setOnItemClickListener(
(parent, view, position, id) -> recipient = adapter.getItem(position) new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
adapter.getItem(pos);
}
}
); );
recipientInput.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { recipientInput.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override @Override

View File

@ -20,6 +20,7 @@ import android.app.Activity;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.Switch; import android.widget.Switch;
@ -60,28 +61,34 @@ public class CreateAddressActivity extends AppCompatActivity {
} }
final Button cancel = (Button) findViewById(R.id.cancel); final Button cancel = (Button) findViewById(R.id.cancel);
cancel.setOnClickListener(v -> { cancel.setOnClickListener(new View.OnClickListener() {
setResult(Activity.RESULT_CANCELED); @Override
finish(); public void onClick(View view) {
setResult(Activity.RESULT_CANCELED);
finish();
}
}); });
final Button ok = (Button) findViewById(R.id.do_import); final Button ok = (Button) findViewById(R.id.do_import);
ok.setOnClickListener(v -> { ok.setOnClickListener(new View.OnClickListener() {
String addressText = String.valueOf(address.getText()).trim(); @Override
try { public void onClick(View view) {
BitmessageAddress bmAddress = new BitmessageAddress(addressText); String addressText = String.valueOf(address.getText()).trim();
bmAddress.setAlias(label.getText().toString()); try {
BitmessageAddress bmAddress = new BitmessageAddress(addressText);
bmAddress.setAlias(label.getText().toString());
BitmessageContext bmc = Singleton.getBitmessageContext BitmessageContext bmc = Singleton.getBitmessageContext
(CreateAddressActivity.this); (CreateAddressActivity.this);
bmc.addContact(bmAddress); bmc.addContact(bmAddress);
if (subscribe.isChecked()) { if (subscribe.isChecked()) {
bmc.addSubscribtion(bmAddress); bmc.addSubscribtion(bmAddress);
}
setResult(Activity.RESULT_OK);
finish();
} catch (RuntimeException e) {
address.setError(getString(R.string.error_illegal_address));
} }
setResult(Activity.RESULT_OK);
finish();
} catch (RuntimeException e) {
address.setError(getString(R.string.error_illegal_address));
} }
}); });
} }

View File

@ -67,15 +67,18 @@ public class ImportIdentitiesFragment extends Fragment {
} catch (IOException e) { } catch (IOException e) {
return super.onCreateView(inflater, container, savedInstanceState); return super.onCreateView(inflater, container, savedInstanceState);
} }
view.findViewById(R.id.finish).setOnClickListener(v -> { view.findViewById(R.id.finish).setOnClickListener(new View.OnClickListener() {
importer.importAll(adapter.getSelected()); @Override
MainActivity mainActivity = MainActivity.getInstance(); public void onClick(View view) {
if (mainActivity != null) { importer.importAll(adapter.getSelected());
for (BitmessageAddress selected : adapter.getSelected()) { MainActivity mainActivity = MainActivity.getInstance();
mainActivity.addIdentityEntry(selected); if (mainActivity != null) {
for (BitmessageAddress selected : adapter.getSelected()) {
mainActivity.addIdentityEntry(selected);
}
} }
getActivity().finish();
} }
getActivity().finish();
}); });
return view; return view;
} }

View File

@ -28,6 +28,7 @@ import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.github.angads25.filepicker.controller.DialogSelectionListener;
import com.github.angads25.filepicker.model.DialogConfigs; import com.github.angads25.filepicker.model.DialogConfigs;
import com.github.angads25.filepicker.model.DialogProperties; import com.github.angads25.filepicker.model.DialogProperties;
import com.github.angads25.filepicker.view.FilePickerDialog; import com.github.angads25.filepicker.view.FilePickerDialog;
@ -60,16 +61,19 @@ public class InputWifFragment extends Fragment {
View view = inflater.inflate(R.layout.fragment_import_input, container, false); View view = inflater.inflate(R.layout.fragment_import_input, container, false);
wifData = (TextView) view.findViewById(R.id.wif_input); wifData = (TextView) view.findViewById(R.id.wif_input);
view.findViewById(R.id.next).setOnClickListener(v -> { view.findViewById(R.id.next).setOnClickListener(new View.OnClickListener() {
Bundle bundle = new Bundle(); @Override
bundle.putString(WIF_DATA, wifData.getText().toString()); public void onClick(View view) {
Bundle bundle = new Bundle();
bundle.putString(WIF_DATA, wifData.getText().toString());
ImportIdentitiesFragment fragment = new ImportIdentitiesFragment(); ImportIdentitiesFragment fragment = new ImportIdentitiesFragment();
fragment.setArguments(bundle); fragment.setArguments(bundle);
getFragmentManager().beginTransaction() getFragmentManager().beginTransaction()
.replace(R.id.content, fragment) .replace(R.id.content, fragment)
.commit(); .commit();
}
}); });
return view; return view;
} }
@ -89,23 +93,26 @@ public class InputWifFragment extends Fragment {
properties.extensions = null; properties.extensions = null;
FilePickerDialog dialog = new FilePickerDialog(getActivity(), properties); FilePickerDialog dialog = new FilePickerDialog(getActivity(), properties);
dialog.setTitle(getString(R.string.select_file_title)); dialog.setTitle(getString(R.string.select_file_title));
dialog.setDialogSelectionListener(files -> { dialog.setDialogSelectionListener(new DialogSelectionListener() {
if (files.length > 0) { @Override
try (InputStream in = new FileInputStream(files[0])) { public void onSelectedFilePaths(String[] files) {
ByteArrayOutputStream data = new ByteArrayOutputStream(); if (files.length > 0) {
byte[] buffer = new byte[1024]; try (InputStream in = new FileInputStream(files[0])) {
int length; ByteArrayOutputStream data = new ByteArrayOutputStream();
//noinspection ConstantConditions byte[] buffer = new byte[1024];
while ((length = in.read(buffer)) != -1) { int length;
data.write(buffer, 0, 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();
} }
wifData.setText(data.toString("UTF-8"));
} catch (IOException e) {
Toast.makeText(
getActivity(),
R.string.error_loading_data,
Toast.LENGTH_SHORT
).show();
} }
} }
}); });

View File

@ -24,10 +24,12 @@ import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.RelativeLayout; import android.widget.RelativeLayout;
import android.widget.Toast; import android.widget.Toast;
import com.github.amlcurran.showcaseview.ShowcaseView; import com.github.amlcurran.showcaseview.ShowcaseView;
import com.github.amlcurran.showcaseview.targets.Target;
import com.mikepenz.community_material_typeface_library.CommunityMaterial; import com.mikepenz.community_material_typeface_library.CommunityMaterial;
import com.mikepenz.google_material_typeface_library.GoogleMaterial; import com.mikepenz.google_material_typeface_library.GoogleMaterial;
import com.mikepenz.iconics.IconicsDrawable; import com.mikepenz.iconics.IconicsDrawable;
@ -35,6 +37,7 @@ import com.mikepenz.materialdrawer.AccountHeader;
import com.mikepenz.materialdrawer.AccountHeaderBuilder; import com.mikepenz.materialdrawer.AccountHeaderBuilder;
import com.mikepenz.materialdrawer.Drawer; import com.mikepenz.materialdrawer.Drawer;
import com.mikepenz.materialdrawer.DrawerBuilder; import com.mikepenz.materialdrawer.DrawerBuilder;
import com.mikepenz.materialdrawer.interfaces.OnCheckedChangeListener;
import com.mikepenz.materialdrawer.model.DividerDrawerItem; import com.mikepenz.materialdrawer.model.DividerDrawerItem;
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem; import com.mikepenz.materialdrawer.model.PrimaryDrawerItem;
import com.mikepenz.materialdrawer.model.ProfileDrawerItem; import com.mikepenz.materialdrawer.model.ProfileDrawerItem;
@ -182,13 +185,16 @@ public class MainActivity extends AppCompatActivity
.setStyle(R.style.CustomShowcaseTheme) .setStyle(R.style.CustomShowcaseTheme)
.setContentTitle(R.string.full_node) .setContentTitle(R.string.full_node)
.setContentText(R.string.full_node_description) .setContentText(R.string.full_node_description)
.setTarget(() -> { .setTarget(new Target() {
View view = drawer.getStickyFooter(); @Override
int[] location = new int[2]; public Point getPoint() {
view.getLocationInWindow(location); View view = drawer.getStickyFooter();
int x = location[0] + 7 * view.getWidth() / 8; int[] location = new int[2];
int y = location[1] + view.getHeight() / 2; view.getLocationInWindow(location);
return new Point(x, y); 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) .replaceEndButton(R.layout.showcase_button)
.hideOnTouchOutside() .hideOnTouchOutside()
@ -246,32 +252,36 @@ public class MainActivity extends AppCompatActivity
.withActivity(this) .withActivity(this)
.withHeaderBackground(R.drawable.header) .withHeaderBackground(R.drawable.header)
.withProfiles(profiles) .withProfiles(profiles)
.withOnAccountHeaderListener((view, profile, currentProfile) -> { .withOnAccountHeaderListener(new AccountHeader.OnAccountHeaderListener() {
switch ((int) profile.getIdentifier()) { @Override
case ADD_IDENTITY: public boolean onProfileChanged(View view, IProfile profile, boolean current) {
addIdentityDialog(); switch ((int) profile.getIdentifier()) {
break; case ADD_IDENTITY:
case MANAGE_IDENTITY: addIdentityDialog();
BitmessageAddress identity = Singleton.getIdentity(this); break;
if (identity == null) { case MANAGE_IDENTITY:
Toast.makeText(this, R.string.no_identity_warning, LENGTH_LONG).show(); BitmessageAddress identity = Singleton.getIdentity(MainActivity.this);
} else { if (identity == null) {
Intent show = new Intent(MainActivity.this, Toast.makeText(MainActivity.this,
AddressDetailActivity.class); R.string.no_identity_warning, LENGTH_LONG).show();
show.putExtra(AddressDetailFragment.ARG_ITEM, identity); } else {
startActivity(show); Intent show = new Intent(MainActivity.this,
} AddressDetailActivity.class);
break; show.putExtra(AddressDetailFragment.ARG_ITEM, identity);
default: startActivity(show);
if (profile instanceof ProfileDrawerItem) {
Object tag = ((ProfileDrawerItem) profile).getTag();
if (tag instanceof BitmessageAddress) {
Singleton.setIdentity((BitmessageAddress) tag);
} }
} 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(); .build();
if (profiles.size() > 2) { // There's always the add and manage identity items if (profiles.size() > 2) { // There's always the add and manage identity items
@ -333,11 +343,15 @@ public class MainActivity extends AppCompatActivity
.withName(R.string.full_node) .withName(R.string.full_node)
.withIcon(CommunityMaterial.Icon.cmd_cloud_outline) .withIcon(CommunityMaterial.Icon.cmd_cloud_outline)
.withChecked(isRunning()) .withChecked(isRunning())
.withOnCheckedChangeListener((drawerItem, buttonView, isChecked) -> { .withOnCheckedChangeListener(new OnCheckedChangeListener() {
if (isChecked) { @Override
checkAndStartNode(); public void onCheckedChanged(IDrawerItem drawerItem, CompoundButton buttonView,
} else { boolean isChecked) {
stopService(new Intent(this, BitmessageService.class)); if (isChecked) {
checkAndStartNode();
} else {
stopService(new Intent(MainActivity.this, BitmessageService.class));
}
} }
}); });
@ -347,36 +361,39 @@ public class MainActivity extends AppCompatActivity
.withAccountHeader(accountHeader) .withAccountHeader(accountHeader)
.withDrawerItems(drawerItems) .withDrawerItems(drawerItems)
.addStickyDrawerItems(nodeSwitch) .addStickyDrawerItems(nodeSwitch)
.withOnDrawerItemClickListener((view, position, item) -> { .withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() {
if (item.getTag() instanceof Label) { @Override
selectedLabel = (Label) item.getTag(); public boolean onItemClick(View view, int position, IDrawerItem item) {
showSelectedLabel(); if (item.getTag() instanceof Label) {
return false; selectedLabel = (Label) item.getTag();
} else if (item instanceof Nameable<?>) { showSelectedLabel();
Nameable<?> ni = (Nameable<?>) item; return false;
switch (ni.getName().getTextRes()) { } else if (item instanceof Nameable<?>) {
case R.string.contacts_and_subscriptions: Nameable<?> ni = (Nameable<?>) item;
if (!(getSupportFragmentManager().findFragmentById(R.id switch (ni.getName().getTextRes()) {
.item_list) instanceof AddressListFragment)) { case R.string.contacts_and_subscriptions:
changeList(new AddressListFragment()); if (!(getSupportFragmentManager().findFragmentById(R.id
} else { .item_list) instanceof AddressListFragment)) {
((AddressListFragment) getSupportFragmentManager() changeList(new AddressListFragment());
.findFragmentById(R.id.item_list)).updateList(); } else {
} ((AddressListFragment) getSupportFragmentManager()
break; .findFragmentById(R.id.item_list)).updateList();
case R.string.settings: }
startActivity(new Intent(MainActivity.this, SettingsActivity break;
.class)); case R.string.settings:
break; startActivity(new Intent(MainActivity.this, SettingsActivity
case R.string.archive: .class));
selectedLabel = null; break;
showSelectedLabel(); case R.string.archive:
break; selectedLabel = null;
case R.string.full_node: showSelectedLabel();
return true; break;
case R.string.full_node:
return true;
}
} }
return false;
} }
return false;
}) })
.withShowDrawerOnFirstLaunch(true) .withShowDrawerOnFirstLaunch(true)
.build(); .build();
@ -461,11 +478,14 @@ public class MainActivity extends AppCompatActivity
} }
public static void updateNodeSwitch() { public static void updateNodeSwitch() {
MainActivity i = getInstance(); final MainActivity i = getInstance();
if (i != null) { if (i != null) {
i.runOnUiThread(() -> { i.runOnUiThread(new Runnable() {
i.nodeSwitch.withChecked(i.bmc.isRunning()); @Override
i.drawer.updateStickyFooterItem(i.nodeSwitch); public void run() {
i.nodeSwitch.withChecked(i.bmc.isRunning());
i.drawer.updateStickyFooterItem(i.nodeSwitch);
}
}); });
} }
} }

View File

@ -31,6 +31,7 @@ import android.widget.TextView;
import com.mikepenz.google_material_typeface_library.GoogleMaterial; import com.mikepenz.google_material_typeface_library.GoogleMaterial;
import java.util.Iterator; import java.util.Iterator;
import java.util.regex.Matcher;
import ch.dissem.apps.abit.listener.ActionBarListener; import ch.dissem.apps.abit.listener.ActionBarListener;
import ch.dissem.apps.abit.service.Singleton; import ch.dissem.apps.abit.service.Singleton;
@ -110,7 +111,12 @@ public class MessageDetailFragment extends Fragment {
Linkify.addLinks(messageBody, WEB_URLS); Linkify.addLinks(messageBody, WEB_URLS);
Linkify.addLinks(messageBody, BITMESSAGE_ADDRESS_PATTERN, BITMESSAGE_URL_SCHEMA, null, Linkify.addLinks(messageBody, BITMESSAGE_ADDRESS_PATTERN, BITMESSAGE_URL_SCHEMA, null,
(match, url) -> match.group() new Linkify.TransformFilter() {
@Override
public String transformUrl(Matcher match, String url) {
return match.group();
}
}
); );
messageBody.setLinksClickable(true); messageBody.setLinksClickable(true);

View File

@ -46,21 +46,27 @@ public class SettingsFragment
addPreferencesFromResource(R.xml.preferences); addPreferencesFromResource(R.xml.preferences);
Preference about = findPreference("about"); Preference about = findPreference("about");
about.setOnPreferenceClickListener(preference -> { about.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
new LibsBuilder() @Override
.withActivityTitle(getActivity().getString(R.string.about)) public boolean onPreferenceClick(Preference preference) {
.withActivityStyle(Libs.ActivityStyle.LIGHT_DARK_TOOLBAR) new LibsBuilder()
.withAboutIconShown(true) .withActivityTitle(getActivity().getString(R.string.about))
.withAboutVersionShown(true) .withActivityStyle(Libs.ActivityStyle.LIGHT_DARK_TOOLBAR)
.withAboutDescription(getString(R.string.about_app)) .withAboutIconShown(true)
.start(getActivity()); .withAboutVersionShown(true)
return true; .withAboutDescription(getString(R.string.about_app))
.start(getActivity());
return true;
}
}); });
Preference status = findPreference("status"); Preference status = findPreference("status");
status.setOnPreferenceClickListener(preference -> { status.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
startActivity(new Intent(getActivity(), StatusActivity.class)); @Override
return true; public boolean onPreferenceClick(Preference preference) {
startActivity(new Intent(getActivity(), StatusActivity.class));
return true;
}
}); });
} }

View File

@ -21,6 +21,7 @@ import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.CheckBox; import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView; import android.widget.TextView;
import java.util.ArrayList; import java.util.ArrayList;
@ -75,9 +76,12 @@ public class AddressSelectorAdapter
super(v); super(v);
checkbox = (CheckBox) v.findViewById(R.id.checkbox); checkbox = (CheckBox) v.findViewById(R.id.checkbox);
address = (TextView) v.findViewById(R.id.address); address = (TextView) v.findViewById(R.id.address);
checkbox.setOnCheckedChangeListener((buttonView, isChecked) -> { checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
if (data != null) { @Override
data.selected = isChecked; public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
if (data != null) {
data.selected = isChecked;
}
} }
}); });
} }

View File

@ -105,8 +105,18 @@ public class SwipeableMessageAdapter
} }
public SwipeableMessageAdapter() { public SwipeableMessageAdapter() {
itemViewOnClickListener = this::onItemViewClick; itemViewOnClickListener = new View.OnClickListener() {
swipeableViewContainerOnClickListener = this::onSwipeableViewContainerClick; @Override
public void onClick(View view) {
onItemViewClick(view);
}
};
swipeableViewContainerOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
onSwipeableViewContainerClick(view);
}
};
// SwipeableItemAdapter requires stable ID, and also // SwipeableItemAdapter requires stable ID, and also
// have to implement the getItemId() method appropriately. // have to implement the getItemId() method appropriately.

View File

@ -19,6 +19,7 @@ package ch.dissem.apps.abit.dialog;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
@ -60,47 +61,55 @@ public class AddIdentityDialogFragment extends AppCompatDialogFragment {
getDialog().setTitle(R.string.add_identity); getDialog().setTitle(R.string.add_identity);
View view = inflater.inflate(R.layout.dialog_add_identity, container, false); View view = inflater.inflate(R.layout.dialog_add_identity, container, false);
final RadioGroup radioGroup = (RadioGroup) view.findViewById(R.id.radioGroup); final RadioGroup radioGroup = (RadioGroup) view.findViewById(R.id.radioGroup);
view.findViewById(R.id.ok).setOnClickListener(v -> { view.findViewById(R.id.ok).setOnClickListener(new View.OnClickListener() {
final Context ctx = getActivity().getBaseContext(); @Override
switch (radioGroup.getCheckedRadioButtonId()) { public void onClick(View view) {
case R.id.create_identity: final Context ctx = getActivity().getBaseContext();
Toast.makeText(ctx, switch (radioGroup.getCheckedRadioButtonId()) {
R.string.toast_long_running_operation, case R.id.create_identity:
Toast.LENGTH_SHORT).show(); Toast.makeText(ctx,
new AsyncTask<Void, Void, BitmessageAddress>() { R.string.toast_long_running_operation,
@Override Toast.LENGTH_SHORT).show();
protected BitmessageAddress doInBackground(Void... args) { new AsyncTask<Void, Void, BitmessageAddress>() {
return bmc.createIdentity(false, Pubkey.Feature.DOES_ACK); @Override
} protected BitmessageAddress doInBackground(Void... args) {
return bmc.createIdentity(false, Pubkey.Feature.DOES_ACK);
@Override
protected void onPostExecute(BitmessageAddress chan) {
Toast.makeText(ctx,
R.string.toast_identity_created,
Toast.LENGTH_SHORT).show();
MainActivity mainActivity = MainActivity.getInstance();
if (mainActivity != null) {
mainActivity.addIdentityEntry(chan);
} }
}
}.execute(); @Override
break; protected void onPostExecute(BitmessageAddress chan) {
case R.id.import_identity: Toast.makeText(ctx,
startActivity(new Intent(ctx, ImportIdentityActivity.class)); R.string.toast_identity_created,
break; Toast.LENGTH_SHORT).show();
case R.id.add_chan: MainActivity mainActivity = MainActivity.getInstance();
addChanDialog(); if (mainActivity != null) {
break; mainActivity.addIdentityEntry(chan);
case R.id.add_deterministic_address: }
new DeterministicIdentityDialogFragment().show(getFragmentManager(), }
"dialog"); }.execute();
break; break;
default: case R.id.import_identity:
return; startActivity(new Intent(ctx, ImportIdentityActivity.class));
break;
case R.id.add_chan:
addChanDialog();
break;
case R.id.add_deterministic_address:
new DeterministicIdentityDialogFragment().show(getFragmentManager(),
"dialog");
break;
default:
return;
}
dismiss();
}
});
view.findViewById(R.id.dismiss).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dismiss();
} }
dismiss();
}); });
view.findViewById(R.id.dismiss).setOnClickListener(v -> dismiss());
return view; return view;
} }
@ -113,31 +122,34 @@ public class AddIdentityDialogFragment extends AppCompatDialogFragment {
new AlertDialog.Builder(activity) new AlertDialog.Builder(activity)
.setTitle(R.string.add_chan) .setTitle(R.string.add_chan)
.setView(dialogView) .setView(dialogView)
.setPositiveButton(R.string.ok, (dialogInterface, i) -> { .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
TextView passphrase = (TextView) dialogView.findViewById(R.id.passphrase); @Override
Toast.makeText(ctx, R.string.toast_long_running_operation, public void onClick(DialogInterface dialogInterface, int i) {
Toast.LENGTH_SHORT).show(); TextView passphrase = (TextView) dialogView.findViewById(R.id.passphrase);
new AsyncTask<String, Void, BitmessageAddress>() { Toast.makeText(ctx, R.string.toast_long_running_operation,
@Override Toast.LENGTH_SHORT).show();
protected BitmessageAddress doInBackground(String... args) { new AsyncTask<String, Void, BitmessageAddress>() {
String pass = args[0]; @Override
BitmessageAddress chan = bmc.createChan(pass); protected BitmessageAddress doInBackground(String... args) {
chan.setAlias(pass); String pass = args[0];
bmc.addresses().save(chan); BitmessageAddress chan = bmc.createChan(pass);
return chan; chan.setAlias(pass);
} bmc.addresses().save(chan);
return chan;
@Override
protected void onPostExecute(BitmessageAddress chan) {
Toast.makeText(ctx,
R.string.toast_chan_created,
Toast.LENGTH_SHORT).show();
MainActivity mainActivity = MainActivity.getInstance();
if (mainActivity != null) {
mainActivity.addIdentityEntry(chan);
} }
}
}.execute(passphrase.getText().toString()); @Override
protected void onPostExecute(BitmessageAddress chan) {
Toast.makeText(ctx,
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) .setNegativeButton(R.string.cancel, null)
.show(); .show();

View File

@ -56,68 +56,76 @@ public class DeterministicIdentityDialogFragment extends AppCompatDialogFragment
getDialog().setTitle(R.string.add_deterministic_address); getDialog().setTitle(R.string.add_deterministic_address);
View view = inflater.inflate(R.layout.dialog_add_deterministic_identity, container, false); View view = inflater.inflate(R.layout.dialog_add_deterministic_identity, container, false);
view.findViewById(R.id.ok) view.findViewById(R.id.ok)
.setOnClickListener(v -> { .setOnClickListener(new View.OnClickListener() {
dismiss(); @Override
final Context context = getActivity().getBaseContext(); public void onClick(View view) {
View dialogView = getView(); dismiss();
TextView label = (TextView) dialogView.findViewById(R.id.label); final Context context = getActivity().getBaseContext();
TextView passphrase = (TextView) dialogView.findViewById(R.id.passphrase); View dialogView = getView();
TextView numberOfAddresses = (TextView) dialogView.findViewById(R.id assert dialogView != null;
.number_of_identities); TextView label = (TextView) dialogView.findViewById(R.id.label);
Switch shorter = (Switch) dialogView.findViewById(R.id.shorter); 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.makeText(context, R.string.toast_long_running_operation,
Toast.LENGTH_SHORT).show(); Toast.LENGTH_SHORT).show();
new AsyncTask<Object, Void, List<BitmessageAddress>>() { new AsyncTask<Object, Void, List<BitmessageAddress>>() {
@Override @Override
protected List<BitmessageAddress> doInBackground(Object... args) { protected List<BitmessageAddress> doInBackground(Object... args) {
String label = (String) args[0]; String label = (String) args[0];
String pass = (String) args[1]; String pass = (String) args[1];
int numberOfAddresses = (int) args[2]; int numberOfAddresses = (int) args[2];
boolean shorter = (boolean) args[3]; boolean shorter = (boolean) args[3];
List<BitmessageAddress> identities = bmc.createDeterministicAddresses List<BitmessageAddress> identities = bmc.createDeterministicAddresses
(pass, (pass,
numberOfAddresses, Pubkey.LATEST_VERSION, 1L, shorter); numberOfAddresses, Pubkey.LATEST_VERSION, 1L, shorter);
int i = 0; 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) { for (BitmessageAddress identity : identities) {
mainActivity.addIdentityEntry(identity); 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(
}.execute( label.getText().toString(),
label.getText().toString(), passphrase.getText().toString(),
passphrase.getText().toString(), Integer.valueOf(numberOfAddresses.getText().toString()),
Integer.valueOf(numberOfAddresses.getText().toString()), shorter.isChecked()
shorter.isChecked() );
); }
}); });
view.findViewById(R.id.dismiss) view.findViewById(R.id.dismiss).setOnClickListener(new View.OnClickListener() {
.setOnClickListener(v -> dismiss()); @Override
public void onClick(View view) {
dismiss();
}
});
return view; return view;
} }

View File

@ -19,6 +19,7 @@ package ch.dissem.apps.abit.dialog;
import android.app.Activity; import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.view.View;
import ch.dissem.apps.abit.R; import ch.dissem.apps.abit.R;
import ch.dissem.apps.abit.service.BitmessageService; import ch.dissem.apps.abit.service.BitmessageService;
@ -34,11 +35,19 @@ public class FullNodeDialogActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_full_node); setContentView(R.layout.dialog_full_node);
findViewById(R.id.ok).setOnClickListener(v -> { findViewById(R.id.ok).setOnClickListener(new View.OnClickListener() {
startService(new Intent(this, BitmessageService.class)); @Override
updateNodeSwitch(); public void onClick(View view) {
finish(); startService(new Intent(FullNodeDialogActivity.this, BitmessageService.class));
updateNodeSwitch();
finish();
}
});
findViewById(R.id.dismiss).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
}); });
findViewById(R.id.dismiss).setOnClickListener(v -> finish());
} }
} }

View File

@ -48,32 +48,38 @@ public class MessageListener implements BitmessageContext.Listener {
@Override @Override
public void receive(final Plaintext plaintext) { public void receive(final Plaintext plaintext) {
pool.submit(() -> { pool.submit(new Runnable() {
unacknowledged.addFirst(plaintext); @Override
numberOfUnacknowledgedMessages++; public void run() {
if (unacknowledged.size() > 5) { unacknowledged.addFirst(plaintext);
unacknowledged.removeLast(); numberOfUnacknowledgedMessages++;
} if (unacknowledged.size() > 5) {
if (numberOfUnacknowledgedMessages == 1) { unacknowledged.removeLast();
notification.singleNotification(plaintext); }
} else { if (numberOfUnacknowledgedMessages == 1) {
notification.multiNotification(unacknowledged, numberOfUnacknowledgedMessages); notification.singleNotification(plaintext);
} } else {
notification.show(); notification.multiNotification(unacknowledged, numberOfUnacknowledgedMessages);
}
notification.show();
// If MainActivity is shown, update the sidebar badges // If MainActivity is shown, update the sidebar badges
MainActivity main = MainActivity.getInstance(); MainActivity main = MainActivity.getInstance();
if (main != null) { if (main != null) {
main.updateUnread(); main.updateUnread();
}
} }
}); });
} }
public void resetNotification() { public void resetNotification() {
pool.submit(() -> { pool.submit(new Runnable() {
notification.hide(); @Override
unacknowledged.clear(); public void run() {
numberOfUnacknowledgedMessages = 0; notification.hide();
unacknowledged.clear();
numberOfUnacknowledgedMessages = 0;
}
}); });
} }
} }

View File

@ -17,12 +17,14 @@
package ch.dissem.apps.abit.pow; package ch.dissem.apps.abit.pow;
import android.content.Context; import android.content.Context;
import android.support.annotation.NonNull;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import ch.dissem.apps.abit.service.Singleton; import ch.dissem.apps.abit.service.Singleton;
import ch.dissem.apps.abit.synchronization.SyncAdapter; import ch.dissem.apps.abit.synchronization.SyncAdapter;
@ -50,34 +52,40 @@ public class ServerPowEngine implements ProofOfWorkEngine, InternalContext
public ServerPowEngine(Context ctx) { public ServerPowEngine(Context ctx) {
this.ctx = ctx; this.ctx = ctx;
pool = Executors.newCachedThreadPool(r -> { pool = Executors.newCachedThreadPool(new ThreadFactory() {
Thread thread = Executors.defaultThreadFactory().newThread(r); @Override
thread.setPriority(Thread.MIN_PRIORITY); public Thread newThread(@NonNull Runnable r) {
return thread; Thread thread = Executors.defaultThreadFactory().newThread(r);
thread.setPriority(Thread.MIN_PRIORITY);
return thread;
}
}); });
} }
@Override @Override
public void calculateNonce(final byte[] initialHash, final byte[] target, Callback callback) { public void calculateNonce(final byte[] initialHash, final byte[] target, Callback callback) {
pool.execute(() -> { pool.execute(new Runnable() {
BitmessageAddress identity = Singleton.getIdentity(ctx); @Override
if (identity == null) throw new RuntimeException("No Identity for calculating POW"); public void run() {
BitmessageAddress identity = Singleton.getIdentity(ctx);
if (identity == null) throw new RuntimeException("No Identity for calculating POW");
ProofOfWorkRequest request = new ProofOfWorkRequest(identity, initialHash, ProofOfWorkRequest request = new ProofOfWorkRequest(identity, initialHash,
CALCULATE, target); CALCULATE, target);
SyncAdapter.startPowSync(ctx); SyncAdapter.startPowSync(ctx);
try { try {
CryptoCustomMessage<ProofOfWorkRequest> cryptoMsg = new CryptoCustomMessage<> CryptoCustomMessage<ProofOfWorkRequest> cryptoMsg = new CryptoCustomMessage<>
(request); (request);
cryptoMsg.signAndEncrypt( cryptoMsg.signAndEncrypt(
identity, identity,
cryptography().createPublicKey(identity.getPublicDecryptionKey()) cryptography().createPublicKey(identity.getPublicDecryptionKey())
); );
context.getNetworkHandler().send( context.getNetworkHandler().send(
Preferences.getTrustedNode(ctx), Preferences.getTrustedNodePort(ctx), Preferences.getTrustedNode(ctx), Preferences.getTrustedNodePort(ctx),
cryptoMsg); cryptoMsg);
} catch (Exception e) { } catch (Exception e) {
LOG.error(e.getMessage(), e); LOG.error(e.getMessage(), e);
}
} }
}); });
} }

View File

@ -92,23 +92,26 @@ public class ProofOfWorkService extends Service {
} }
private void calculateNonce(final PowItem item) { private void calculateNonce(final PowItem item) {
engine.calculateNonce(item.initialHash, item.targetValue, (initialHash, nonce) -> { engine.calculateNonce(item.initialHash, item.targetValue, new ProofOfWorkEngine.Callback() {
try { @Override
item.callback.onNonceCalculated(initialHash, nonce); public void onNonceCalculated(byte[] initialHash, byte[] nonce) {
} finally { try {
PowItem next; item.callback.onNonceCalculated(initialHash, nonce);
synchronized (queue) { } finally {
next = queue.poll(); PowItem next;
if (next == null) { synchronized (queue) {
calculating = false; next = queue.poll();
stopForeground(true); if (next == null) {
stopSelf(); calculating = false;
} else { stopForeground(true);
notification.update(queue.size()).show(); stopSelf();
} else {
notification.update(queue.size()).show();
}
}
if (next != null) {
calculateNonce(next);
} }
}
if (next != null) {
calculateNonce(next);
} }
} }
}); });

View File

@ -110,9 +110,9 @@ public class Singleton {
return powRepo; return powRepo;
} }
public static BitmessageAddress getIdentity(Context ctx) { public static BitmessageAddress getIdentity(final Context ctx) {
if (identity == null) { if (identity == null) {
BitmessageContext bmc = getBitmessageContext(ctx); final BitmessageContext bmc = getBitmessageContext(ctx);
synchronized (Singleton.class) { synchronized (Singleton.class) {
if (identity == null) { if (identity == null) {
List<BitmessageAddress> identities = bmc.addresses() List<BitmessageAddress> identities = bmc.addresses()