From 489901dca1f1450a733cd025fe2ec55978c21875 Mon Sep 17 00:00:00 2001 From: "marcin.jedynski" Date: Sun, 6 Jan 2019 20:56:01 +0100 Subject: [PATCH 01/43] added timepicker, email validation, new UI --- app/src/main/AndroidManifest.xml | 7 +- .../findmytutor/activity/LoginActivity.java | 3 +- .../findmytutor/activity/SharingFragment.java | 57 +++-- .../findmytutor/activity/StartupActivity.java | 2 + .../activity/TimePickerFragment.java | 46 ++++ .../wmi/findmytutor/activity/TutorTab.java | 89 +++++++- .../adapters/DutyHoursAdapter.java | 30 ++- app/src/main/res/layout/content_tutor_tab.xml | 214 ++++-------------- .../res/layout/content_tutor_tab_layout.xml | 199 ++++++++++++++++ app/src/main/res/layout/duty_hour_row.xml | 8 +- app/src/main/res/menu/menu_profile.xml | 11 + app/src/main/res/values/strings.xml | 97 +++++++- 12 files changed, 548 insertions(+), 215 deletions(-) create mode 100644 app/src/main/java/com/uam/wmi/findmytutor/activity/TimePickerFragment.java create mode 100644 app/src/main/res/layout/content_tutor_tab_layout.xml create mode 100644 app/src/main/res/menu/menu_profile.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d209b5a..2e32ae2 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -38,11 +38,11 @@ + android:screenOrientation="portrait" + android:windowSoftInputMode="adjustPan" /> + + \ No newline at end of file diff --git a/app/src/main/java/com/uam/wmi/findmytutor/activity/LoginActivity.java b/app/src/main/java/com/uam/wmi/findmytutor/activity/LoginActivity.java index fda30bf..caf7eae 100644 --- a/app/src/main/java/com/uam/wmi/findmytutor/activity/LoginActivity.java +++ b/app/src/main/java/com/uam/wmi/findmytutor/activity/LoginActivity.java @@ -39,7 +39,8 @@ import io.reactivex.disposables.CompositeDisposable; import io.reactivex.schedulers.Schedulers; import okhttp3.ResponseBody; -public class LoginActivity extends AppCompatActivity { +public class +LoginActivity extends AppCompatActivity { private AutoCompleteTextView mLoginNameView; private EditText mPasswordView; diff --git a/app/src/main/java/com/uam/wmi/findmytutor/activity/SharingFragment.java b/app/src/main/java/com/uam/wmi/findmytutor/activity/SharingFragment.java index 8882bfd..3734389 100644 --- a/app/src/main/java/com/uam/wmi/findmytutor/activity/SharingFragment.java +++ b/app/src/main/java/com/uam/wmi/findmytutor/activity/SharingFragment.java @@ -3,6 +3,7 @@ package com.uam.wmi.findmytutor.activity; import android.annotation.SuppressLint; import android.app.AlertDialog; import android.app.FragmentTransaction; +import android.app.TimePickerDialog; import android.content.DialogInterface; import android.content.SharedPreferences; import android.os.Bundle; @@ -16,6 +17,7 @@ import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.TimePicker; import android.widget.Toast; import com.annimon.stream.IntPair; @@ -123,28 +125,6 @@ public class SharingFragment extends PreferenceFragment implements SharedPrefere String[] stringnames = predefinedLocationsNames.toArray(new String[0]); predefinedLocationsList = new ArrayList<>(Arrays.asList(stringnames)); - if (!PrefUtils.getLocationLevel(getApplicationContext()).equals("manual")) { - preferenceCategory.removePreference(manualLocationList); - preferenceCategory.removePreference(removeManualLocation); - preferenceCategory.removePreference(manualLocationButton); - }else{ - if(predefinedCoordsList.isEmpty()){ - locationSharing.setEnabled(false); - locationSharing.setChecked(false); - PrefUtils.disableSharing(getApplicationContext()); - ((MapActivity) getActivity()).handleBackgroundTaskLifeCycle(); - removeManualLocation.setEnabled(false); - manualLocationList.setEnabled(false); - manualLocationList.setSummary(""); - }else{ - manualLocationList.setEnabled(true); - manualLocationList.setSummary(PrefUtils.getCurrentManualLocationName(getApplicationContext())); - removeManualLocation.setEnabled(true); - locationSharing.setEnabled(true); - - - } - } List activesId = Stream.of(coords).indexed() .filter(v -> v.getSecond().getPredefinedCoordinateId().equals(currentCoordId)).map(IntPair::getFirst).toList(); @@ -199,10 +179,31 @@ public class SharingFragment extends PreferenceFragment implements SharedPrefere statusMapping.put(0, "available"); statusMapping.put(1, "consultation"); statusMapping.put(2, "busy"); - + if (!PrefUtils.getLocationLevel(getApplicationContext()).equals("manual")) { + preferenceCategory.removePreference(manualLocationList); + preferenceCategory.removePreference(removeManualLocation); + preferenceCategory.removePreference(manualLocationButton); + }else{ + if(predefinedCoordsList.isEmpty()){ + locationSharing.setEnabled(false); + locationSharing.setChecked(false); + PrefUtils.disableSharing(getApplicationContext()); + ((MapActivity) getActivity()).handleBackgroundTaskLifeCycle(); + removeManualLocation.setEnabled(false); + manualLocationList.setEnabled(false); + manualLocationList.setSummary(""); + }else{ + manualLocationList.setEnabled(true); + manualLocationList.setSummary(PrefUtils.getCurrentManualLocationName(getApplicationContext())); + removeManualLocation.setEnabled(true); + locationSharing.setEnabled(true); + } + } statusList.setSummary(PrefUtils.getUserStatus(getApplicationContext())); manualLocationList.setSummary(PrefUtils.getCurrentManualLocationName(getApplicationContext())); + + /** Main sharing switch**/ locationSharing.setOnPreferenceChangeListener((buttonView, newValue) -> { PrefUtils.storeEnableSharingLocalization(getApplicationContext(), (Boolean) newValue); @@ -282,7 +283,17 @@ public class SharingFragment extends PreferenceFragment implements SharedPrefere lp.setSummary(entries[Integer.parseInt((String) newValue)]); return true; }); + statusList.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + if(statusesArray.length == 0) + { + builder.setTitle("nie ma wody na pustyni"); + } + return true; + } + }); /** Custom status edittext change listener **/ manualStatus.setOnPreferenceChangeListener((preference, newValue) -> { diff --git a/app/src/main/java/com/uam/wmi/findmytutor/activity/StartupActivity.java b/app/src/main/java/com/uam/wmi/findmytutor/activity/StartupActivity.java index 9f6e086..efcb3c9 100644 --- a/app/src/main/java/com/uam/wmi/findmytutor/activity/StartupActivity.java +++ b/app/src/main/java/com/uam/wmi/findmytutor/activity/StartupActivity.java @@ -7,6 +7,7 @@ import android.content.res.Resources; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.DisplayMetrics; +import android.widget.ScrollView; import android.widget.Toast; @@ -30,6 +31,7 @@ public class StartupActivity extends AppCompatActivity { finish(); } else { Intent loginIntent = new Intent(this, LoginActivity.class); +// Intent loginIntent = new Intent(this, ScrollingActivity.class); startActivityForResult(loginIntent, AUTHENTICATION_REQUEST_CODE); } diff --git a/app/src/main/java/com/uam/wmi/findmytutor/activity/TimePickerFragment.java b/app/src/main/java/com/uam/wmi/findmytutor/activity/TimePickerFragment.java new file mode 100644 index 0000000..dcc2580 --- /dev/null +++ b/app/src/main/java/com/uam/wmi/findmytutor/activity/TimePickerFragment.java @@ -0,0 +1,46 @@ +package com.uam.wmi.findmytutor.activity; +import android.app.Dialog; +import android.app.DialogFragment; +import android.app.TimePickerDialog; +import android.os.Bundle; +import android.text.format.DateFormat; +import android.widget.TextView; +import android.widget.TimePicker; + +import com.uam.wmi.findmytutor.model.DutyHourViewModel; + +import java.util.Calendar; + +public class TimePickerFragment extends DialogFragment + implements TimePickerDialog.OnTimeSetListener { + private TextView textView; + private String field; + private DutyHourViewModel duty; + public TimePickerFragment(TextView view, DutyHourViewModel duty, String field){ + this.textView = view; + this.duty=duty; + this.field=field; + } + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + // Use the current time as the default values for the picker + final Calendar c = Calendar.getInstance(); + int hour = c.get(Calendar.HOUR_OF_DAY); + int minute = c.get(Calendar.MINUTE); + + // Create a new instance of TimePickerDialog and return it + return new TimePickerDialog(getActivity(), this, hour, minute, + DateFormat.is24HourFormat(getActivity())); + } + + public void onTimeSet(TimePicker view, int hourOfDay, int minute) { + String time = String.format("%d:%02d",hourOfDay,minute); + textView.setText(time); + if(field.equals("start")){ + duty.setStart(time); + }else{ + duty.setEnd(time); + } + // Do something with the time chosen by the user + } +} diff --git a/app/src/main/java/com/uam/wmi/findmytutor/activity/TutorTab.java b/app/src/main/java/com/uam/wmi/findmytutor/activity/TutorTab.java index 575ff5d..5e9adac 100644 --- a/app/src/main/java/com/uam/wmi/findmytutor/activity/TutorTab.java +++ b/app/src/main/java/com/uam/wmi/findmytutor/activity/TutorTab.java @@ -1,14 +1,22 @@ package com.uam.wmi.findmytutor.activity; +import android.graphics.drawable.ColorDrawable; import android.os.Bundle; import android.support.design.widget.TextInputEditText; import android.support.design.widget.TextInputLayout; +import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; import android.util.Log; +import android.view.Gravity; +import android.view.Menu; +import android.view.MenuItem; import android.view.View; import android.widget.Button; +import android.widget.LinearLayout; +import android.widget.PopupWindow; import android.widget.TextView; import android.widget.Toast; @@ -28,6 +36,8 @@ import com.uam.wmi.findmytutor.utils.RestApiHelper; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import butterknife.ButterKnife; import io.reactivex.android.schedulers.AndroidSchedulers; @@ -59,12 +69,34 @@ public class TutorTab extends AppCompatActivity { private DutyHoursAdapter dutyHoursAdapter; private RecyclerView.LayoutManager dutyHoursLayoutManager; private TutorTabViewModel newTab; + public boolean isEmailValid(String email) + { + String regExpn = + "^(([\\w-]+\\.)+[\\w-]+|([a-zA-Z]{1}|[\\w-]{2,}))@" + +"((([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\\.([0-1]?" + +"[0-9]{1,2}|25[0-5]|2[0-4][0-9])\\." + +"([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\\.([0-1]?" + +"[0-9]{1,2}|25[0-5]|2[0-4][0-9])){1}|" + +"([a-zA-Z]+[\\w-]+\\.)+[a-zA-Z]{2,4})$"; + CharSequence inputStr = email; + + Pattern pattern = Pattern.compile(regExpn,Pattern.CASE_INSENSITIVE); + Matcher matcher = pattern.matcher(inputStr); + + if(matcher.matches()) + return true; + else + return false; + } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); setContentView(R.layout.content_tutor_tab); + Toolbar toolbar = findViewById(R.id.toolbar); + toolbar.setTitle(getString(R.string.profile_activity_title)); + setSupportActionBar(toolbar); ButterKnife.bind(this); userName = findViewById(R.id.userName); @@ -86,7 +118,7 @@ public class TutorTab extends AppCompatActivity { getTutorTab(); - findViewById(R.id.contentTutorTabInfoImageButton).setOnClickListener(v-> InfoHelperUtils.infoPopUp(v,R.layout.info_popup_tutor_tab)); +// findViewById(R.id.contentTutorTabInfoImageButton).setOnClickListener(v-> InfoHelperUtils.infoPopUp(v,R.layout.info_popup_tutor_tab)); userName.setText(String.format("%s %s", PrefUtils.getUserFirstName(getApplicationContext()), PrefUtils.getUserLastName(getApplicationContext()))); @@ -112,6 +144,34 @@ public class TutorTab extends AppCompatActivity { scrapButton.setOnClickListener(view -> scrapTutorTab()); } + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.menu_profile, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + + if (item.getItemId()==R.id.action_profile_info_popup){ + int layoutID = R.layout.info_popup_tutor_tab; + + View popupView = getLayoutInflater().inflate(layoutID,null); + + PopupWindow popupWindow = new PopupWindow(popupView, + LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); + // If the PopupWindow should be focusable + popupWindow.setFocusable(true); + // If you need the PopupWindow to dismiss when when touched outside + popupWindow.setBackgroundDrawable(new ColorDrawable()); + // Get the View's(the one that was clicked in the Fragment) location + View anchorView= getWindow().getDecorView().findViewById(android.R.id.content); + popupWindow.showAtLocation(anchorView,Gravity.TOP|Gravity.END, 0, 0); + } + + return super.onOptionsItemSelected(item); + } + private void getTutorTab(){ disposable.add( tutorTabService.apiUsersTutorTabByTutorIdGet(PrefUtils.getUserId(getApplicationContext())) @@ -123,7 +183,7 @@ public class TutorTab extends AppCompatActivity { dutyHourList = tutorTabViewModel.getDutyHours(); if(dutyHourList != null){ - dutyHoursAdapter = new DutyHoursAdapter(getApplicationContext(),dutyHourList); + dutyHoursAdapter = new DutyHoursAdapter(getApplicationContext(),dutyHourList, getFragmentManager()); dutyHoursRecycller.setAdapter(dutyHoursAdapter); addDutyButton.setOnClickListener(v -> addEmptyDuty(dutyHoursAdapter)); } @@ -144,7 +204,7 @@ public class TutorTab extends AppCompatActivity { if( code == 404){ ifTutorTabExists = false; - dutyHoursAdapter = new DutyHoursAdapter(getApplicationContext(),new ArrayList()); + dutyHoursAdapter = new DutyHoursAdapter(getApplicationContext(),new ArrayList(), getFragmentManager()); dutyHoursRecycller.setAdapter(dutyHoursAdapter); addDutyButton.setOnClickListener(v -> addEmptyDuty(dutyHoursAdapter)); } @@ -161,17 +221,22 @@ public class TutorTab extends AppCompatActivity { private void setUpSaveListener(Button button) { button.setOnClickListener(view -> { - newTab = new TutorTabViewModel(PrefUtils.getUserId(getApplicationContext()), - userRoom.getText().toString(), - userEmail.getText().toString(), - userNote.getText().toString(), - dutyHoursAdapter.getDutyList()); - if(ifTutorTabExists){ - putUserTab(newTab); + if( isEmailValid(userEmail.getText().toString())){ + newTab = new TutorTabViewModel(PrefUtils.getUserId(getApplicationContext()), + userRoom.getText().toString(), + userEmail.getText().toString(), + userNote.getText().toString(), + dutyHoursAdapter.getDutyList()); + if(ifTutorTabExists){ + putUserTab(newTab); + }else{ + postUserTab(newTab); + ifTutorTabExists=true; + } }else{ - postUserTab(newTab); - ifTutorTabExists=true; + userEmail.setError(getString(R.string.error_invalid_email)); } + }); } diff --git a/app/src/main/java/com/uam/wmi/findmytutor/adapters/DutyHoursAdapter.java b/app/src/main/java/com/uam/wmi/findmytutor/adapters/DutyHoursAdapter.java index eaa95f1..c0f23b1 100644 --- a/app/src/main/java/com/uam/wmi/findmytutor/adapters/DutyHoursAdapter.java +++ b/app/src/main/java/com/uam/wmi/findmytutor/adapters/DutyHoursAdapter.java @@ -1,6 +1,9 @@ package com.uam.wmi.findmytutor.adapters; +import android.app.DialogFragment; +import android.app.FragmentManager; import android.content.Context; +import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v7.widget.RecyclerView; import android.text.Editable; @@ -14,6 +17,7 @@ import android.widget.TextView; import com.annimon.stream.Collectors; import com.annimon.stream.Stream; import com.uam.wmi.findmytutor.R; +import com.uam.wmi.findmytutor.activity.TimePickerFragment; import com.uam.wmi.findmytutor.model.DutyHourViewModel; import java.util.ArrayList; import java.util.List; @@ -24,10 +28,12 @@ import butterknife.ButterKnife; public class DutyHoursAdapter extends RecyclerView.Adapter { private Context context; private List hours; + private FragmentManager fragmentManager; - public DutyHoursAdapter(Context context, List hours) { + public DutyHoursAdapter(Context context, List hours, FragmentManager fragmentManager) { this.context = context; - this.hours = new ArrayList<>(hours); + this.hours = new ArrayList(hours); + this.fragmentManager = fragmentManager; } @@ -75,7 +81,7 @@ public class DutyHoursAdapter extends RecyclerView.Adapter - - - + android:layout_height="match_parent" + android:fitsSystemWindows="true" + android:id="@+id/activity_whitelist_container" + tools:context=".activity.WhiteList"> - - + android:layout_height="132dp" + android:fitsSystemWindows="true" + android:theme="@style/AppTheme.AppBarOverlay"> - - -