Receiving almost works, unfortunately, JDBC doesn't so I have to rewrite the whole damn repository code.

This commit is contained in:
Christian Basler 2015-08-14 17:25:05 +02:00
parent 89a5ada48a
commit cb2040b0ce
38 changed files with 657 additions and 285 deletions

View File

@ -37,6 +37,8 @@ dependencies {
compile('com.mikepenz:materialdrawer:3.1.0@aar') {
transitive = true
}
compile 'com.mikepenz:iconics:1.6.2@aar'
compile 'com.mikepenz:community-material-typeface:1.1.71@aar'
}
idea.module {

View File

@ -30,12 +30,45 @@
android:name="android.support.PARENT_ACTIVITY"
android:value=".MessageListActivity"/>
</activity>
<activity
android:name=".ComposeMessageActivity"
android:label="Compose"
android:parentActivityName=".MessageListActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MessageListActivity"/>
<intent-filter>
<action android:name="android.intent.action.SENDTO"/>
<data android:scheme="bitmessage"/>
<data android:scheme="bitmsg"/>
<data android:scheme="bm"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<data android:mimeType="text/plain"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE"/>
<data android:mimeType="text/plain"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity
android:name=".SettingsActivity"
android:label="@string/settings"
android:parentActivityName=".MessageListActivity">
<intent-filter>
<action android:name="android.intent.action.MANAGE_NETWORK_USAGE"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
@ -46,6 +79,22 @@
android:exported="true"
android:permission="">
</service>
<activity
android:name=".OpenBitmessageLinkActivity"
android:label="@string/title_activity_open_bitmessage_link"
android:theme="@style/Theme.AppCompat.Light.Dialog">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<data android:scheme="bitmessage"/>
<data android:scheme="bitmsg"/>
<data android:scheme="bm"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
</intent-filter>
</activity>
</application>
</manifest>

View File

@ -0,0 +1,28 @@
package ch.dissem.apps.abit;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
/**
* Compose a new message.
*/
public class ComposeMessageActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.toolbar_layout);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_action_close);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(false);
// Display the fragment as the main content.
getSupportFragmentManager().beginTransaction()
.replace(R.id.content, new ComposeMessageFragment())
.commit();
}
}

View File

@ -0,0 +1,77 @@
package ch.dissem.apps.abit;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.*;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.Toast;
import ch.dissem.bitmessage.BitmessageContext;
import ch.dissem.bitmessage.entity.BitmessageAddress;
/**
* Compose a new message.
*/
public class ComposeMessageFragment extends Fragment {
/**
* The fragment argument representing the sender identity.
*/
public static final String ARG_IDENTITY = "from";
/**
* The fragment argument representing the recipient.
*/
public static final String ARG_RECIPIENT = "to";
private BitmessageContext bmCtx;
private BitmessageAddress identity;
private BitmessageAddress recipient;
/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public ComposeMessageFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
if (getArguments().containsKey(ARG_IDENTITY)) {
identity = (BitmessageAddress) getArguments().getSerializable(ARG_IDENTITY);
}
if (getArguments().containsKey(ARG_RECIPIENT)) {
recipient = (BitmessageAddress) getArguments().getSerializable(ARG_RECIPIENT);
}
}
setHasOptionsMenu(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_compose_message, container, false);
EditText body = (EditText) rootView.findViewById(R.id.body);
body.setInputType(EditorInfo.TYPE_TEXT_VARIATION_SHORT_MESSAGE | EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE);
body.setImeOptions(EditorInfo.IME_ACTION_SEND | EditorInfo.IME_FLAG_NO_ENTER_ACTION);
return rootView;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.compose, menu);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.send:
Toast.makeText(getActivity(), "TODO: Send", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}

View File

