├── .gitignore
├── .idea
├── .name
├── compiler.xml
├── copyright
│ └── profiles_settings.xml
├── encodings.xml
├── gradle.xml
├── misc.xml
├── modules.xml
├── runConfigurations.xml
└── vcs.xml
├── OpenVBX.iml
├── README.md
├── app
├── app.iml
├── build.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── ic_launcher-web.png
│ ├── java
│ └── org
│ │ └── openvbx
│ │ ├── AnnotationActivity.java
│ │ ├── CallActivity.java
│ │ ├── InboxActivity.java
│ │ ├── LoginActivity.java
│ │ ├── MessageActivity.java
│ │ ├── OpenVBX.java
│ │ ├── SmsActivity.java
│ │ ├── adapters
│ │ ├── AnnotationAdapter.java
│ │ ├── CallerIDAdapter.java
│ │ ├── MessagesAdapter.java
│ │ └── UserAdapter.java
│ │ └── models
│ │ ├── Annotation.java
│ │ ├── CallerID.java
│ │ ├── ClientResult.java
│ │ ├── Folder.java
│ │ ├── Inbox.java
│ │ ├── Message.java
│ │ ├── MessageResult.java
│ │ └── User.java
│ └── res
│ ├── drawable-hdpi
│ ├── ic_archive_white_36dp.png
│ ├── ic_call_white_48dp.png
│ ├── ic_folder_white_48dp.png
│ ├── ic_inbox_white_48dp.png
│ ├── ic_message_white_48dp.png
│ ├── ic_pause_white_48dp.png
│ ├── ic_play_arrow_white_48dp.png
│ ├── ic_reply_white_48dp.png
│ ├── ic_speaker_notes_white_36dp.png
│ ├── ic_textsms_white_36dp.png
│ └── ic_voicemail_white_48dp.png
│ ├── drawable-mdpi
│ ├── ic_archive_white_36dp.png
│ ├── ic_call_white_48dp.png
│ ├── ic_folder_white_48dp.png
│ ├── ic_inbox_white_48dp.png
│ ├── ic_message_white_48dp.png
│ ├── ic_pause_white_48dp.png
│ ├── ic_play_arrow_white_48dp.png
│ ├── ic_reply_white_48dp.png
│ ├── ic_speaker_notes_white_36dp.png
│ ├── ic_textsms_white_36dp.png
│ └── ic_voicemail_white_48dp.png
│ ├── drawable-xhdpi
│ ├── ic_archive_white_36dp.png
│ ├── ic_call_white_48dp.png
│ ├── ic_folder_white_48dp.png
│ ├── ic_inbox_white_48dp.png
│ ├── ic_message_white_48dp.png
│ ├── ic_pause_white_48dp.png
│ ├── ic_play_arrow_white_48dp.png
│ ├── ic_reply_white_48dp.png
│ ├── ic_speaker_notes_white_36dp.png
│ ├── ic_textsms_white_36dp.png
│ └── ic_voicemail_white_48dp.png
│ ├── drawable-xxhdpi
│ ├── ic_archive_white_36dp.png
│ ├── ic_call_white_48dp.png
│ ├── ic_folder_white_48dp.png
│ ├── ic_inbox_white_48dp.png
│ ├── ic_message_white_48dp.png
│ ├── ic_pause_white_48dp.png
│ ├── ic_play_arrow_white_48dp.png
│ ├── ic_reply_white_48dp.png
│ ├── ic_speaker_notes_white_36dp.png
│ ├── ic_textsms_white_36dp.png
│ └── ic_voicemail_white_48dp.png
│ ├── drawable-xxxhdpi
│ ├── ic_archive_white_36dp.png
│ ├── ic_call_white_48dp.png
│ ├── ic_folder_white_48dp.png
│ ├── ic_inbox_white_48dp.png
│ ├── ic_message_white_48dp.png
│ ├── ic_pause_white_48dp.png
│ ├── ic_play_arrow_white_48dp.png
│ ├── ic_reply_white_48dp.png
│ ├── ic_speaker_notes_white_36dp.png
│ ├── ic_textsms_white_36dp.png
│ └── ic_voicemail_white_48dp.png
│ ├── drawable
│ ├── drawer_header.xml
│ └── logo.png
│ ├── layout
│ ├── activity_annotation.xml
│ ├── activity_call.xml
│ ├── activity_inbox.xml
│ ├── activity_login.xml
│ ├── activity_message.xml
│ ├── activity_sms.xml
│ ├── dialog_settings.xml
│ ├── drawer_header.xml
│ ├── fragment_annotation_item.xml
│ ├── fragment_inbox_item.xml
│ ├── fragment_refreshable_list.xml
│ └── fragment_toolbar.xml
│ ├── menu
│ ├── menu_drawer.xml
│ ├── menu_inbox.xml
│ └── menu_message.xml
│ ├── mipmap-hdpi
│ └── ic_launcher.png
│ ├── mipmap-mdpi
│ └── ic_launcher.png
│ ├── mipmap-xhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxxhdpi
│ └── ic_launcher.png
│ └── values
│ ├── colors.xml
│ ├── strings.xml
│ └── themes.xml
├── build.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 | /local.properties
3 | /.idea/workspace.xml
4 | /.idea/libraries
5 | .DS_Store
6 | /build
7 | /app/build
8 |
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | OpenVBX-Android
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | 1.7
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/OpenVBX.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # OpenVBX for Android [](https://play.google.com/store/apps/details?id=org.openvbx)
2 |
3 | This repository contains the source code for the OpenVBX Android app.
4 |
5 | Please see the [issues](https://github.com/chadsmith/OpenVBX-Android/issues) section to report any bugs or feature requests and to see the list of known issues.
6 |
7 | ## Requirements
8 |
9 | * OpenVBX 0.90 or higher
10 | * Android 4.0.3 or higher
11 |
12 | ## Building in Android Studio
13 |
14 | `New > Import Project...` or `New > Project from Version Control > GitHub` should do the trick.
15 |
16 | ## Trademarks
17 |
18 | "OpenVBX" and "Twilio" are trademarks of Twilio, Inc., all rights reserved. If you want to redistribute this Android app, you must come up with your own product name. Use of the Twilio trademarks in your product name requires Twilio's written permission. This version of OpenVBX for Android was released with permission from Twilio, Inc.
19 |
20 | ## Acknowledgements
21 |
22 | This project uses open source libraries such as:
23 |
24 | * [RxAndroid](https://github.com/ReactiveX/RxAndroid)
25 | * [Retrofit](http://square.github.io/retrofit/)
26 |
27 | ## Contributing
28 |
29 | Please fork this repository and contribute back using [pull requests](https://github.com/chadsmith/OpenVBX-Android/pulls).
30 |
31 | Any contributions, large or small, major features, bug fixes, additional language translations, unit/integration tests are welcomed and appreciated.
--------------------------------------------------------------------------------
/app/app.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | generateDebugSources
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.2"
6 | defaultConfig {
7 | applicationId "org.openvbx"
8 | minSdkVersion 15
9 | targetSdkVersion 23
10 | versionCode 3
11 | versionName "1.0.1"
12 | multiDexEnabled true
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
18 | }
19 | }
20 | compileOptions {
21 | sourceCompatibility JavaVersion.VERSION_1_7
22 | targetCompatibility JavaVersion.VERSION_1_7
23 | }
24 | productFlavors {
25 | }
26 | }
27 |
28 | dependencies {
29 | compile fileTree(dir: 'libs', include: ['*.jar'])
30 | compile 'com.google.android.gms:play-services-gcm:8.4.0'
31 | compile 'io.reactivex:rxandroid:1.1.0'
32 | compile 'com.squareup.okhttp3:okhttp:3.2.0'
33 | compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'
34 | compile 'com.squareup.retrofit2:retrofit:2.0.2'
35 | compile 'com.squareup.retrofit2:converter-gson:2.0.2'
36 | compile 'com.squareup.retrofit2:converter-scalars:2.0.2'
37 | compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2'
38 | compile 'com.android.support:multidex:1.0.1'
39 | compile 'com.android.support:support-v4:23.3.0'
40 | compile 'com.android.support:appcompat-v7:23.3.0'
41 | compile 'com.android.support:design:23.3.0'
42 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
17 |
21 |
22 |
26 |
27 |
28 |
29 |
30 |
31 |
34 |
35 |
38 |
39 |
43 |
44 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/app/src/main/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/ic_launcher-web.png
--------------------------------------------------------------------------------
/app/src/main/java/org/openvbx/AnnotationActivity.java:
--------------------------------------------------------------------------------
1 | package org.openvbx;
2 |
3 | import android.os.Bundle;
4 | import android.support.v7.app.AppCompatActivity;
5 | import android.support.v7.widget.Toolbar;
6 | import android.view.MenuItem;
7 | import android.view.View;
8 | import android.widget.EditText;
9 |
10 | import org.openvbx.models.Message;
11 |
12 | import rx.functions.Action1;
13 |
14 | // TODO - move to dialog
15 | public class AnnotationActivity extends AppCompatActivity {
16 |
17 | private Message message;
18 |
19 | @Override
20 | public void onCreate(Bundle savedInstanceState) {
21 | super.onCreate(savedInstanceState);
22 |
23 | setContentView(R.layout.activity_annotation);
24 |
25 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
26 | setSupportActionBar(toolbar);
27 | getSupportActionBar().setDisplayHomeAsUpEnabled(true);
28 |
29 | Bundle extras = getIntent().getExtras();
30 | message = extras.getParcelable("message");
31 | findViewById(R.id.add).setOnClickListener(new View.OnClickListener() {
32 | public void onClick(View view) {
33 | String description = ((EditText) findViewById(R.id.description)).getText().toString();
34 | if (!description.isEmpty()) {
35 | OpenVBX.toast(R.string.saving);
36 | OpenVBX.API.addAnnotation(message.id, "noted", description)
37 | .compose(OpenVBX.defaultSchedulers())
38 | .subscribe(new Action1() {
39 | @Override
40 | public void call(Void ignored) {
41 | finish();
42 | }
43 | });
44 | }
45 | }
46 | });
47 | }
48 |
49 | @Override
50 | public boolean onOptionsItemSelected(MenuItem item) {
51 | int id = item.getItemId();
52 | switch(id) {
53 | case android.R.id.home:
54 | finish();
55 | break;
56 | }
57 | return super.onOptionsItemSelected(item);
58 | }
59 |
60 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/openvbx/CallActivity.java:
--------------------------------------------------------------------------------
1 | package org.openvbx;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.support.v7.widget.Toolbar;
7 | import android.view.MenuItem;
8 | import android.view.View;
9 | import android.widget.EditText;
10 | import android.widget.Spinner;
11 |
12 | import org.openvbx.adapters.CallerIDAdapter;
13 | import org.openvbx.models.MessageResult;
14 |
15 | import rx.functions.Action1;
16 |
17 | public class CallActivity extends AppCompatActivity {
18 |
19 | private Activity mActivity;
20 | private Spinner spinner;
21 | private EditText toInput;
22 | private int message_id = -1;
23 |
24 | // TODO - switch call button to FAB
25 | // TODO - add custom dial pad
26 | @Override
27 | public void onCreate(Bundle savedInstanceState) {
28 | super.onCreate(savedInstanceState);
29 |
30 | mActivity = this;
31 | setContentView(R.layout.activity_call);
32 |
33 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
34 | setSupportActionBar(toolbar);
35 | getSupportActionBar().setDisplayHomeAsUpEnabled(true);
36 |
37 | spinner = (Spinner) findViewById(R.id.callerid);
38 | CallerIDAdapter adapter = new CallerIDAdapter(this, OpenVBX.getCallerIDs("voice"));
39 | spinner.setAdapter(adapter);
40 |
41 | toInput = (EditText) findViewById(R.id.to);
42 |
43 | Bundle extras = getIntent().getExtras();
44 | if(extras != null) {
45 | spinner.setSelection(adapter.indexOf(extras.getString("from")));
46 | toInput.setText(extras.getString("to"));
47 | message_id = extras.getInt("message_id", -1);
48 | }
49 |
50 | findViewById(R.id.call).setOnClickListener(new View.OnClickListener() {
51 | public void onClick(View view) {
52 | String callerid = spinner.getSelectedItem().toString();
53 | String to = toInput.getText().toString().trim();
54 | if(!callerid.isEmpty() && !to.isEmpty()) {
55 | (message_id == -1 ? OpenVBX.API.sendCall(callerid, OpenVBX.device, to) : OpenVBX.API.sendCallback(message_id, callerid, OpenVBX.device, to))
56 | .compose(OpenVBX.defaultSchedulers())
57 | .subscribe(new Action1() {
58 | @Override
59 | public void call(MessageResult result) {
60 | if (result.error)
61 | OpenVBX.error(mActivity, result.message);
62 | else {
63 | OpenVBX.toast(R.string.calling);
64 | finish();
65 | }
66 | }
67 | });
68 | }
69 | }
70 | });
71 | }
72 |
73 | @Override
74 | public boolean onOptionsItemSelected(MenuItem item) {
75 | int id = item.getItemId();
76 | switch(id) {
77 | case android.R.id.home:
78 | finish();
79 | break;
80 | }
81 | return super.onOptionsItemSelected(item);
82 | }
83 |
84 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/openvbx/InboxActivity.java:
--------------------------------------------------------------------------------
1 | package org.openvbx;
2 |
3 | import android.content.Context;
4 | import android.content.DialogInterface;
5 | import android.content.Intent;
6 | import android.os.Bundle;
7 | import android.support.design.widget.NavigationView;
8 | import android.support.v4.widget.DrawerLayout;
9 | import android.support.v4.widget.SwipeRefreshLayout;
10 | import android.support.v7.app.ActionBarDrawerToggle;
11 | import android.support.v7.app.AlertDialog;
12 | import android.support.v7.app.AppCompatActivity;
13 | import android.support.v7.widget.Toolbar;
14 | import android.view.LayoutInflater;
15 | import android.view.Menu;
16 | import android.view.MenuItem;
17 | import android.view.View;
18 | import android.widget.AdapterView;
19 | import android.widget.BaseAdapter;
20 | import android.widget.EditText;
21 | import android.widget.HeaderViewListAdapter;
22 | import android.widget.LinearLayout;
23 | import android.widget.ListView;
24 | import android.widget.TextView;
25 |
26 | import org.openvbx.adapters.MessagesAdapter;
27 | import org.openvbx.models.CallerID;
28 | import org.openvbx.models.Folder;
29 | import org.openvbx.models.Inbox;
30 | import org.openvbx.models.Message;
31 |
32 | import java.util.ArrayList;
33 |
34 | import rx.Observable;
35 | import rx.functions.Action1;
36 | import rx.functions.Func1;
37 |
38 | public class InboxActivity extends AppCompatActivity {
39 |
40 | private Context mContext;
41 | private DrawerLayout drawerLayout;
42 | private Toolbar toolbar;
43 | private NavigationView navigationView;
44 | private LinearLayout mainContent;
45 | private MessagesAdapter messagesAdapter;
46 | private LinearLayout progress;
47 | private SwipeRefreshLayout refreshView;
48 |
49 | private Inbox inbox;
50 | private Folder folder = new Folder();
51 |
52 | @Override
53 | public void onCreate(Bundle savedInstanceState) {
54 | super.onCreate(savedInstanceState);
55 | setContentView(R.layout.activity_inbox);
56 |
57 | Bundle extras = getIntent().getExtras();
58 |
59 | if(extras != null)
60 | inbox = extras.getParcelable("inbox");
61 |
62 | mContext = getApplicationContext();
63 |
64 | drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
65 | toolbar = (Toolbar) findViewById(R.id.toolbar);
66 | setSupportActionBar(toolbar);
67 |
68 | mainContent = (LinearLayout) findViewById(R.id.main);
69 |
70 | ActionBarDrawerToggle drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.open, R.string.close) {
71 | public void onDrawerClosed(View view) {
72 | super.onDrawerClosed(view);
73 | }
74 |
75 | public void onDrawerOpened(View drawerView) {
76 | super.onDrawerOpened(drawerView);
77 | }
78 |
79 | public void onDrawerSlide(View drawerView, float slideOffset) {
80 | super.onDrawerSlide(drawerView, slideOffset);
81 | mainContent.setTranslationX(slideOffset * drawerView.getWidth());
82 | drawerLayout.bringChildToFront(drawerView);
83 | drawerLayout.requestLayout();
84 | }
85 | };
86 | drawerLayout.setDrawerListener(drawerToggle);
87 | drawerToggle.syncState();
88 |
89 | View headerView = LayoutInflater.from(this).inflate(R.layout.drawer_header, null);
90 | TextView currentUser = (TextView) headerView.findViewById(R.id.current_user);
91 | currentUser.setText(OpenVBX.email);
92 |
93 | navigationView = (NavigationView) findViewById(R.id.navigation_view);
94 | navigationView.addHeaderView(headerView);
95 | navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
96 | @Override
97 | public boolean onNavigationItemSelected(MenuItem menuItem) {
98 | int itemId = menuItem.getItemId();
99 | switch (itemId) {
100 | case R.id.settings:
101 | requestDevice();
102 | break;
103 | case R.id.logout:
104 | OpenVBX.signOut();
105 | requireLogin();
106 | break;
107 | default:
108 | selectFolder(itemId);
109 | menuItem.setChecked(true);
110 | }
111 | drawerLayout.closeDrawers();
112 | return true;
113 | }
114 | });
115 |
116 | progress = (LinearLayout) findViewById(R.id.progress);
117 | refreshView = (SwipeRefreshLayout) findViewById(R.id.refresh);
118 | ListView listView = (ListView) findViewById(R.id.list);
119 |
120 | messagesAdapter = new MessagesAdapter(this, R.layout.fragment_inbox_item, folder.messages.items);
121 |
122 | if(OpenVBX.endpoint == null || OpenVBX.email == null || OpenVBX.password == null)
123 | requireLogin();
124 | else if(OpenVBX.device == null)
125 | requestDevice();
126 | else
127 | getOutgoingCallerIDs();
128 |
129 | listView.setAdapter(messagesAdapter);
130 | listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
131 | @Override
132 | public void onItemClick(AdapterView> parent, View view, int position, long id) {
133 | Message message = messagesAdapter.get(position);
134 | Intent i = new Intent(mContext, MessageActivity.class);
135 | i.putExtra("message", message);
136 | startActivity(i);
137 | }
138 | });
139 | refreshView.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
140 | @Override
141 | public void onRefresh() {
142 | refresh();
143 | }
144 | });
145 | progress.setVisibility(View.VISIBLE);
146 | findViewById(R.id.call).setOnClickListener(new View.OnClickListener() {
147 | @Override
148 | public void onClick(View v) {
149 | Intent i = new Intent(mContext, CallActivity.class);
150 | startActivity(i);
151 | }
152 | });
153 | }
154 |
155 | public void requireLogin() {
156 | Intent i = new Intent(mContext, LoginActivity.class);
157 | startActivity(i);
158 | finish();
159 | }
160 |
161 | public void requestDevice() {
162 | View dialogView = LayoutInflater.from(this).inflate(R.layout.dialog_settings, null);
163 | final EditText deviceInput = (EditText) dialogView.findViewById(R.id.device);
164 | deviceInput.setText(OpenVBX.device);
165 | new AlertDialog.Builder(this)
166 | .setView(dialogView)
167 | .setCancelable(false)
168 | .setPositiveButton(R.string.save, new DialogInterface.OnClickListener() {
169 | @Override
170 | public void onClick(DialogInterface dialog, int which) {
171 | String device = deviceInput.getText().toString();
172 | if (!device.isEmpty()) {
173 | OpenVBX.saveDevice(device);
174 | dialog.dismiss();
175 | }
176 | }
177 | })
178 | .show();
179 | }
180 |
181 | public void getOutgoingCallerIDs() {
182 | OpenVBX.API.getOutgoingCallerIDs()
183 | .compose(OpenVBX.>defaultSchedulers())
184 | .subscribe(new Action1>() {
185 | @Override
186 | public void call(ArrayList callerIDs) {
187 | OpenVBX.callerIDs = callerIDs;
188 | }
189 | });
190 | }
191 |
192 | public void refresh() {
193 | OpenVBX.API.getFolders()
194 | .flatMap(new Func1>() {
195 | @Override
196 | public Observable call(Inbox update) {
197 | inbox = update;
198 | if (folder.id != -1)
199 | return OpenVBX.API.getFolder(folder.id);
200 | else if (!inbox.folders.isEmpty())
201 | return OpenVBX.API.getFolder(inbox.folders.get(0).id);
202 | else
203 | return Observable.just(new Folder());
204 | }
205 | })
206 | .compose(OpenVBX.defaultSchedulers())
207 | .subscribe(new Action1() {
208 | @Override
209 | public void call(Folder selected) {
210 | folder = selected;
211 | updateNavigationMenu();
212 | messagesAdapter.update(folder.messages.items);
213 | toolbar.setTitle(folder.name == null ? getString(R.string.app_name) : folder.name);
214 | progress.setVisibility(View.GONE);
215 | refreshView.setRefreshing(false);
216 | }
217 | });
218 | }
219 |
220 | private void updateNavigationMenu() {
221 | Menu menu = navigationView.getMenu();
222 | menu.removeGroup(R.id.primary_group);
223 | for(int i = 0; i < inbox.folders.size(); i++) {
224 | Folder folder = inbox.folders.get(i);
225 | MenuItem menuItem = menu.add(R.id.primary_group, i, i, folder.name);
226 | menuItem.setIcon("inbox".equals(folder.type) ? R.drawable.ic_inbox_white_48dp : R.drawable.ic_folder_white_48dp);
227 | }
228 | invalidateNavigationMenu();
229 | }
230 |
231 | private void invalidateNavigationMenu() {
232 | for (int i = 0, count = navigationView.getChildCount(); i < count; i++) {
233 | final View child = navigationView.getChildAt(i);
234 | if (child != null && child instanceof ListView) {
235 | final ListView menuView = (ListView) child;
236 | final HeaderViewListAdapter adapter = (HeaderViewListAdapter) menuView.getAdapter();
237 | final BaseAdapter wrapped = (BaseAdapter) adapter.getWrappedAdapter();
238 | wrapped.notifyDataSetChanged();
239 | }
240 | }
241 | }
242 |
243 | private void selectFolder(int folder_id) {
244 | if(folder.id != folder_id)
245 | progress.setVisibility(View.VISIBLE);
246 | OpenVBX.API.getFolder(folder_id)
247 | .compose(OpenVBX.defaultSchedulers())
248 | .subscribe(new Action1() {
249 | @Override
250 | public void call(Folder selected) {
251 | folder = selected;
252 | messagesAdapter.update(folder.messages.items);
253 | toolbar.setTitle(folder.name);
254 | progress.setVisibility(View.GONE);
255 | }
256 | });
257 | }
258 |
259 | @Override
260 | protected void onResume() {
261 | super.onResume();
262 | refresh();
263 | }
264 |
265 | @Override
266 | public boolean onCreateOptionsMenu(Menu menu) {
267 | getMenuInflater().inflate(R.menu.menu_inbox, menu);
268 | return true;
269 | }
270 |
271 | @Override
272 | public boolean onOptionsItemSelected(MenuItem item) {
273 | int id = item.getItemId();
274 | Intent i;
275 | switch(id) {
276 | case android.R.id.home:
277 | finish();
278 | break;
279 | case R.id.action_new_sms:
280 | i = new Intent(mContext, SmsActivity.class);
281 | startActivity(i);
282 | break;
283 | }
284 | return super.onOptionsItemSelected(item);
285 | }
286 |
287 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/openvbx/LoginActivity.java:
--------------------------------------------------------------------------------
1 | package org.openvbx;
2 |
3 | import android.Manifest;
4 | import android.app.Activity;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.content.pm.PackageManager;
8 | import android.os.Build;
9 | import android.os.Bundle;
10 | import android.support.v4.app.ActivityCompat;
11 | import android.support.v7.app.AppCompatActivity;
12 | import android.telephony.TelephonyManager;
13 | import android.view.View;
14 | import android.widget.EditText;
15 | import android.widget.LinearLayout;
16 |
17 | import org.openvbx.models.ClientResult;
18 | import org.openvbx.models.Inbox;
19 |
20 | import rx.Subscriber;
21 |
22 | public class LoginActivity extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback {
23 |
24 | private static final int PERMISSION_REQUEST_PHONE_STATE = 0;
25 | private Activity mActivity;
26 | private Context mContext;
27 |
28 | private LinearLayout setupView;
29 | private EditText endpointInput;
30 | private String endpoint;
31 |
32 | private LinearLayout loginView;
33 | private EditText emailInput;
34 | private EditText passwordInput;
35 | private String email;
36 | private String password;
37 |
38 | private Boolean canCheckPhoneState;
39 |
40 | @Override
41 | public void onCreate(Bundle savedInstanceState) {
42 | super.onCreate(savedInstanceState);
43 | setContentView(R.layout.activity_login);
44 |
45 | mActivity = this;
46 | mContext = getApplicationContext();
47 | setupView = (LinearLayout) findViewById(R.id.setup);
48 | endpointInput = (EditText) findViewById(R.id.endpoint);
49 |
50 | findViewById(R.id.next).setOnClickListener(new View.OnClickListener() {
51 | public void onClick(View view) {
52 | endpoint = endpointInput.getText().toString().trim();
53 | if(!endpoint.isEmpty()) {
54 | OpenVBX.setEndpoint(endpoint);
55 | checkEndpoint();
56 | }
57 | }
58 | });
59 |
60 | endpointInput.setText(OpenVBX.endpoint);
61 |
62 | if(ActivityCompat.checkSelfPermission(mActivity, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED)
63 | canCheckPhoneState = true;
64 | else
65 | ActivityCompat.requestPermissions(this, new String[]{ Manifest.permission.READ_PHONE_STATE }, PERMISSION_REQUEST_PHONE_STATE);
66 |
67 | loginView = (LinearLayout) findViewById(R.id.sign_in);
68 | emailInput = (EditText) findViewById(R.id.email);
69 | passwordInput = (EditText) findViewById(R.id.password);
70 |
71 | findViewById(R.id.login).setOnClickListener(new View.OnClickListener() {
72 | public void onClick(View view) {
73 | email = emailInput.getText().toString().trim();
74 | password = passwordInput.getText().toString();
75 | if(!email.isEmpty() && !password.isEmpty()) {
76 | OpenVBX.setLogin(email, password);
77 | OpenVBX.API.getFolders()
78 | .compose(OpenVBX.defaultSchedulers())
79 | .subscribe(new Subscriber() {
80 | @Override
81 | public void onCompleted() {
82 | }
83 |
84 | @Override
85 | public void onError(Throwable e) {
86 | OpenVBX.setLogin(email, null);
87 | passwordInput.setText(null);
88 | OpenVBX.error(mActivity, R.string.login_failed);
89 | }
90 |
91 | @Override
92 | public void onNext(Inbox inbox) {
93 | OpenVBX.saveLogin();
94 | if (canCheckPhoneState) {
95 | TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
96 | String device = telephonyManager.getLine1Number();
97 | if (!device.isEmpty() && !Build.PRODUCT.equals("sdk") && !Build.PRODUCT.equals("google_sdk"))
98 | OpenVBX.saveDevice(device);
99 | }
100 | Intent i = new Intent(mContext, InboxActivity.class);
101 | i.putExtra("inbox", inbox);
102 | startActivity(i);
103 | finish();
104 | }
105 | });
106 | }
107 | }
108 | });
109 |
110 | emailInput.setText(OpenVBX.email);
111 | passwordInput.setText(OpenVBX.password);
112 | }
113 |
114 | public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
115 | switch (requestCode) {
116 | case PERMISSION_REQUEST_PHONE_STATE:
117 | if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
118 | canCheckPhoneState = true;
119 | break;
120 | default:
121 | super.onRequestPermissionsResult(requestCode, permissions, grantResults);
122 | }
123 | }
124 |
125 | private void checkEndpoint() {
126 | OpenVBX.API.checkEndpoint()
127 | .compose(OpenVBX.defaultSchedulers())
128 | .subscribe(new Subscriber() {
129 | @Override
130 | public void onCompleted() {
131 | }
132 |
133 | @Override
134 | public void onError(Throwable e) {
135 | if (endpoint.endsWith("index.php")) {
136 | OpenVBX.setEndpoint(null);
137 | endpointInput.setText(null);
138 | OpenVBX.error(mActivity, R.string.invalid_endpoint);
139 | } else {
140 | if (!endpoint.endsWith("/"))
141 | endpoint += "/";
142 | endpoint += "index.php";
143 | OpenVBX.setEndpoint(endpoint);
144 | checkEndpoint();
145 | }
146 | }
147 |
148 | @Override
149 | public void onNext(ClientResult result) {
150 | OpenVBX.saveEndpoint();
151 | setupView.setVisibility(View.GONE);
152 | loginView.setVisibility(View.VISIBLE);
153 | }
154 | });
155 | }
156 |
157 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/openvbx/MessageActivity.java:
--------------------------------------------------------------------------------
1 | package org.openvbx;
2 |
3 | import android.content.Intent;
4 | import android.media.AudioManager;
5 | import android.media.MediaPlayer;
6 | import android.os.Bundle;
7 | import android.support.v7.app.AppCompatActivity;
8 | import android.support.v7.widget.Toolbar;
9 | import android.view.Menu;
10 | import android.view.MenuItem;
11 | import android.view.MotionEvent;
12 | import android.view.View;
13 | import android.view.View.OnTouchListener;
14 | import android.widget.AdapterView;
15 | import android.widget.AdapterView.OnItemSelectedListener;
16 | import android.widget.ArrayAdapter;
17 | import android.widget.ImageView;
18 | import android.widget.LinearLayout;
19 | import android.widget.ListView;
20 | import android.widget.SeekBar;
21 | import android.widget.Spinner;
22 | import android.widget.TextView;
23 |
24 | import org.openvbx.adapters.AnnotationAdapter;
25 | import org.openvbx.adapters.UserAdapter;
26 | import org.openvbx.models.Annotation;
27 | import org.openvbx.models.Message;
28 | import org.openvbx.models.User;
29 |
30 | import java.util.ArrayList;
31 |
32 | import rx.functions.Action1;
33 |
34 | public class MessageActivity extends AppCompatActivity {
35 |
36 | private Boolean isVoice = false;
37 | private MediaPlayer mediaPlayer = null;
38 | private SeekBar seekBar;
39 | private ImageView play;
40 | private Thread updateProgress = null;
41 | private String statuses[] = { "Open", "Closed", "Pending" };
42 | private Spinner status;
43 | private Spinner assigned;
44 | private UserAdapter userAdapter;
45 | private AnnotationAdapter annotationAdapter;
46 | private Message message;
47 | private ListView annotationList;
48 | private LinearLayout progress;
49 | private Boolean isPaused = false;
50 |
51 | @Override
52 | public void onCreate(Bundle savedInstanceState) {
53 | super.onCreate(savedInstanceState);
54 |
55 | setContentView(R.layout.activity_message);
56 |
57 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
58 | setSupportActionBar(toolbar);
59 | getSupportActionBar().setDisplayHomeAsUpEnabled(true);
60 |
61 | progress = (LinearLayout) findViewById(R.id.progress);
62 |
63 | Bundle extras = getIntent().getExtras();
64 | message = extras.getParcelable("message");
65 |
66 | annotationList = (ListView) findViewById(R.id.annotations);
67 | annotationAdapter = new AnnotationAdapter(this, R.layout.fragment_annotation_item, new ArrayList());
68 | annotationList.setAdapter(annotationAdapter);
69 |
70 | status = (Spinner) findViewById(R.id.status);
71 | ArrayAdapter statusAdapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, statuses);
72 | statusAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
73 | status.setAdapter(statusAdapter);
74 | status.setOnItemSelectedListener(new OnItemSelectedListener() {
75 | public void onItemSelected(AdapterView> parent, View view, int pos, long id) {
76 | final String status = statuses[pos].toLowerCase();
77 | OpenVBX.API.updateTicketStatus(message.id, status)
78 | .compose(OpenVBX.defaultSchedulers())
79 | .subscribe(new Action1() {
80 | @Override
81 | public void call(Void ignored) {
82 | // TODO - refresh view
83 | }
84 | });
85 | }
86 |
87 | public void onNothingSelected(AdapterView> parent) {
88 | }
89 | });
90 |
91 | assigned = (Spinner) findViewById(R.id.assigned);
92 | userAdapter = new UserAdapter(this, new ArrayList());
93 | assigned.setAdapter(userAdapter);
94 | assigned.setOnItemSelectedListener(new OnItemSelectedListener() {
95 | public void onItemSelected(AdapterView> parent, View view, int pos, long id) {
96 | final int user_id = message.active_users.get(pos).id;
97 | OpenVBX.API.updateAssignment(message.id, user_id)
98 | .compose(OpenVBX.defaultSchedulers())
99 | .subscribe(new Action1() {
100 | @Override
101 | public void call(Void ignored) {
102 | // TODO - refresh view
103 | }
104 | });
105 | }
106 |
107 | public void onNothingSelected(AdapterView> parent) {
108 | }
109 | });
110 |
111 | progress.setVisibility(View.VISIBLE);
112 |
113 | findViewById(R.id.reply).setOnClickListener(new View.OnClickListener() {
114 | public void onClick(View view) {
115 | Intent i = new Intent(getApplicationContext(), isVoice ? CallActivity.class : SmsActivity.class);
116 | i.putExtra("from", message.original_called);
117 | i.putExtra("to", message.original_caller);
118 | i.putExtra("message_id", message.id);
119 | startActivity(i);
120 | }
121 | });
122 | }
123 |
124 | public void refresh() {
125 | OpenVBX.API.getMessage(message.id)
126 | .compose(OpenVBX.defaultSchedulers())
127 | .subscribe(new Action1() {
128 | @Override
129 | public void call(Message update) {
130 | message = update;
131 |
132 | ((TextView) findViewById(R.id.caller)).setText(message.caller);
133 | ((TextView) findViewById(R.id.received_time)).setText(message.receivedTime());
134 |
135 | TextView folder = (TextView) findViewById(R.id.folder);
136 | folder.setText(message.folder);
137 | if (message.folder.isEmpty())
138 | folder.setVisibility(View.GONE);
139 |
140 | ((TextView) findViewById(R.id.summary)).setText(message.summary);
141 |
142 | if (message.isVoice()) {
143 | for (int i = 0; i < statuses.length; i++)
144 | if (statuses[i].toLowerCase().equals(message.ticket_status))
145 | status.setSelection(i);
146 | status.setVisibility(View.VISIBLE);
147 |
148 | if (!message.folder.isEmpty()) {
149 | message.active_users.add(0, new User(0, "Select a", "user"));
150 | userAdapter.update(message.active_users);
151 | if (message.assigned != -1)
152 | assigned.setSelection(userAdapter.indexOf(message.assigned));
153 | assigned.setVisibility(View.VISIBLE);
154 | }
155 |
156 | if (!message.annotations.items.isEmpty()) {
157 | annotationAdapter.update(message.annotations.items);
158 | annotationList.setVisibility(View.VISIBLE);
159 | }
160 |
161 | status.setVisibility(View.VISIBLE);
162 | play = (ImageView) findViewById(R.id.play);
163 | seekBar = (SeekBar) findViewById(R.id.seekbar);
164 | seekBar.setOnTouchListener(new OnTouchListener() {
165 | public boolean onTouch(View v, MotionEvent event) {
166 | if (mediaPlayer.isPlaying()) {
167 | SeekBar sb = (SeekBar) v;
168 | mediaPlayer.seekTo(sb.getProgress());
169 | }
170 | return false;
171 | }
172 | });
173 | play.setOnClickListener(new View.OnClickListener() {
174 | @Override
175 | public void onClick(View v) {
176 | if(mediaPlayer.isPlaying()) {
177 | isPaused = true;
178 | mediaPlayer.pause();
179 | updateButtonState(false);
180 | }
181 | else {
182 | isPaused = false;
183 | int curr = seekBar.getProgress();
184 | int total = mediaPlayer.getDuration();
185 | seekBar.setMax(total);
186 | if(curr < total)
187 | mediaPlayer.seekTo(curr);
188 | else
189 | mediaPlayer.seekTo(0);
190 | mediaPlayer.start();
191 | updateButtonState(true);
192 | updateProgress = new Thread(new Runnable() {
193 | public void run() {
194 | Thread currentThread = Thread.currentThread();
195 | int curr = mediaPlayer.getCurrentPosition();
196 | int total = mediaPlayer.getDuration();
197 | seekBar.setProgress(curr);
198 | while (currentThread == updateProgress && mediaPlayer != null && mediaPlayer.isPlaying()) {
199 | try {
200 | curr = mediaPlayer.getCurrentPosition();
201 | seekBar.setProgress(curr);
202 | Thread.sleep(100);
203 | } catch (InterruptedException e) {
204 | e.printStackTrace();
205 | }
206 | }
207 | if(!isPaused) {
208 | seekBar.setProgress(total);
209 | updateButtonState(false);
210 | }
211 | }
212 | });
213 | updateProgress.start();
214 | }
215 | }
216 | });
217 | seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
218 | @Override
219 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
220 | if(fromUser)
221 | mediaPlayer.seekTo(progress);
222 | }
223 |
224 | @Override
225 | public void onStartTrackingTouch(SeekBar seekBar) {
226 | }
227 |
228 | @Override
229 | public void onStopTrackingTouch(SeekBar seekBar) {
230 | }
231 | });
232 | mediaPlayer = new MediaPlayer();
233 | mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
234 | try {
235 | mediaPlayer.setDataSource(message.recording_url);
236 | } catch (Exception e) {
237 | e.printStackTrace();
238 | }
239 | mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
240 | @Override
241 | public void onPrepared(MediaPlayer mp) {
242 | findViewById(R.id.audio).setVisibility(View.VISIBLE);
243 | }
244 | });
245 | mediaPlayer.prepareAsync();
246 | }
247 |
248 | invalidateOptionsMenu();
249 | progress.setVisibility(View.GONE);
250 | }
251 | });
252 | }
253 |
254 | public void updateButtonState(final Boolean showPause) {
255 | runOnUiThread(new Runnable() {
256 | @Override
257 | public void run() {
258 | play.setImageResource(showPause ? R.drawable.ic_pause_white_48dp : R.drawable.ic_play_arrow_white_48dp);
259 | }
260 | });
261 | }
262 |
263 | @Override
264 | protected void onResume() {
265 | super.onResume();
266 | refresh();
267 | }
268 |
269 | @Override
270 | public boolean onCreateOptionsMenu(Menu menu) {
271 | getMenuInflater().inflate(R.menu.menu_message, menu);
272 | menu.findItem(R.id.action_add_note).setVisible(isVoice);
273 | return true;
274 | }
275 |
276 | @Override
277 | public boolean onOptionsItemSelected(MenuItem item) {
278 | int id = item.getItemId();
279 | Intent i;
280 | switch(id) {
281 | case android.R.id.home:
282 | finish();
283 | break;
284 | case R.id.action_add_note:
285 | i = new Intent(getApplicationContext(), AnnotationActivity.class);
286 | i.putExtra("message", message);
287 | startActivity(i);
288 | break;
289 | case R.id.action_archive:
290 | // TODO - confirm before deleting
291 | OpenVBX.API.archiveMessage(message.id, true)
292 | .compose(OpenVBX.defaultSchedulers())
293 | .subscribe(new Action1() {
294 | @Override
295 | public void call(Void ignored) {
296 | OpenVBX.toast(R.string.message_archived);
297 | finish();
298 | }
299 | });
300 | break;
301 | }
302 | return super.onOptionsItemSelected(item);
303 | }
304 |
305 | @Override
306 | protected void onPause() {
307 | super.onPause();
308 | updateProgress = null;
309 | if(mediaPlayer != null) {
310 | mediaPlayer.release();
311 | mediaPlayer = null;
312 | }
313 | }
314 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/openvbx/OpenVBX.java:
--------------------------------------------------------------------------------
1 | package org.openvbx;
2 |
3 | import android.app.Activity;
4 | import android.app.Application;
5 | import android.content.Context;
6 | import android.content.SharedPreferences;
7 | import android.os.Handler;
8 | import android.os.Looper;
9 | import android.support.v7.app.AlertDialog;
10 | import android.util.Base64;
11 | import android.widget.Toast;
12 |
13 | import org.openvbx.models.CallerID;
14 | import org.openvbx.models.ClientResult;
15 | import org.openvbx.models.Folder;
16 | import org.openvbx.models.Inbox;
17 | import org.openvbx.models.Message;
18 | import org.openvbx.models.MessageResult;
19 |
20 | import java.io.IOException;
21 | import java.util.ArrayList;
22 |
23 | import okhttp3.Interceptor;
24 | import okhttp3.OkHttpClient;
25 | import okhttp3.Request;
26 | import okhttp3.Response;
27 | import okhttp3.logging.HttpLoggingInterceptor;
28 | import retrofit2.Retrofit;
29 | import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
30 | import retrofit2.converter.gson.GsonConverterFactory;
31 | import retrofit2.http.Field;
32 | import retrofit2.http.FormUrlEncoded;
33 | import retrofit2.http.GET;
34 | import retrofit2.http.POST;
35 | import retrofit2.http.Path;
36 | import rx.Observable;
37 | import rx.android.schedulers.AndroidSchedulers;
38 | import rx.schedulers.Schedulers;
39 |
40 | public class OpenVBX extends Application {
41 |
42 | private static SharedPreferences settings;
43 |
44 | public static String endpoint = null;
45 | public static String email = null;
46 | public static String password = null;
47 | public static String device = null;
48 | public static Context mContext;
49 |
50 | public static VbxService API;
51 |
52 | public static ArrayList callerIDs = new ArrayList<>();
53 |
54 | public void onCreate() {
55 |
56 | super.onCreate();
57 |
58 | mContext = getApplicationContext();
59 | settings = getSharedPreferences("settings", MODE_PRIVATE);
60 | endpoint = settings.getString("endpoint", null);
61 | email = settings.getString("email", null);
62 | password = settings.getString("password", null);
63 | device = settings.getString("device", null);
64 |
65 | if(endpoint != null && !endpoint.isEmpty())
66 | API = getApiInstance();
67 | }
68 |
69 | private static VbxService getApiInstance() {
70 |
71 | // Use HttpLoggingInterceptor.Level.NONE to disable logging
72 | HttpLoggingInterceptor logger = new HttpLoggingInterceptor();
73 | logger.setLevel(HttpLoggingInterceptor.Level.BODY);
74 |
75 | Interceptor setAcceptType = new Interceptor() {
76 | @Override
77 | public Response intercept(Chain chain) throws IOException {
78 | Request request = chain.request();
79 | Request typedRequest = request
80 | .newBuilder()
81 | .header("Accept", "application/json")
82 | .build();
83 | return chain.proceed(typedRequest);
84 | }
85 | };
86 |
87 | Interceptor setAuthorization = new Interceptor() {
88 | @Override
89 | public Response intercept(Chain chain) throws IOException {
90 | Request request = chain.request();
91 | if(email != null && password != null) {
92 | String auth = Base64.encodeToString((email + ":" + password).getBytes(), Base64.NO_WRAP);
93 | Request typedRequest = request
94 | .newBuilder()
95 | .header("Authorization", String.format("Basic %s", auth))
96 | .build();
97 | return chain.proceed(typedRequest);
98 | }
99 | return chain.proceed(request);
100 | }
101 | };
102 |
103 | OkHttpClient apiClient = new OkHttpClient.Builder()
104 | .addInterceptor(logger)
105 | .addInterceptor(setAcceptType)
106 | .addInterceptor(setAuthorization)
107 | .build();
108 |
109 | return new Retrofit.Builder()
110 | .baseUrl(endpoint)
111 | .client(apiClient)
112 | .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
113 | .addConverterFactory(GsonConverterFactory.create())
114 | .build()
115 | .create(VbxService.class);
116 | }
117 |
118 | public static ArrayList getCallerIDs(String type) {
119 | if("voice".equals(type))
120 | return callerIDs;
121 | ArrayList result = new ArrayList<>();
122 | for(CallerID callerID : callerIDs)
123 | if(callerID.hasSms())
124 | result.add(callerID);
125 | return result;
126 | }
127 |
128 | public static void setEndpoint(String endpoint) {
129 | OpenVBX.endpoint = endpoint;
130 | API = getApiInstance();
131 | }
132 |
133 | public static void saveEndpoint() {
134 | settings.edit().putString("endpoint", endpoint).apply();
135 | }
136 |
137 | public static void setLogin(String email, String password) {
138 | OpenVBX.email = email;
139 | OpenVBX.password = password;
140 | }
141 |
142 | public static void saveLogin() {
143 | settings.edit().putString("email", email).putString("password", password).apply();
144 | }
145 |
146 | public static void saveDevice(String device) {
147 | OpenVBX.device = device;
148 | settings.edit().putString("device", device).apply();
149 | }
150 |
151 | public static void signOut() {
152 | settings.edit().clear().apply();
153 | endpoint = null;
154 | email = null;
155 | password = null;
156 | device = null;
157 | }
158 |
159 | public static void error(Activity activity, String message) {
160 | new AlertDialog.Builder(activity)
161 | .setMessage(message)
162 | .setPositiveButton(R.string.ok, null)
163 | .show();
164 | }
165 |
166 | public static void error(Activity activity, int message) {
167 | new AlertDialog.Builder(activity)
168 | .setMessage(message)
169 | .setPositiveButton(R.string.ok, null)
170 | .show();
171 | }
172 |
173 | public static void toast(final String message) {
174 | new Handler(Looper.getMainLooper()).post(new Runnable() {
175 | @Override
176 | public void run() {
177 | Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
178 | }
179 | });
180 | }
181 |
182 | public static void toast(int id) {
183 | toast(mContext.getString(id));
184 | }
185 |
186 | public interface VbxService {
187 |
188 | @GET("/client")
189 | Observable checkEndpoint();
190 |
191 | @GET("/messages/inbox")
192 | Observable getFolders();
193 |
194 | @GET("/messages/inbox/{folder_id}")
195 | Observable getFolder(@Path("folder_id") int folder_id);
196 |
197 | @GET("/messages/details/{message_id}")
198 | Observable getMessage(@Path("message_id") int message_id);
199 |
200 | @FormUrlEncoded
201 | @POST("/messages/details/{message_id}")
202 | Observable archiveMessage(@Path("message_id") int message_id, @Field("archived") Boolean archived);
203 |
204 | @FormUrlEncoded
205 | @POST("/messages/details/{message_id}")
206 | Observable updateTicketStatus(@Path("message_id") int message_id, @Field("ticket_status") String status);
207 |
208 | @FormUrlEncoded
209 | @POST("/messages/details/{message_id}")
210 | Observable updateAssignment(@Path("message_id") int message_id, @Field("assigned") int user_id);
211 |
212 | @FormUrlEncoded
213 | @POST("/messages/details/{message_id}/annotations")
214 | Observable addAnnotation(@Path("message_id") int message_id, @Field("annotation_type") String annotation_type, @Field("description") String description);
215 |
216 | @FormUrlEncoded
217 | @POST("/messages/sms")
218 | Observable sendMessage(@Field("from") String from, @Field("to") String to, @Field("content") String content);
219 |
220 | @FormUrlEncoded
221 | @POST("/messages/sms/{message_id}")
222 | Observable sendReply(@Path("message_id") int message_id, @Field("from") String from, @Field("to") String to, @Field("content") String content);
223 |
224 | @FormUrlEncoded
225 | @POST("/messages/call")
226 | Observable sendCall(@Field("callerid") String callerid, @Field("from") String from, @Field("to") String to);
227 |
228 | @FormUrlEncoded
229 | @POST("/messages/call/{message_id}")
230 | Observable sendCallback(@Path("message_id") int message_id, @Field("callerid") String callerid, @Field("from") String from, @Field("to") String to);
231 |
232 | @GET("/numbers/outgoingcallerid")
233 | Observable> getOutgoingCallerIDs();
234 | }
235 |
236 | public static Observable.Transformer defaultSchedulers() {
237 | return new Observable.Transformer() {
238 | @Override
239 | public Observable call(Observable observable) {
240 | return observable.subscribeOn(Schedulers.io())
241 | .observeOn(AndroidSchedulers.mainThread());
242 | }
243 | };
244 | }
245 |
246 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/openvbx/SmsActivity.java:
--------------------------------------------------------------------------------
1 | package org.openvbx;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.support.v7.widget.Toolbar;
7 | import android.view.MenuItem;
8 | import android.view.View;
9 | import android.widget.EditText;
10 | import android.widget.Spinner;
11 |
12 | import org.openvbx.adapters.CallerIDAdapter;
13 | import org.openvbx.models.MessageResult;
14 |
15 | import rx.functions.Action1;
16 |
17 | public class SmsActivity extends AppCompatActivity {
18 |
19 | private Activity mActivity;
20 | private Spinner spinner;
21 | private EditText toInput;
22 | private int message_id = -1;
23 |
24 | // TODO - switch send button to FAB
25 | @Override
26 | public void onCreate(Bundle savedInstanceState) {
27 | super.onCreate(savedInstanceState);
28 |
29 | mActivity = this;
30 | setContentView(R.layout.activity_sms);
31 |
32 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
33 | setSupportActionBar(toolbar);
34 | getSupportActionBar().setDisplayHomeAsUpEnabled(true);
35 |
36 | spinner = (Spinner) findViewById(R.id.from);
37 | CallerIDAdapter adapter = new CallerIDAdapter(this, OpenVBX.getCallerIDs("sms"));
38 | spinner.setAdapter(adapter);
39 |
40 | toInput = (EditText) findViewById(R.id.to);
41 |
42 | Bundle extras = getIntent().getExtras();
43 | if(extras != null) {
44 | spinner.setSelection(adapter.indexOf(extras.getString("from")));
45 | toInput.setText(extras.getString("to"));
46 | message_id = extras.getInt("message_id", -1);
47 | }
48 |
49 | findViewById(R.id.send).setOnClickListener(new View.OnClickListener() {
50 | public void onClick(View view) {
51 | String from = spinner.getSelectedItem().toString();
52 | String to = toInput.getText().toString().trim();
53 | String content = ((EditText) findViewById(R.id.content)).getText().toString();
54 | if (!from.isEmpty() && !to.isEmpty() && !content.isEmpty()) {
55 | (message_id == -1 ? OpenVBX.API.sendMessage(from, to, content) : OpenVBX.API.sendReply(message_id, from, to, content))
56 | .compose(OpenVBX.defaultSchedulers())
57 | .subscribe(new Action1() {
58 | @Override
59 | public void call(MessageResult result) {
60 | if (result.error)
61 | OpenVBX.error(mActivity, result.message);
62 | else {
63 | OpenVBX.toast(R.string.message_sent);
64 | finish();
65 | }
66 | }
67 | });
68 | }
69 | }
70 | });
71 | }
72 |
73 | @Override
74 | public boolean onOptionsItemSelected(MenuItem item) {
75 | int id = item.getItemId();
76 | switch(id) {
77 | case android.R.id.home:
78 | finish();
79 | break;
80 | }
81 | return super.onOptionsItemSelected(item);
82 | }
83 |
84 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/openvbx/adapters/AnnotationAdapter.java:
--------------------------------------------------------------------------------
1 | package org.openvbx.adapters;
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.ArrayAdapter;
8 | import android.widget.TextView;
9 |
10 | import org.openvbx.R;
11 | import org.openvbx.models.Annotation;
12 |
13 | import java.util.ArrayList;
14 |
15 | public class AnnotationAdapter extends ArrayAdapter {
16 | public ArrayList annotations;
17 | private int ViewResourceId;
18 | private LayoutInflater inflater;
19 |
20 | public AnnotationAdapter(Context context, int textViewResourceId, ArrayList annotations) {
21 | super(context, textViewResourceId, annotations);
22 | this.annotations = annotations;
23 | this.ViewResourceId = textViewResourceId;
24 | inflater = LayoutInflater.from(context);
25 | }
26 |
27 | @Override
28 | public View getView(int position, View convertView, ViewGroup parent) {
29 | View view = convertView;
30 | if (view == null) {
31 | view = inflater.inflate(ViewResourceId, null);
32 | }
33 | Annotation annotation = annotations.get(position);
34 | if (annotation != null) {
35 | TextView name = (TextView) view.findViewById(R.id.name);
36 | TextView description = (TextView) view.findViewById(R.id.description);
37 | name.setText(annotation.getName());
38 | description.setText(annotation.description);
39 | }
40 | return view;
41 | }
42 |
43 | @Override
44 | public int getCount() {
45 | return annotations.size();
46 | }
47 |
48 | public Annotation get(int position) {
49 | return annotations.get(position);
50 | }
51 |
52 | public void update(ArrayList annotations) {
53 | this.annotations = annotations;
54 | notifyDataSetChanged();
55 | }
56 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/openvbx/adapters/CallerIDAdapter.java:
--------------------------------------------------------------------------------
1 | package org.openvbx.adapters;
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 org.openvbx.models.CallerID;
11 |
12 | import java.util.ArrayList;
13 |
14 | public class CallerIDAdapter extends BaseAdapter {
15 | public ArrayList callerids;
16 | private LayoutInflater inflater;
17 |
18 | static class ViewHolder {
19 | TextView text;
20 | }
21 |
22 | public CallerIDAdapter(Context context, ArrayList callerids) {
23 | this.callerids = callerids;
24 | inflater = LayoutInflater.from(context);
25 | }
26 |
27 | public int getCount() {
28 | return callerids.size();
29 | }
30 |
31 | public CallerID get(int position){
32 | return callerids.get(position);
33 | }
34 |
35 | public void add(CallerID callerid){
36 | callerids.add(callerid);
37 | }
38 |
39 | public String getItem(int position){
40 | return get(position).name;
41 | }
42 |
43 | public long getItemId(int position) {
44 | return callerids.indexOf(get(position));
45 | }
46 |
47 | public int indexOf(String number) {
48 | for(int i = 0; i < callerids.size(); i++)
49 | if(number.equals(callerids.get(i).phone_number))
50 | return i;
51 | return -1;
52 | }
53 |
54 | public View getView(int position, View convertView, ViewGroup parent) {
55 | return createResource(position, convertView, parent, android.R.layout.simple_spinner_item);
56 | }
57 |
58 | public View getDropDownView(int position, View convertView, ViewGroup parent) {
59 | return createResource(position, convertView, parent, android.R.layout.simple_spinner_dropdown_item);
60 | }
61 |
62 | public View createResource(int position, View convertView, ViewGroup parent, int resource) {
63 | View v = convertView;
64 | ViewHolder vh;
65 | if (v == null) {
66 | v = inflater.inflate(resource, parent, false);
67 | vh = new ViewHolder();
68 | vh.text = (TextView) v.findViewById(android.R.id.text1);
69 | v.setTag(vh);
70 | }
71 | else
72 | vh = (ViewHolder) v.getTag();
73 | vh.text.setText(get(position).name);
74 | return v;
75 | }
76 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/openvbx/adapters/MessagesAdapter.java:
--------------------------------------------------------------------------------
1 | package org.openvbx.adapters;
2 |
3 | import android.content.Context;
4 | import android.graphics.Typeface;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.ArrayAdapter;
9 | import android.widget.ImageView;
10 | import android.widget.TextView;
11 |
12 | import org.openvbx.R;
13 | import org.openvbx.models.Message;
14 |
15 | import java.util.ArrayList;
16 |
17 | public class MessagesAdapter extends ArrayAdapter {
18 | public ArrayList messages;
19 | private int ViewResourceId;
20 | private LayoutInflater inflater;
21 |
22 | public MessagesAdapter(Context context, int textViewResourceId, ArrayList messages) {
23 | super(context, textViewResourceId, messages);
24 | this.messages = messages;
25 | this.ViewResourceId = textViewResourceId;
26 | inflater = LayoutInflater.from(context);
27 | }
28 |
29 | public int indexOf(int id) {
30 | for(int i = 0; i < messages.size(); i++)
31 | if(id == messages.get(i).id)
32 | return i;
33 | return -1;
34 | }
35 |
36 | @Override
37 | public View getView(int position, View convertView, ViewGroup parent) {
38 | View view = convertView;
39 | if (view == null) {
40 | view = inflater.inflate(ViewResourceId, null);
41 | }
42 | Message message = messages.get(position);
43 | if (message != null) {
44 | ImageView icon = (ImageView) view.findViewById(R.id.icon);
45 | TextView caller = (TextView) view.findViewById(R.id.caller);
46 | TextView folder = (TextView) view.findViewById(R.id.folder);
47 | TextView short_summary = (TextView) view.findViewById(R.id.short_summary);
48 | TextView received_time = (TextView) view.findViewById(R.id.received_time);
49 | icon.setImageResource("sms".equals(message.type) ? R.drawable.ic_message_white_48dp : R.drawable.ic_voicemail_white_48dp);
50 | caller.setText(message.caller);
51 | folder.setText(message.folder);
52 | if(message.folder.isEmpty())
53 | folder.setVisibility(View.GONE);
54 | short_summary.setText(message.short_summary);
55 | if(message.short_summary.isEmpty())
56 | short_summary.setVisibility(View.GONE);
57 | received_time.setText(message.receivedTime());
58 | int typeface = message.unread ? Typeface.BOLD : Typeface.NORMAL;
59 | caller.setTypeface(null, typeface);
60 | folder.setTypeface(null, typeface);
61 | short_summary.setTypeface(null, typeface);
62 | received_time.setTypeface(null, typeface);
63 | }
64 | return view;
65 | }
66 |
67 | @Override
68 | public int getCount() {
69 | return messages.size();
70 | }
71 |
72 | public Message get(int position) {
73 | return messages.get(position);
74 | }
75 |
76 | public void update(ArrayList messages) {
77 | this.messages = messages;
78 | notifyDataSetChanged();
79 | }
80 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/openvbx/adapters/UserAdapter.java:
--------------------------------------------------------------------------------
1 | package org.openvbx.adapters;
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 org.openvbx.models.User;
11 |
12 | import java.util.ArrayList;
13 |
14 | public class UserAdapter extends BaseAdapter {
15 |
16 | public ArrayList users;
17 | private LayoutInflater inflater;
18 |
19 | static class ViewHolder {
20 | TextView text;
21 | }
22 |
23 | public UserAdapter(Context context, ArrayList users) {
24 | this.users = users;
25 | inflater = LayoutInflater.from(context);
26 | }
27 |
28 | public int getCount() {
29 | return users.size();
30 | }
31 |
32 | public User get(int position){
33 | return users.get(position);
34 | }
35 |
36 | public void add(User user){
37 | users.add(user);
38 | }
39 |
40 | public String getItem(int position){
41 | return get(position).getName();
42 | }
43 |
44 | public long getItemId(int position) {
45 | return users.indexOf(get(position));
46 | }
47 |
48 | public int indexOf(int id) {
49 | for(int i = 0; i < users.size(); i++)
50 | if(id == users.get(i).id)
51 | return i;
52 | return -1;
53 | }
54 |
55 | public View getView(int position, View convertView, ViewGroup parent) {
56 | return createResource(position, convertView, parent, android.R.layout.simple_spinner_item);
57 | }
58 |
59 | public View getDropDownView(int position, View convertView, ViewGroup parent) {
60 | return createResource(position, convertView, parent, android.R.layout.simple_spinner_dropdown_item);
61 | }
62 |
63 | public View createResource(int position, View convertView, ViewGroup parent, int resource) {
64 | View v = convertView;
65 | ViewHolder vh;
66 | if (v == null) {
67 | v = inflater.inflate(resource, parent, false);
68 | vh = new ViewHolder();
69 | vh.text = (TextView) v.findViewById(android.R.id.text1);
70 | v.setTag(vh);
71 | }
72 | else
73 | vh = (ViewHolder) v.getTag();
74 | vh.text.setText(get(position).getName());
75 | return v;
76 | }
77 |
78 | public void update(ArrayList users) {
79 | this.users = users;
80 | notifyDataSetChanged();
81 | }
82 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/openvbx/models/Annotation.java:
--------------------------------------------------------------------------------
1 | package org.openvbx.models;
2 |
3 | import android.os.Parcel;
4 | import android.os.Parcelable;
5 |
6 | public class Annotation implements Parcelable {
7 |
8 | public int id;
9 | public String annotation_type = "noted";
10 | public int message_id;
11 | public int user_id;
12 | public String description = "";
13 | public String created;
14 | public int tenant_id;
15 | public String email;
16 | public String first_name = "";
17 | public String last_name = "";
18 |
19 | public String getName() {
20 | return first_name + " " + last_name;
21 | }
22 |
23 | protected Annotation(Parcel in) {
24 | id = in.readInt();
25 | annotation_type = in.readString();
26 | message_id = in.readInt();
27 | user_id = in.readInt();
28 | description = in.readString();
29 | created = in.readString();
30 | tenant_id = in.readInt();
31 | email = in.readString();
32 | first_name = in.readString();
33 | last_name = in.readString();
34 | }
35 |
36 | @Override
37 | public int describeContents() {
38 | return 0;
39 | }
40 |
41 | @Override
42 | public void writeToParcel(Parcel dest, int flags) {
43 | dest.writeInt(id);
44 | dest.writeString(annotation_type);
45 | dest.writeInt(message_id);
46 | dest.writeInt(user_id);
47 | dest.writeString(description);
48 | dest.writeString(created);
49 | dest.writeInt(tenant_id);
50 | dest.writeString(email);
51 | dest.writeString(first_name);
52 | dest.writeString(last_name);
53 | }
54 |
55 | @SuppressWarnings("unused")
56 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
57 | @Override
58 | public Annotation createFromParcel(Parcel in) {
59 | return new Annotation(in);
60 | }
61 |
62 | @Override
63 | public Annotation[] newArray(int size) {
64 | return new Annotation[size];
65 | }
66 | };
67 |
68 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/openvbx/models/CallerID.java:
--------------------------------------------------------------------------------
1 | package org.openvbx.models;
2 |
3 | import android.os.Parcel;
4 | import android.os.Parcelable;
5 |
6 | import com.google.gson.annotations.SerializedName;
7 |
8 | public class CallerID implements Parcelable {
9 |
10 | public int flow_id;
11 | public String id;
12 | public String name;
13 | public String phone;
14 | public String phone_number;
15 | public String url;
16 | public String method;
17 | public String smsUrl;
18 | public String smsMethod;
19 | @SerializedName("capabilities")
20 | public Capabilities capabilities = new Capabilities();
21 | public String voiceApplicationSid;
22 | public Boolean installed;
23 |
24 | public Boolean hasSms() {
25 | return capabilities != null && capabilities.sms;
26 | }
27 |
28 | protected CallerID(Parcel in) {
29 | flow_id = in.readInt();
30 | id = in.readString();
31 | name = in.readString();
32 | phone = in.readString();
33 | phone_number = in.readString();
34 | url = in.readString();
35 | method = in.readString();
36 | smsUrl = in.readString();
37 | smsMethod = in.readString();
38 | capabilities = (Capabilities) in.readValue(Capabilities.class.getClassLoader());
39 | voiceApplicationSid = in.readString();
40 | byte installedVal = in.readByte();
41 | installed = installedVal == 0x02 ? null : installedVal != 0x00;
42 | }
43 |
44 | @Override
45 | public int describeContents() {
46 | return 0;
47 | }
48 |
49 | @Override
50 | public void writeToParcel(Parcel dest, int flags) {
51 | dest.writeInt(flow_id);
52 | dest.writeString(id);
53 | dest.writeString(name);
54 | dest.writeString(phone);
55 | dest.writeString(phone_number);
56 | dest.writeString(url);
57 | dest.writeString(method);
58 | dest.writeString(smsUrl);
59 | dest.writeString(smsMethod);
60 | dest.writeValue(capabilities);
61 | dest.writeString(voiceApplicationSid);
62 | if (installed == null) {
63 | dest.writeByte((byte) (0x02));
64 | } else {
65 | dest.writeByte((byte) (installed ? 0x01 : 0x00));
66 | }
67 | }
68 |
69 | @SuppressWarnings("unused")
70 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
71 | @Override
72 | public CallerID createFromParcel(Parcel in) {
73 | return new CallerID(in);
74 | }
75 |
76 | @Override
77 | public CallerID[] newArray(int size) {
78 | return new CallerID[size];
79 | }
80 | };
81 |
82 | public static class Capabilities implements Parcelable {
83 |
84 | public Boolean voice = false;
85 | public Boolean sms = false;
86 | public Boolean mms = false;
87 |
88 | public Capabilities() {
89 | }
90 |
91 | protected Capabilities(Parcel in) {
92 | byte voiceVal = in.readByte();
93 | voice = voiceVal == 0x02 ? null : voiceVal != 0x00;
94 | byte smsVal = in.readByte();
95 | sms = smsVal == 0x02 ? null : smsVal != 0x00;
96 | byte mmsVal = in.readByte();
97 | mms = mmsVal == 0x02 ? null : mmsVal != 0x00;
98 | }
99 |
100 | @Override
101 | public int describeContents() {
102 | return 0;
103 | }
104 |
105 | @Override
106 | public void writeToParcel(Parcel dest, int flags) {
107 | if (voice == null) {
108 | dest.writeByte((byte) (0x02));
109 | } else {
110 | dest.writeByte((byte) (voice ? 0x01 : 0x00));
111 | }
112 | if (sms == null) {
113 | dest.writeByte((byte) (0x02));
114 | } else {
115 | dest.writeByte((byte) (sms ? 0x01 : 0x00));
116 | }
117 | if (mms == null) {
118 | dest.writeByte((byte) (0x02));
119 | } else {
120 | dest.writeByte((byte) (mms ? 0x01 : 0x00));
121 | }
122 | }
123 |
124 | @SuppressWarnings("unused")
125 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
126 | @Override
127 | public Capabilities createFromParcel(Parcel in) {
128 | return new Capabilities(in);
129 | }
130 |
131 | @Override
132 | public Capabilities[] newArray(int size) {
133 | return new Capabilities[size];
134 | }
135 | };
136 |
137 | }
138 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/openvbx/models/ClientResult.java:
--------------------------------------------------------------------------------
1 | package org.openvbx.models;
2 |
3 | public class ClientResult {
4 |
5 | public Boolean error = false;
6 | public String message = null;
7 | public String version = null;
8 | public String theme = null;
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/app/src/main/java/org/openvbx/models/Folder.java:
--------------------------------------------------------------------------------
1 | package org.openvbx.models;
2 |
3 | import android.os.Parcel;
4 | import android.os.Parcelable;
5 |
6 | import com.google.gson.annotations.SerializedName;
7 |
8 | import java.util.ArrayList;
9 |
10 | public class Folder implements Parcelable {
11 |
12 | public int id = -1;
13 | public String name = null;
14 | public String type = null;
15 | public int archived = 0;
16 | @SerializedName("new")
17 | public int unread = 0;
18 | public int read = 0;
19 | public int total = 0;
20 | @SerializedName("messages")
21 | public Messages messages = new Messages();
22 |
23 | public Folder() {
24 | }
25 |
26 | protected Folder(Parcel in) {
27 | id = in.readInt();
28 | name = in.readString();
29 | type = in.readString();
30 | archived = in.readInt();
31 | unread = in.readInt();
32 | read = in.readInt();
33 | total = in.readInt();
34 | messages = (Messages) in.readValue(Messages.class.getClassLoader());
35 | }
36 |
37 | @Override
38 | public int describeContents() {
39 | return 0;
40 | }
41 |
42 | @Override
43 | public void writeToParcel(Parcel dest, int flags) {
44 | dest.writeInt(id);
45 | dest.writeString(name);
46 | dest.writeString(type);
47 | dest.writeInt(archived);
48 | dest.writeInt(unread);
49 | dest.writeInt(read);
50 | dest.writeInt(total);
51 | dest.writeValue(messages);
52 | }
53 |
54 | @SuppressWarnings("unused")
55 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
56 | @Override
57 | public Folder createFromParcel(Parcel in) {
58 | return new Folder(in);
59 | }
60 |
61 | @Override
62 | public Folder[] newArray(int size) {
63 | return new Folder[size];
64 | }
65 | };
66 |
67 | public static class Messages implements Parcelable {
68 |
69 | @SerializedName("items")
70 | public ArrayList items = new ArrayList<>();
71 | public int total = 0;
72 | public Boolean offset = false;
73 | public int max = 20;
74 |
75 | public Messages() {
76 | }
77 |
78 | protected Messages(Parcel in) {
79 | if (in.readByte() == 0x01) {
80 | items = new ArrayList<>();
81 | in.readList(items, Message.class.getClassLoader());
82 | } else {
83 | items = null;
84 | }
85 | total = in.readInt();
86 | byte offsetVal = in.readByte();
87 | offset = offsetVal == 0x02 ? null : offsetVal != 0x00;
88 | max = in.readInt();
89 | }
90 |
91 | @Override
92 | public int describeContents() {
93 | return 0;
94 | }
95 |
96 | @Override
97 | public void writeToParcel(Parcel dest, int flags) {
98 | if (items == null) {
99 | dest.writeByte((byte) (0x00));
100 | } else {
101 | dest.writeByte((byte) (0x01));
102 | dest.writeList(items);
103 | }
104 | dest.writeInt(total);
105 | if (offset == null) {
106 | dest.writeByte((byte) (0x02));
107 | } else {
108 | dest.writeByte((byte) (offset ? 0x01 : 0x00));
109 | }
110 | dest.writeInt(max);
111 | }
112 |
113 | @SuppressWarnings("unused")
114 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
115 | @Override
116 | public Messages createFromParcel(Parcel in) {
117 | return new Messages(in);
118 | }
119 |
120 | @Override
121 | public Messages[] newArray(int size) {
122 | return new Messages[size];
123 | }
124 | };
125 |
126 | }
127 |
128 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/openvbx/models/Inbox.java:
--------------------------------------------------------------------------------
1 | package org.openvbx.models;
2 |
3 | import android.os.Parcel;
4 | import android.os.Parcelable;
5 |
6 | import com.google.gson.annotations.SerializedName;
7 |
8 | import java.util.ArrayList;
9 |
10 | public class Inbox implements Parcelable {
11 |
12 | public int max = 20;
13 | public Boolean offset = false;
14 | public int total = 0;
15 | @SerializedName("folders")
16 | public ArrayList folders = new ArrayList<>();
17 |
18 | protected Inbox(Parcel in) {
19 | max = in.readInt();
20 | byte offsetVal = in.readByte();
21 | offset = offsetVal == 0x02 ? null : offsetVal != 0x00;
22 | total = in.readInt();
23 | if (in.readByte() == 0x01) {
24 | folders = new ArrayList<>();
25 | in.readList(folders, Folder.class.getClassLoader());
26 | } else {
27 | folders = null;
28 | }
29 | }
30 |
31 | @Override
32 | public int describeContents() {
33 | return 0;
34 | }
35 |
36 | @Override
37 | public void writeToParcel(Parcel dest, int flags) {
38 | dest.writeInt(max);
39 | if (offset == null) {
40 | dest.writeByte((byte) (0x02));
41 | } else {
42 | dest.writeByte((byte) (offset ? 0x01 : 0x00));
43 | }
44 | dest.writeInt(total);
45 | if (folders == null) {
46 | dest.writeByte((byte) (0x00));
47 | } else {
48 | dest.writeByte((byte) (0x01));
49 | dest.writeList(folders);
50 | }
51 | }
52 |
53 | @SuppressWarnings("unused")
54 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
55 | @Override
56 | public Inbox createFromParcel(Parcel in) {
57 | return new Inbox(in);
58 | }
59 |
60 | @Override
61 | public Inbox[] newArray(int size) {
62 | return new Inbox[size];
63 | }
64 | };
65 |
66 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/openvbx/models/Message.java:
--------------------------------------------------------------------------------
1 | package org.openvbx.models;
2 |
3 |
4 | import android.os.Parcel;
5 | import android.os.Parcelable;
6 |
7 | import com.google.gson.annotations.SerializedName;
8 |
9 | import java.text.SimpleDateFormat;
10 | import java.util.ArrayList;
11 | import java.util.Locale;
12 |
13 | public class Message implements Parcelable {
14 |
15 | public int id;
16 | public Boolean selected_folder = false;
17 | public Boolean selected_folder_id = false;
18 | public String status = "read";
19 | public String folder = "";
20 | public int folder_id;
21 | public String summary = "";
22 | public String short_summary = "";
23 | public int assigned = -1;
24 | public String type = "";
25 | public int assigned_user;
26 | public String ticket_status;
27 | public Boolean archived = false;
28 | public Boolean unread = false;
29 | public String recording_url;
30 | public String recording_length;
31 | public String received_time;
32 | public String last_updated;
33 | public String called;
34 | public String caller;
35 | public String original_called;
36 | public String original_caller;
37 | public String owner_type;
38 | public String message_type;
39 | @SerializedName("active_users")
40 | public ArrayList active_users = new ArrayList<>();
41 | @SerializedName("annotations")
42 | public Annotations annotations = new Annotations();
43 |
44 | public String receivedTime() {
45 | try {
46 | return new SimpleDateFormat("M/d/yy h:mm a", Locale.getDefault()).format(new SimpleDateFormat("yyyy-MMM-dd'T'HH:mm:ssZ", Locale.getDefault()).parse(received_time));
47 | } catch (Exception e) {
48 | e.printStackTrace();
49 | return null;
50 | }
51 | }
52 |
53 | public Boolean isVoice() {
54 | return type != null && type.equals("voice");
55 | }
56 |
57 | public Boolean isSms() {
58 | return type != null && type.equals("sms");
59 | }
60 |
61 | protected Message(Parcel in) {
62 | id = in.readInt();
63 | byte selected_folderVal = in.readByte();
64 | selected_folder = selected_folderVal == 0x02 ? null : selected_folderVal != 0x00;
65 | byte selected_folder_idVal = in.readByte();
66 | selected_folder_id = selected_folder_idVal == 0x02 ? null : selected_folder_idVal != 0x00;
67 | status = in.readString();
68 | folder = in.readString();
69 | folder_id = in.readInt();
70 | summary = in.readString();
71 | short_summary = in.readString();
72 | assigned = in.readInt();
73 | type = in.readString();
74 | assigned_user = in.readInt();
75 | ticket_status = in.readString();
76 | byte archivedVal = in.readByte();
77 | archived = archivedVal == 0x02 ? null : archivedVal != 0x00;
78 | byte unreadVal = in.readByte();
79 | unread = unreadVal == 0x02 ? null : unreadVal != 0x00;
80 | recording_url = in.readString();
81 | recording_length = in.readString();
82 | received_time = in.readString();
83 | last_updated = in.readString();
84 | called = in.readString();
85 | caller = in.readString();
86 | original_called = in.readString();
87 | original_caller = in.readString();
88 | owner_type = in.readString();
89 | message_type = in.readString();
90 | if (in.readByte() == 0x01) {
91 | active_users = new ArrayList<>();
92 | in.readList(active_users, User.class.getClassLoader());
93 | } else {
94 | active_users = null;
95 | }
96 | annotations = (Annotations) in.readValue(Annotations.class.getClassLoader());
97 | }
98 |
99 | @Override
100 | public int describeContents() {
101 | return 0;
102 | }
103 |
104 | @Override
105 | public void writeToParcel(Parcel dest, int flags) {
106 | dest.writeInt(id);
107 | if (selected_folder == null) {
108 | dest.writeByte((byte) (0x02));
109 | } else {
110 | dest.writeByte((byte) (selected_folder ? 0x01 : 0x00));
111 | }
112 | if (selected_folder_id == null) {
113 | dest.writeByte((byte) (0x02));
114 | } else {
115 | dest.writeByte((byte) (selected_folder_id ? 0x01 : 0x00));
116 | }
117 | dest.writeString(status);
118 | dest.writeString(folder);
119 | dest.writeInt(folder_id);
120 | dest.writeString(summary);
121 | dest.writeString(short_summary);
122 | dest.writeInt(assigned);
123 | dest.writeString(type);
124 | dest.writeInt(assigned_user);
125 | dest.writeString(ticket_status);
126 | if (archived == null) {
127 | dest.writeByte((byte) (0x02));
128 | } else {
129 | dest.writeByte((byte) (archived ? 0x01 : 0x00));
130 | }
131 | if (unread == null) {
132 | dest.writeByte((byte) (0x02));
133 | } else {
134 | dest.writeByte((byte) (unread ? 0x01 : 0x00));
135 | }
136 | dest.writeString(recording_url);
137 | dest.writeString(recording_length);
138 | dest.writeString(received_time);
139 | dest.writeString(last_updated);
140 | dest.writeString(called);
141 | dest.writeString(caller);
142 | dest.writeString(original_called);
143 | dest.writeString(original_caller);
144 | dest.writeString(owner_type);
145 | dest.writeString(message_type);
146 | if (active_users == null) {
147 | dest.writeByte((byte) (0x00));
148 | } else {
149 | dest.writeByte((byte) (0x01));
150 | dest.writeList(active_users);
151 | }
152 | dest.writeValue(annotations);
153 | }
154 |
155 | @SuppressWarnings("unused")
156 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
157 | @Override
158 | public Message createFromParcel(Parcel in) {
159 | return new Message(in);
160 | }
161 |
162 | @Override
163 | public Message[] newArray(int size) {
164 | return new Message[size];
165 | }
166 | };
167 |
168 | public static class Annotations implements Parcelable {
169 |
170 | @SerializedName("items")
171 | public ArrayList items = new ArrayList<>();
172 | public int max = 0;
173 | public int total = 0;
174 |
175 | public Annotations() {
176 | }
177 |
178 | protected Annotations(Parcel in) {
179 | if (in.readByte() == 0x01) {
180 | items = new ArrayList<>();
181 | in.readList(items, Annotation.class.getClassLoader());
182 | } else {
183 | items = null;
184 | }
185 | max = in.readInt();
186 | total = in.readInt();
187 | }
188 |
189 | @Override
190 | public int describeContents() {
191 | return 0;
192 | }
193 |
194 | @Override
195 | public void writeToParcel(Parcel dest, int flags) {
196 | if (items == null) {
197 | dest.writeByte((byte) (0x00));
198 | } else {
199 | dest.writeByte((byte) (0x01));
200 | dest.writeList(items);
201 | }
202 | dest.writeInt(max);
203 | dest.writeInt(total);
204 | }
205 |
206 | @SuppressWarnings("unused")
207 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
208 | @Override
209 | public Annotations createFromParcel(Parcel in) {
210 | return new Annotations(in);
211 | }
212 |
213 | @Override
214 | public Annotations[] newArray(int size) {
215 | return new Annotations[size];
216 | }
217 | };
218 |
219 | }
220 |
221 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/openvbx/models/MessageResult.java:
--------------------------------------------------------------------------------
1 | package org.openvbx.models;
2 |
3 | public class MessageResult {
4 |
5 | public Boolean error;
6 | public String message = "";
7 |
8 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/openvbx/models/User.java:
--------------------------------------------------------------------------------
1 | package org.openvbx.models;
2 |
3 | import android.os.Parcel;
4 | import android.os.Parcelable;
5 |
6 | public class User implements Parcelable {
7 |
8 | public int id;
9 | public String first_name;
10 | public String last_name;
11 | public String email;
12 |
13 | public String getName() {
14 | return first_name + " " + last_name;
15 | }
16 |
17 | public User(int id, String first_name, String last_name) {
18 | this.id = id;
19 | this.first_name = first_name;
20 | this.last_name = last_name;
21 | }
22 |
23 | protected User(Parcel in) {
24 | id = in.readInt();
25 | first_name = in.readString();
26 | last_name = in.readString();
27 | email = in.readString();
28 | }
29 |
30 | @Override
31 | public int describeContents() {
32 | return 0;
33 | }
34 |
35 | @Override
36 | public void writeToParcel(Parcel dest, int flags) {
37 | dest.writeInt(id);
38 | dest.writeString(first_name);
39 | dest.writeString(last_name);
40 | dest.writeString(email);
41 | }
42 |
43 | @SuppressWarnings("unused")
44 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
45 | @Override
46 | public User createFromParcel(Parcel in) {
47 | return new User(in);
48 | }
49 |
50 | @Override
51 | public User[] newArray(int size) {
52 | return new User[size];
53 | }
54 | };
55 |
56 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_archive_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-hdpi/ic_archive_white_36dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_call_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-hdpi/ic_call_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_folder_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-hdpi/ic_folder_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_inbox_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-hdpi/ic_inbox_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_message_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-hdpi/ic_message_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_pause_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-hdpi/ic_pause_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_play_arrow_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-hdpi/ic_play_arrow_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_reply_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-hdpi/ic_reply_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_speaker_notes_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-hdpi/ic_speaker_notes_white_36dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_textsms_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-hdpi/ic_textsms_white_36dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_voicemail_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-hdpi/ic_voicemail_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_archive_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-mdpi/ic_archive_white_36dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_call_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-mdpi/ic_call_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_folder_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-mdpi/ic_folder_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_inbox_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-mdpi/ic_inbox_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_message_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-mdpi/ic_message_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_pause_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-mdpi/ic_pause_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_play_arrow_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-mdpi/ic_play_arrow_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_reply_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-mdpi/ic_reply_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_speaker_notes_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-mdpi/ic_speaker_notes_white_36dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_textsms_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-mdpi/ic_textsms_white_36dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_voicemail_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-mdpi/ic_voicemail_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_archive_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xhdpi/ic_archive_white_36dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_call_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xhdpi/ic_call_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_folder_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xhdpi/ic_folder_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_inbox_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xhdpi/ic_inbox_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_message_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xhdpi/ic_message_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_pause_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xhdpi/ic_pause_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_play_arrow_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xhdpi/ic_play_arrow_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_reply_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xhdpi/ic_reply_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_speaker_notes_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xhdpi/ic_speaker_notes_white_36dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_textsms_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xhdpi/ic_textsms_white_36dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_voicemail_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xhdpi/ic_voicemail_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_archive_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xxhdpi/ic_archive_white_36dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_call_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xxhdpi/ic_call_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_folder_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xxhdpi/ic_folder_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_inbox_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xxhdpi/ic_inbox_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_message_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xxhdpi/ic_message_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_pause_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xxhdpi/ic_pause_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_play_arrow_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xxhdpi/ic_play_arrow_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_reply_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xxhdpi/ic_reply_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_speaker_notes_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xxhdpi/ic_speaker_notes_white_36dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_textsms_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xxhdpi/ic_textsms_white_36dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_voicemail_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xxhdpi/ic_voicemail_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_archive_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xxxhdpi/ic_archive_white_36dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_call_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xxxhdpi/ic_call_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_folder_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xxxhdpi/ic_folder_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_inbox_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xxxhdpi/ic_inbox_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_message_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xxxhdpi/ic_message_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_pause_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xxxhdpi/ic_pause_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_play_arrow_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xxxhdpi/ic_play_arrow_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_reply_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xxxhdpi/ic_reply_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_speaker_notes_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xxxhdpi/ic_speaker_notes_white_36dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_textsms_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xxxhdpi/ic_textsms_white_36dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_voicemail_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable-xxxhdpi/ic_voicemail_white_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/drawer_header.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/drawable/logo.png
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_annotation.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
16 |
23 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_call.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
17 |
22 |
30 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_inbox.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
14 |
15 |
18 |
19 |
32 |
33 |
34 |
43 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_login.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
12 |
21 |
26 |
33 |
42 |
48 |
55 |
56 |
62 |
69 |
77 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_message.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
20 |
24 |
25 |
26 |
29 |
33 |
38 |
44 |
49 |
54 |
60 |
66 |
73 |
80 |
81 |
88 |
95 |
96 |
101 |
102 |
115 |
116 |
117 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_sms.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
16 |
21 |
29 |
37 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/dialog_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
14 |
23 |
28 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/drawer_header.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
16 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_annotation_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
13 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_inbox_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
14 |
17 |
23 |
29 |
35 |
41 |
42 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_refreshable_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
13 |
17 |
18 |
19 |
23 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_toolbar.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_drawer.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
11 |
14 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_inbox.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_message.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
11 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #607D8B
4 | #455A64
5 | #CFD8DC
6 | #9CBD41
7 | #212121
8 | #727272
9 | #FFFFFF
10 | #B6B6B6
11 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | OpenVBX
4 | Login
5 | Settings
6 | Messages
7 | Archive
8 | Reply
9 | New SMS
10 | New Call
11 | Details
12 | Add Note
13 | From
14 | Status
15 | Assigned to
16 | To
17 | Message
18 | Send
19 | Next
20 | URL to your OpenVBX installation
21 | https://
22 | Connect to your OpenVBX
23 | Save
24 | When you place phone calls using OpenVBX, you\'ll be called at this number to complete the connection.
25 | Phone Number
26 | Password
27 | E-Mail
28 | Call
29 | Sign Out
30 | Folders
31 | Open
32 | Close
33 | Error
34 | OK
35 | Your email address or password is invalid.
36 | The URL provided doesn\'t seem to point to an OpenVBX installation.
37 | Message sent
38 | Message archived
39 | Calling...
40 | Saving...
41 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
15 |
23 |
26 |
30 |
37 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | buildscript {
3 | repositories {
4 | jcenter()
5 | }
6 | dependencies {
7 | classpath 'com.android.tools.build:gradle:2.1.0'
8 | }
9 | }
10 |
11 | allprojects {
12 | repositories {
13 | jcenter()
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chadsmith/OpenVBX-Android/53aafb87aa3d404ecd98f37809562079aea8ddf0/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sat Apr 30 17:45:50 CDT 2016
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------