Skip to content

Commit f60ff62

Browse files
committed
Implement port of Xamarin Android Chat
1 parent 0a00978 commit f60ff62

File tree

92 files changed

+2432
-27
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

92 files changed

+2432
-27
lines changed

src/androidchat/.idea/misc.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/androidchat/app/build.gradle

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,43 @@
1+
buildscript {
2+
repositories {
3+
maven { url 'https://maven.fabric.io/public' }
4+
}
5+
6+
dependencies {
7+
// These docs use an open ended version so that our plugin
8+
// can be updated quickly in response to Android tooling updates
9+
10+
// We recommend changing it to the latest version from our changelog:
11+
// https://docs.fabric.io/android/changelog.html#fabric-gradle-plugin
12+
classpath 'io.fabric.tools:gradle:1.+'
13+
}
14+
}
15+
116
apply plugin: 'com.android.application'
17+
apply plugin: 'io.fabric'
218

19+
repositories {
20+
maven { url 'https://maven.fabric.io/public' }
21+
}
322
android {
423
compileSdkVersion 25
524
buildToolsVersion "25.0.2"
25+
626
defaultConfig {
727
applicationId "servicestack.net.androidchat"
828
minSdkVersion 21
929
targetSdkVersion 25
1030
versionCode 1
1131
versionName "1.0"
32+
1233
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
34+
jackOptions {
35+
enabled true
36+
}
37+
}
38+
compileOptions {
39+
sourceCompatibility JavaVersion.VERSION_1_8
40+
targetCompatibility JavaVersion.VERSION_1_8
1341
}
1442
buildTypes {
1543
release {
@@ -24,6 +52,12 @@ dependencies {
2452
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
2553
exclude group: 'com.android.support', module: 'support-annotations'
2654
})
27-
compile 'com.android.support:appcompat-v7:25.1.1'
55+
compile 'com.android.support:appcompat-v7:25.2.0'
56+
compile 'com.android.support:design:25.2.0'
57+
compile 'net.servicestack:android:1.0.30'
58+
compile 'com.facebook.android:facebook-android-sdk:[4,5)'
59+
compile('com.twitter.sdk.android:twitter:2.3.1@aar') {
60+
transitive = true;
61+
}
2862
testCompile 'junit:junit:4.12'
2963
}

src/androidchat/app/src/main/AndroidManifest.xml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,36 @@
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
33
package="servicestack.net.androidchat">
44

5+
<uses-sdk />
6+
<uses-permission android:name="android.permission.INTERNET" />
7+
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
8+
<uses-permission android:name="android.permission.VIBRATE" />
9+
510
<application
11+
android:name=".App"
612
android:allowBackup="true"
713
android:icon="@mipmap/ic_launcher"
814
android:label="@string/app_name"
915
android:supportsRtl="true"
1016
android:theme="@style/AppTheme">
17+
1118
<activity android:name=".MainActivity">
19+
</activity>
20+
21+
<activity android:name=".LoginActivity">
22+
</activity>
23+
24+
<activity android:name=".LoginButtonsActivity">
25+
<!-- Move to .LoginActivity if you prefer that login page instead -->
1226
<intent-filter>
1327
<action android:name="android.intent.action.MAIN" />
14-
1528
<category android:name="android.intent.category.LAUNCHER" />
1629
</intent-filter>
1730
</activity>
31+
32+
<meta-data android:name="io.fabric.ApiKey" android:value="b2d318d908fceea66ab422d2d31907d9444b01cc" />
33+
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>
34+
1835
</application>
1936

2037
</manifest>
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package servicestack.net.androidchat;
2+
3+
import android.content.Context;
4+
import android.view.LayoutInflater;
5+
import android.view.View;
6+
import android.view.ViewGroup;
7+
import android.widget.BaseAdapter;
8+
import android.widget.TextView;
9+
10+
import java.util.List;
11+
12+
/**
13+
* Created by mythz on 2/15/2017.
14+
*/
15+
16+
public class ActionListViewAdapter extends BaseAdapter {
17+
private Context context;
18+
private List<String> items;
19+
20+
public ActionListViewAdapter(Context context, List<String> items) {
21+
this.context = context;
22+
this.items = items;
23+
}
24+
25+
@Override
26+
public long getItemId(int position) {
27+
return position;
28+
}
29+
30+
@Override
31+
public View getView(int position, View convertView, ViewGroup parent) {
32+
View row = convertView;
33+
if (row == null)
34+
row = LayoutInflater.from(context).inflate(R.layout.action_row_item, null, false);
35+
TextView label = (TextView)row.findViewById(R.id.actionLabel);
36+
label.setText(items.get(position));
37+
return row;
38+
}
39+
40+
@Override
41+
public int getCount() {
42+
return items.size();
43+
}
44+
45+
@Override
46+
public Object getItem(int position) {
47+
return items.get(position);
48+
}
49+
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
package servicestack.net.androidchat;
2+
3+
import android.app.Application;
4+
import android.content.Context;
5+
import android.content.SharedPreferences;
6+
import android.graphics.Bitmap;
7+
import android.support.v4.util.LruCache;
8+
9+
import com.facebook.AccessToken;
10+
import com.facebook.login.LoginManager;
11+
import com.twitter.sdk.android.core.TwitterAuthToken;
12+
13+
import net.servicestack.android.AndroidServerEventsClient;
14+
import net.servicestack.android.AndroidServiceClient;
15+
import net.servicestack.android.AsyncUtils;
16+
import net.servicestack.client.AsyncSuccess;
17+
18+
/**
19+
* Created by mythz on 2/19/2017.
20+
*/
21+
22+
public class App extends Application {
23+
public static final String BaseUrl = "http://chat.servicestack.net/";
24+
25+
private Context context;
26+
private SharedPreferences prefs;
27+
private AndroidServerEventsClient serverEventsClient;
28+
private static App instance;
29+
private LruCache bitmapCache = new LruCache(4 * 1024 * 1024) {// 4MiB
30+
protected int sizeOf(String key, Bitmap value) {
31+
return value.getByteCount();
32+
}
33+
};
34+
35+
public App() {}
36+
37+
public App(Context context, String... channels) {
38+
this.context = context;
39+
this.prefs = context.getSharedPreferences("servicestack.net.androidchat",Context.MODE_PRIVATE);
40+
serverEventsClient = new AndroidServerEventsClient(BaseUrl, channels);
41+
}
42+
43+
public void onCreate() {
44+
super.onCreate();
45+
instance = new App(getApplicationContext(), "home");
46+
}
47+
48+
public static App get() {
49+
return instance;
50+
}
51+
52+
public Context getContext(){
53+
return context;
54+
}
55+
56+
public AndroidServerEventsClient getServerEventsClient(){
57+
return serverEventsClient;
58+
}
59+
60+
public AndroidServiceClient getServiceClient(){
61+
return serverEventsClient.getAndroidClient();
62+
}
63+
64+
public dtos.Authenticate getSavedAccessToken(){
65+
AccessToken facebookAccessToken = AccessToken.getCurrentAccessToken();
66+
if (facebookAccessToken != null){
67+
return new dtos.Authenticate()
68+
.setProvider("facebook")
69+
.setAccessToken(facebookAccessToken.getToken())
70+
.setRememberMe(true);
71+
}
72+
73+
String twitterAccessToken = prefs.getString("twitter.AccessToken", null);
74+
String twitterAccessSecret = prefs.getString("twitter.AccessTokenSecret", null);
75+
76+
if (twitterAccessToken == null || twitterAccessSecret == null)
77+
return null;
78+
79+
return new dtos.Authenticate()
80+
.setProvider("twitter")
81+
.setAccessToken(twitterAccessToken)
82+
.setAccessTokenSecret(twitterAccessSecret)
83+
.setRememberMe(true);
84+
}
85+
86+
public void saveTwitterAccessToken(TwitterAuthToken authToken){
87+
SharedPreferences.Editor editor = prefs.edit();
88+
editor.putString("twitter.AccessToken", authToken.token);
89+
editor.putString("twitter.AccessTokenSecret", authToken.secret);
90+
editor.apply();
91+
}
92+
93+
public void logout(){
94+
App.get().getServiceClient().clearCookies(); //Logout server
95+
96+
LoginManager.getInstance().logOut(); //Logout facebook
97+
98+
SharedPreferences.Editor editor = prefs.edit(); //Logout twitter
99+
editor.remove("twitter.AccessToken");
100+
editor.remove("twitter.AccessTokenSecret");
101+
editor.apply();
102+
}
103+
104+
public void readBitmap(final String url, final AsyncSuccess<Bitmap> success){
105+
Bitmap cachedBitmap = (Bitmap)bitmapCache.get(url);
106+
if (cachedBitmap != null){
107+
success.success(cachedBitmap);
108+
return;
109+
}
110+
111+
AsyncUtils.readBitmap(url, imageBitmap -> {
112+
bitmapCache.put(url, imageBitmap);
113+
success.success(imageBitmap);
114+
},
115+
error -> {
116+
error.printStackTrace();
117+
});
118+
}
119+
120+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package servicestack.net.androidchat;
2+
3+
import android.support.annotation.StringRes;
4+
import android.support.design.widget.NavigationView;
5+
import android.support.v4.widget.DrawerLayout;
6+
import android.support.v7.app.ActionBarDrawerToggle;
7+
import android.support.v7.app.AppCompatActivity;
8+
import android.support.v7.widget.Toolbar;
9+
import android.view.View;
10+
import android.widget.ListView;
11+
12+
/**
13+
* Created by mythz on 2/15/2017.
14+
*/
15+
public class ChatActionBarDrawerToggle extends ActionBarDrawerToggle {
16+
private AppCompatActivity hostActivity;
17+
private DrawerLayout drawerLayout;
18+
private int openedResource;
19+
private int closedResource;
20+
21+
private boolean rightIsClosed = true;
22+
private boolean leftIsClosed = true;
23+
24+
public ChatActionBarDrawerToggle(
25+
AppCompatActivity host,
26+
DrawerLayout drawerLayout,
27+
Toolbar toolbar,
28+
@StringRes int openedResource,
29+
@StringRes int closedResource) {
30+
super(host, drawerLayout, toolbar, openedResource, closedResource);
31+
32+
hostActivity = host;
33+
this.drawerLayout = drawerLayout;
34+
this.openedResource = openedResource;
35+
this.closedResource = closedResource;
36+
}
37+
38+
@Override
39+
public void onDrawerOpened(View drawerView)
40+
{
41+
int drawerType = (int)drawerView.getTag();
42+
43+
if (drawerType == 0){
44+
super.onDrawerOpened(drawerView);
45+
hostActivity.getSupportActionBar().setTitle(openedResource);
46+
}
47+
48+
if (drawerView.getId() == R.id.nav_view)
49+
leftIsClosed = false;
50+
51+
if (drawerView.getId() == R.id.right_drawer)
52+
rightIsClosed = false;
53+
}
54+
55+
@Override
56+
public void onDrawerClosed(View drawerView)
57+
{
58+
int drawerType = (int)drawerView.getTag();
59+
60+
if (drawerType == 0){
61+
super.onDrawerClosed(drawerView);
62+
hostActivity.getSupportActionBar().setTitle(closedResource);
63+
}
64+
65+
if (drawerView.getId() == R.id.nav_view)
66+
leftIsClosed = true;
67+
68+
if (drawerView.getId() == R.id.right_drawer)
69+
rightIsClosed = true;
70+
}
71+
72+
@Override
73+
public void onDrawerSlide(View drawerView, float slideOffset)
74+
{
75+
int drawerType = (int)drawerView.getTag();
76+
77+
NavigationView leftDrawer = (NavigationView)hostActivity.findViewById(R.id.nav_view);
78+
ListView rightDrawer = (ListView)hostActivity.findViewById(R.id.right_drawer);
79+
switch (drawerView.getId()){
80+
case R.id.right_drawer:
81+
if (drawerLayout.isDrawerOpen(leftDrawer) && !leftIsClosed){
82+
drawerLayout.closeDrawer(leftDrawer);
83+
leftIsClosed = true;
84+
}
85+
break;
86+
case R.id.nav_view:
87+
if (drawerLayout.isDrawerOpen(rightDrawer) && !rightIsClosed){
88+
drawerLayout.closeDrawer(rightDrawer);
89+
rightIsClosed = true;
90+
}
91+
break;
92+
}
93+
94+
if (drawerType == 0){
95+
super.onDrawerSlide(drawerView, slideOffset);
96+
}
97+
}
98+
}

0 commit comments

Comments
 (0)