@ -0,0 +1,102 @@
/*
* Copyright 2015 Christian Basler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.dissem.apps.abit;
import android.graphics.*;
import android.graphics.drawable.Drawable;
import ch.dissem.bitmessage.entity.BitmessageAddress;
/**
*
*/
public class Identicon extends Drawable {
private static final int SIZE = 9;
private static final int CENTER_COLUMN = 5;
private final Paint paint;
private float cellWidth;
private float cellHeight;
private byte[] hash;
private int color;
private int background;
private boolean[][] fields;
public Identicon(BitmessageAddress input) {
paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
hash = input.getRipe();
fields = new boolean[SIZE][SIZE];
color = Color.HSVToColor(new float[]{Math.abs(hash[0] * hash[1] + hash[2]) % 360, 0.8f, 1.0f});
background = Color.HSVToColor(new float[]{Math.abs(hash[1] * hash[2] + hash[0]) % 360, 0.8f, 1.0f});
for (int row = 0; row < SIZE; row++) {
for (int column = 0; column < SIZE; column++) {
fields[row][column] = hash[(row * (column < CENTER_COLUMN ? column : SIZE - column - 1)) % hash.length] >= 0;
}
}
}
protected byte getByte(int index) {
return hash[index % hash.length];
}
@Override
public void draw(Canvas canvas) {
float x, y;
paint.setColor(background);
canvas.drawPaint(paint);
paint.setColor(color);
for (int row = 0; row < SIZE; row++) {
for (int column = 0; column < SIZE; column++) {
if (fields[row][column]) {
x = cellWidth * column;
y = cellHeight * row;
canvas.drawCircle(x + cellWidth / 2, y + cellHeight / 2, cellHeight / 2, paint);
}
}
}
}
@Override
public void setAlpha(int alpha) {
paint.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter cf) {
paint.setColorFilter(cf);
}
@Override
public int getOpacity() {
return PixelFormat.OPAQUE;
}
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
cellWidth = bounds.width() / (float) SIZE;
cellHeight = bounds.height() / (float) SIZE;
}
}

View File

@ -5,13 +5,16 @@ import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Toast;
import ch.dissem.apps.abit.service.Singleton;
import ch.dissem.bitmessage.BitmessageContext;
import ch.dissem.bitmessage.entity.BitmessageAddress;
import ch.dissem.bitmessage.entity.Plaintext;
import ch.dissem.bitmessage.entity.valueobject.Label;
import com.mikepenz.community_material_typeface_library.CommunityMaterial;
import com.mikepenz.google_material_typeface_library.GoogleMaterial;
import com.mikepenz.iconics.IconicsDrawable;
import com.mikepenz.materialdrawer.Drawer;
@ -59,6 +62,7 @@ public class MessageListActivity extends AppCompatActivity
private AccountHeader accountHeader;
private BitmessageContext bmc;
private Label selectedLabel;
private Menu menu;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -68,7 +72,7 @@ public class MessageListActivity extends AppCompatActivity
setContentView(R.layout.activity_message_list);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
if (findViewById(R.id.message_detail_container) != null) {
@ -109,7 +113,7 @@ public class MessageListActivity extends AppCompatActivity
.withIdentifier(ADD_IDENTITY)
);
profiles.add(new ProfileSettingDrawerItem()
.withName("Manage Account")
.withName(getString(R.string.manage_identity))
.withIcon(GoogleMaterial.Icon.gmd_settings)
);
// Create the AccountHeader
@ -150,6 +154,9 @@ public class MessageListActivity extends AppCompatActivity
.withAccountHeader(accountHeader)
.withDrawerItems(drawerItems)
.addStickyDrawerItems(
new SecondaryDrawerItem()
.withName(getString(R.string.subscriptions))
.withIcon(CommunityMaterial.Icon.cmd_rss),
new SecondaryDrawerItem()
.withName(R.string.settings)
.withIcon(GoogleMaterial.Icon.gmd_settings)
@ -162,6 +169,9 @@ public class MessageListActivity extends AppCompatActivity
} else if (item instanceof Nameable<?>) {
Nameable<?> ni = (Nameable<?>) item;
switch (ni.getNameRes()) {
case R.string.subscriptions:
// TODO
break;
case R.string.settings:
startActivity(new Intent(MessageListActivity.this, SettingsActivity.class));
break;
@ -176,10 +186,37 @@ public class MessageListActivity extends AppCompatActivity
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
this.menu = menu;
updateMenu();
return true;
}
private void updateMenu() {
boolean running = bmc.isRunning();
menu.findItem(R.id.sync_enabled).setVisible(running);
menu.findItem(R.id.sync_disabled).setVisible(!running);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.sync_disabled:
bmc.startup(new BitmessageContext.Listener() {
@Override
public void receive(Plaintext plaintext) {
// TODO
Toast.makeText(MessageListActivity.this, plaintext.getSubject(), Toast.LENGTH_LONG).show();
}
});
updateMenu();
return true;
case R.id.sync_enabled:
bmc.shutdown();
updateMenu();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/**

View File

@ -1,6 +1,7 @@
package ch.dissem.apps.abit;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.ListFragment;
@ -9,8 +10,6 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import ch.dissem.apps.abit.service.Singleton;
import ch.dissem.bitmessage.BitmessageContext;
import ch.dissem.bitmessage.entity.Plaintext;
@ -97,7 +96,7 @@ public class MessageListFragment extends ListFragment {
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MessageListFragment.this.getActivity(), "TODO", Toast.LENGTH_SHORT).show();
startActivity(new Intent(getActivity().getApplicationContext(), ComposeMessageActivity.class));
}
});

View File

@ -0,0 +1,113 @@
/*
* Copyright 2015 Christian Basler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.dissem.apps.abit;
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Switch;
import android.widget.TextView;
import ch.dissem.apps.abit.service.Singleton;
import ch.dissem.bitmessage.BitmessageContext;
import ch.dissem.bitmessage.entity.BitmessageAddress;
public class OpenBitmessageLinkActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_open_bitmessage_link);
final TextView addressView = (TextView) findViewById(R.id.address);
final EditText label = (EditText) findViewById(R.id.label);
final Switch importContact = (Switch) findViewById(R.id.import_contact);
final Switch subscribe = (Switch) findViewById(R.id.subscribe);
Uri uri = getIntent().getData();
final String address = getAddress(uri);
String[] parameters = getParameters(uri);
for (String parameter : parameters) {
String name = parameter.substring(0, 6).toLowerCase();
if (name.startsWith("label")) {
label.setText(parameter.substring(parameter.indexOf('=') + 1).trim());
} else if (name.startsWith("action")) {
parameter = parameter.toLowerCase();
importContact.setChecked(parameter.contains("add"));
subscribe.setChecked(parameter.contains("subscribe"));
}
}
addressView.setText(address);
final Button cancel = (Button) findViewById(R.id.cancel);
cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
setResult(Activity.RESULT_CANCELED);
finish();
}
});
final Button ok = (Button) findViewById(R.id.do_import);
ok.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
BitmessageContext bmc = Singleton.getBitmessageContext(OpenBitmessageLinkActivity.this);
BitmessageAddress bmAddress = new BitmessageAddress(address);
bmAddress.setAlias(label.getText().toString());
if (subscribe.isChecked()) {
bmc.addSubscribtion(bmAddress);
}
if (importContact.isChecked()) {
bmc.addContact(bmAddress);
}
setResult(Activity.RESULT_OK);
finish();
}
});
}
private String getAddress(Uri uri) {
StringBuilder result = new StringBuilder();
String schemeSpecificPart = uri.getSchemeSpecificPart();
if (!schemeSpecificPart.startsWith("BM-")) {
result.append("BM-");
}
if (schemeSpecificPart.contains("?")) {
result.append(schemeSpecificPart.substring(0, schemeSpecificPart.indexOf('?')));
} else if (schemeSpecificPart.contains("#")) {
result.append(schemeSpecificPart.substring(0, schemeSpecificPart.indexOf('#')));
} else {
result.append(schemeSpecificPart);
}
return result.toString();
}
private String[] getParameters(Uri uri) {
int index = uri.getSchemeSpecificPart().indexOf('?');
if (index >= 0) {
String parameterPart = uri.getSchemeSpecificPart().substring(index + 1);
return parameterPart.split("&");
} else {
return new String[0];
}
}
}

View File

@ -1,37 +0,0 @@
package ch.dissem.apps.abit;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.os.Environment;
import ch.dissem.bitmessage.repository.JdbcConfig;
import org.flywaydb.core.api.android.ContextHolder;
import org.sqldroid.SQLDroidDriver;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
/**
* Created by chris on 14.07.15.
*/
public class SQLiteConfig extends JdbcConfig {
public SQLiteConfig(Context ctx) {
super(getDbUrl(ctx), "", "");
}
private static String getDbUrl(Context ctx) {
SQLiteDatabase db = ctx.openOrCreateDatabase(Environment.getExternalStorageDirectory()
+ "/jabit.db", Context.MODE_PRIVATE, null);
ContextHolder.setContext(ctx);
return "jdbc:sqlite:" + db.getPath() + "?timeout=5";
}
@Override
public Connection getConnection() throws SQLException {
Properties removeLocale = new Properties();
removeLocale.put(SQLDroidDriver.ADDITONAL_DATABASE_FLAGS, android.database.sqlite.SQLiteDatabase.NO_LOCALIZED_COLLATORS);
return DriverManager.getConnection(dbUrl, removeLocale);
}
}

View File

@ -0,0 +1,7 @@
package ch.dissem.apps.abit.repositories;
/**
* Created by chris on 14.08.15.
*/
public class AndroidInventory {
}

View File

@ -1,213 +0,0 @@
package im.delight.android.identicons;
/**
* Copyright 2014 www.delight.im <info@delight.im>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.security.MessageDigest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
abstract public class Identicon extends View {
private static final String HASH_ALGORITHM = "SHA-256";
private final int mRowCount;
private final int mColumnCount;
private final Paint mPaint;
private volatile int mCellWidth;
private volatile int mCellHeight;
private volatile byte[] mHash;
private volatile int[][] mColors;
private volatile boolean mReady;
public Identicon(Context context) {
super(context);
mRowCount = getRowCount();
mColumnCount = getColumnCount();
mPaint = new Paint();
init();
}
public Identicon(Context context, AttributeSet attrs) {
super(context, attrs);
mRowCount = getRowCount();
mColumnCount = getColumnCount();
mPaint = new Paint();
init();
}
public Identicon(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mRowCount = getRowCount();
mColumnCount = getColumnCount();
mPaint = new Paint();
init();
}
@SuppressLint("NewApi")
protected void init() {
mPaint.setStyle(Paint.Style.FILL);
mPaint.setAntiAlias(true);
mPaint.setDither(true);
setWillNotDraw(false);
if (Build.VERSION.SDK_INT >= 11) {
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
}
public void show(String input) {
// if the input was null
if (input == null) {
// we can't create a hash value and have nothing to show (draw to the view)
mHash = null;
}
// if the input was a proper string (non-null)
else {
// generate a hash from the string to get unique but deterministic byte values
try {
final MessageDigest digest = java.security.MessageDigest.getInstance(HASH_ALGORITHM);
digest.update(input == null ? new byte[0] : input.getBytes());
mHash = digest.digest();
}
catch (Exception e) {
mHash = null;
}
}
// set up the cell colors according to the input that was provided via show(...)
setupColors();
// this view may now be drawn (and thus must be re-drawn)
mReady = true;
invalidate();
}
public void show(int input) {
show(String.valueOf(input));
}
public void show(long input) {
show(String.valueOf(input));
}
public void show(float input) {
show(String.valueOf(input));
}
public void show(double input) {
show(String.valueOf(input));
}
public void show(byte input) {
show(String.valueOf(input));
}
public void show(char input) {
show(String.valueOf(input));
}
public void show(boolean input) {
show(String.valueOf(input));
}
public void show(Object input) {
if (input == null) {
mHash = null;
}
else {
show(String.valueOf(input));
}
}
protected void setupColors() {
mColors = new int[mRowCount][mColumnCount];
int colorVisible = getIconColor();
for (int r = 0; r < mRowCount; r++) {
for (int c = 0; c < mColumnCount; c++) {
if (isCellVisible(r, c)) {
mColors[r][c] = colorVisible;
}
else {
mColors[r][c] = Color.TRANSPARENT;
}
}
}
}
protected byte getByte(int index) {
if (mHash == null) {
return -128;
}
else {
return mHash[index % mHash.length];
}
}
abstract protected int getRowCount();
abstract protected int getColumnCount();
abstract protected boolean isCellVisible(int row, int column);
abstract protected int getIconColor();
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mCellWidth = w / mColumnCount;
mCellHeight = h / mRowCount;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int size = Math.min(getMeasuredWidth(), getMeasuredHeight());
setMeasuredDimension(size, size);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mReady) {
int x, y;
for (int r = 0; r < mRowCount; r++) {
for (int c = 0; c < mColumnCount; c++) {
x = mCellWidth * c;
y = mCellHeight * r;
mPaint.setColor(mColors[r][c]);
canvas.drawRect(x, y + mCellHeight, x + mCellWidth, y, mPaint);
}
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 371 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 862 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 293 B

After

Width:  |  Height:  |  Size: 302 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 593 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 230 B

After

Width:  |  Height:  |  Size: 232 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 497 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 409 B

After

Width:  |  Height:  |  Size: 383 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 814 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 600 B

After

Width:  |  Height:  |  Size: 759 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 895 B

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="BM-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
android:textAppearance="?android:attr/textAppearanceSmall"
android:id="@+id/address"/>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/label_wrapper"
android:layout_below="@+id/address">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:hint="@string/label"
android:id="@+id/label"/>
</android.support.design.widget.TextInputLayout>
<Switch
android:id="@+id/import_contact"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/import_contact"
android:layout_below="@+id/label_wrapper"
android:layout_centerHorizontal="true"
android:layout_marginTop="8dp"/>
<Switch
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/subscribe"
android:id="@+id/subscribe"
android:layout_below="@+id/import_contact"
android:layout_centerHorizontal="true"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/do_import"
android:id="@+id/do_import"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/cancel"
android:id="@+id/cancel"
android:layout_alignParentBottom="true"
android:layout_toLeftOf="@id/do_import"/>
</RelativeLayout>

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="4dp">
<EditText
android:id="@+id/recipient"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textNoSuggestions"
android:singleLine="true"
android:hint="@string/to"/>
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/subject"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textEmailSubject"
android:textAppearance="?android:attr/textAppearanceLarge"
android:hint="@string/subject"/>
</android.support.design.widget.TextInputLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<EditText
android:id="@+id/body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textMultiLine"/>
</ScrollView>
</LinearLayout>

View File

@ -2,7 +2,8 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
xmlns:fab="http://schemas.android.com/tools">
<ListView
android:layout_width="wrap_content"
@ -18,7 +19,7 @@
android:id="@+id/fab_compose_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_plus_sign"
android:src="@drawable/ic_fab_compose_message"
app:elevation="8dp"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"

View File

@ -1,26 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
android:elevation="4dp" />
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_below="@id/toolbar"
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MessageListActivity"
tools:layout="@android:layout/list_content"/>
</RelativeLayout>
xmlns:tools="http://schemas.android.com/tools"
android:layout_below="@id/toolbar"
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MessageListActivity"
tools:layout="@android:layout/list_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_scrollFlags="scroll|enterAlways"/>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/send"
app:showAsAction="always"
android:icon="@drawable/ic_action_send"
android:title="@string/disable_sync"/>`
</menu>

View File

@ -4,4 +4,14 @@
<string name="settings">Einstellungen</string>
<string name="wifi_only">Nur WLAN</string>
<string name="wifi_only_summary">Nicht mit Mobilfunknetz verbinden</string>
<string name="bitmessage_active">Bitmessage ist aktiv</string>
<string name="disable_sync">Synchronisieren ausschalten</string>
<string name="emoji_input">Eingabe von Emojis</string>
<string name="emoji_input_summary">Emoji-Taste anstelle von Eingabe anzeigen</string>
<string name="enable_sync">Synchronisieren einschalten</string>
<string name="subject">Betreff</string>
<string name="to">An</string>
<string name="title_message_detail">Nachricht</string>
<string name="subscriptions">Abonnements</string>
<string name="wifi_mode">Art der WLAN-Verbindung</string>
</resources>

View File

@ -0,0 +1,22 @@
<!--
~ Copyright 2015 Christian Basler
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<resources>
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
(such as screen margins) for screens with more than 820dp of available width. This
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
<dimen name="activity_horizontal_margin">64dp</dimen>
</resources>

View File

@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Palette generated by Material Palette - materialpalette.com/blue-grey/orange -->
<resources>
<color name="primary">#607D8B</color>
<color name="primary_dark">#455A64</color>
<color name="primary_light">#CFD8DC</color>
<color name="accent">#FF9800</color>
<color name="primary">#FFC107</color>
<color name="primary_dark">#FFA000</color>
<color name="primary_light">#FFECB3</color>
<color name="accent">#607D8B</color>
<color name="primary_text">#212121</color>
<color name="secondary_text">#727272</color>
<color name="icons">#FFFFFF</color>
<color name="icons">#212121</color>
<color name="divider">#B6B6B6</color>
</resources>

View File

@ -0,0 +1,21 @@
<!--
~ Copyright 2015 Christian Basler
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>

View File

@ -8,4 +8,22 @@
<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="emoji_input">Emoji Input</string>
<string name="emoji_input_summary">Show the emoji button instead of enter</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="title_activity_open_bitmessage_link">Import Contact</string>
<string name="hello_world">Hello world!</string>
<string name="action_settings">Settings</string>
<string name="import_address">Import Address</string>
<string name="import_contact">Add to contacts</string>
<string name="label">Label</string>
<string name="subscribe">Subscribe</string>
<string name="do_import">Import</string>
<string name="cancel">Cancel</string>
</resources>