Commit 2c3e0998 authored by Nihal Singh's avatar Nihal Singh Committed by Varun Patil

Adds 'Add to Calendar' integration (#286)

* Calender provider implementation

* Undo Calendar provider. Intent approach with dialog

* Lambdas, undo manifest change

* Settings ListPreference added. Fixes minor bug from #284

* Improving EventFragment diff, cleanup

* Preserve going status of event on going back to fragment
parent 99e7df5a
......@@ -6,6 +6,10 @@ public class Constants {
public static final int RESULT_LOAD_IMAGE = 11;
public static final int REQUEST_CAMERA_INT_ID = 101;
public static final String DARK_THEME = "dark_theme";
public static final String CALENDAR_DIALOG = "calendar_dialog";
public static final String CALENDAR_DIALOG_YES = "Yes";
public static final String CALENDAR_DIALOG_NO = "No";
public static final String CALENDAR_DIALOG_ALWAYS_ASK = "Always ask";
public static final String NOTIFICATIONS_RESPONSE_JSON = "notifications_json";
public static final String EVENT_ID = "event_id";
public static final String EVENT_LATITUDE = "event_latitude";
......
......@@ -274,14 +274,20 @@ public class Event implements CardInterface {
subtitle += simpleDateFormatDate.format(Date) + " | " + simpleDateFormatTime.format(Date);
}
String eventVenueName = getEventVenueString();
if (!eventVenueName.equals(""))
subtitle += " | " + eventVenueName;
return subtitle;
}
public String getEventVenueString() {
StringBuilder eventVenueName = new StringBuilder();
for (Venue venue : getEventVenues()) {
eventVenueName.append(", ").append(venue.getVenueShortName());
}
if (!eventVenueName.toString().equals(""))
subtitle += " | " + eventVenueName.toString().substring(2);
return subtitle;
return eventVenueName.toString().equals("") ? "" : eventVenueName.toString().substring(2);
}
public String getAvatarUrl() {
......
......@@ -5,12 +5,16 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Bundle;
import android.provider.CalendarContract;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
......@@ -24,6 +28,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
......@@ -168,12 +173,7 @@ public class EventFragment extends BackHandledFragment implements TransitionTarg
((CoordinatorLayout.LayoutParams) mAppBarLayout.getLayoutParams()).setBehavior(new AppBarLayout.Behavior());
// Set offset on init
mAppBarLayout.post(new Runnable() {
@Override
public void run() {
setAppBarOffset(appBarOffset);
}
});
mAppBarLayout.post(() -> setAppBarOffset(appBarOffset));
// Store offset for next init
mAppBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
......@@ -279,15 +279,12 @@ public class EventFragment extends BackHandledFragment implements TransitionTarg
if (event.getEventVenues().get(0).getVenueLatitude() == 0) {
navigateButton.setVisibility(View.GONE);
} else {
navigateButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Venue primaryVenue = event.getEventVenues().get(0);
Uri gmmIntentUri = Uri.parse("google.navigation:q=" + primaryVenue.getVenueLatitude() + "," + primaryVenue.getVenueLongitude() + "(" + primaryVenue.getVenueName() + ")");
Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
mapIntent.setPackage("com.google.android.apps.maps");
startActivity(mapIntent);
}
navigateButton.setOnClickListener(v -> {
Venue primaryVenue = event.getEventVenues().get(0);
Uri gmmIntentUri = Uri.parse("google.navigation:q=" + primaryVenue.getVenueLatitude() + "," + primaryVenue.getVenueLongitude() + "(" + primaryVenue.getVenueName() + ")");
Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
mapIntent.setPackage("com.google.android.apps.maps");
startActivity(mapIntent);
});
}
} else {
......@@ -318,37 +315,26 @@ public class EventFragment extends BackHandledFragment implements TransitionTarg
});
}
eventPicture.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
zoomImageFromThumb(eventPicture);
}
});
eventPicture.setOnClickListener(v -> zoomImageFromThumb(eventPicture));
mShortAnimationDuration = getResources().getInteger(android.R.integer.config_shortAnimTime);
final FloatingActionButton fab = (FloatingActionButton) getView().findViewById(R.id.edit_fab);
final FloatingActionButton fab = getView().findViewById(R.id.edit_fab);
if (((MainActivity) getActivity()).editEventAccess(event)) {
fab.show();
NestedScrollView nsv = (NestedScrollView) getView().findViewById(R.id.event_scrollview);
nsv.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
@Override
public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
if (scrollY > oldScrollY) fab.hide();
else fab.show();
}
NestedScrollView nsv = getView().findViewById(R.id.event_scrollview);
nsv.setOnScrollChangeListener((NestedScrollView.OnScrollChangeListener) (v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
if (scrollY > oldScrollY) fab.hide();
else fab.show();
});
}
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AddEventFragment addEventFragment = new AddEventFragment();
Bundle bundle = new Bundle();
bundle.putString("id", event.getEventID());
addEventFragment.setArguments(bundle);
((MainActivity) getActivity()).updateFragment(addEventFragment);
}
fab.setOnClickListener(v -> {
AddEventFragment addEventFragment = new AddEventFragment();
Bundle bundle = new Bundle();
bundle.putString("id", event.getEventID());
addEventFragment.setArguments(bundle);
((MainActivity) getActivity()).updateFragment(addEventFragment);
});
}
......@@ -368,221 +354,290 @@ public class EventFragment extends BackHandledFragment implements TransitionTarg
}
private View.OnClickListener getGoingButtonOnClickListener() {
return new View.OnClickListener() {
@Override
public void onClick(View v) {
int currentStatus = event.getEventUserUes();
final int finalStatus;
if (currentStatus == Constants.STATUS_GOING) {
event.setEventGoingCount(event.getEventGoingCount() - 1);
finalStatus = Constants.STATUS_NOT_GOING;
} else if (currentStatus == Constants.STATUS_INTERESTED) {
event.setEventInterestedCount(event.getEventInterestedCount() - 1);
event.setEventGoingCount(event.getEventGoingCount() + 1);
finalStatus = Constants.STATUS_GOING;
} else {
event.setEventGoingCount(event.getEventGoingCount() + 1);
finalStatus = Constants.STATUS_GOING;
}
return v -> {
int currentStatus = event.getEventUserUes();
final int finalStatus;
if (currentStatus == Constants.STATUS_GOING) {
event.setEventGoingCount(event.getEventGoingCount() - 1);
finalStatus = Constants.STATUS_NOT_GOING;
} else if (currentStatus == Constants.STATUS_INTERESTED) {
event.setEventInterestedCount(event.getEventInterestedCount() - 1);
event.setEventGoingCount(event.getEventGoingCount() + 1);
finalStatus = Constants.STATUS_GOING;
} else {
event.setEventGoingCount(event.getEventGoingCount() + 1);
finalStatus = Constants.STATUS_GOING;
}
RetrofitInterface retrofitInterface = Utils.getRetrofitInterface();
retrofitInterface.updateUserEventStatus(Utils.getSessionIDHeader(), event.getEventID(), finalStatus).enqueue(new Callback<Void>() {
@Override
public void onResponse(Call<Void> call, Response<Void> response) {
event.setEventUserUes(finalStatus);
updateGoingInterestedButtonsAppearance(finalStatus);
RetrofitInterface retrofitInterface = Utils.getRetrofitInterface();
retrofitInterface.updateUserEventStatus(Utils.getSessionIDHeader(), event.getEventID(), finalStatus).enqueue(new Callback<Void>() {
@Override
public void onResponse(Call<Void> call, Response<Void> response) {
event.setEventUserUes(finalStatus);
updateGoingInterestedButtonsAppearance(finalStatus);
// Update global memory cache
Utils.eventCache.updateCache(event);
// Preserve status on going back
if (getArguments() != null) {
getArguments().putString(Constants.EVENT_JSON, Utils.gson.toJson(event));
}
@Override
public void onFailure(Call<Void> call, Throwable t) {
Toast.makeText(getContext(), "Network Error", Toast.LENGTH_LONG).show();
// Update global memory cache
Utils.eventCache.updateCache(event);
if (finalStatus == Constants.STATUS_GOING) {
addEventToCalender();
}
}
});
}
@Override
public void onFailure(Call<Void> call, Throwable t) {
Toast.makeText(getContext(), "Network Error", Toast.LENGTH_LONG).show();
}
});
};
}
private View.OnClickListener getInterestedButtonOnClickListener () {
return new View.OnClickListener() {
@Override
public void onClick(View v) {
int currentStatus = event.getEventUserUes();
final int finalStatus;
if (currentStatus == Constants.STATUS_INTERESTED) {
event.setEventInterestedCount(event.getEventInterestedCount() - 1);
finalStatus = Constants.STATUS_NOT_GOING;
} else if (currentStatus == Constants.STATUS_GOING) {
event.setEventInterestedCount(event.getEventInterestedCount() + 1);
event.setEventGoingCount(event.getEventGoingCount() - 1);
finalStatus = Constants.STATUS_INTERESTED;
} else {
event.setEventGoingCount(event.getEventInterestedCount() + 1);
finalStatus = Constants.STATUS_INTERESTED;
}
RetrofitInterface retrofitInterface = Utils.getRetrofitInterface();
retrofitInterface.updateUserEventStatus(Utils.getSessionIDHeader(), event.getEventID(), finalStatus).enqueue(new Callback<Void>() {
@Override
public void onResponse(Call<Void> call, Response<Void> response) {
event.setEventUserUes(finalStatus);
updateGoingInterestedButtonsAppearance(finalStatus);
private View.OnClickListener getInterestedButtonOnClickListener() {
return v -> {
int currentStatus = event.getEventUserUes();
final int finalStatus;
if (currentStatus == Constants.STATUS_INTERESTED) {
event.setEventInterestedCount(event.getEventInterestedCount() - 1);
finalStatus = Constants.STATUS_NOT_GOING;
} else if (currentStatus == Constants.STATUS_GOING) {
event.setEventInterestedCount(event.getEventInterestedCount() + 1);
event.setEventGoingCount(event.getEventGoingCount() - 1);
finalStatus = Constants.STATUS_INTERESTED;
} else {
event.setEventInterestedCount(event.getEventInterestedCount() + 1);
finalStatus = Constants.STATUS_INTERESTED;
}
// Update global memory cache
Utils.eventCache.updateCache(event);
}
RetrofitInterface retrofitInterface = Utils.getRetrofitInterface();
retrofitInterface.updateUserEventStatus(Utils.getSessionIDHeader(), event.getEventID(), finalStatus).enqueue(new Callback<Void>() {
@Override
public void onResponse(Call<Void> call, Response<Void> response) {
event.setEventUserUes(finalStatus);
updateGoingInterestedButtonsAppearance(finalStatus);
@Override
public void onFailure(Call<Void> call, Throwable t) {
Toast.makeText(getContext(), "Network Error", Toast.LENGTH_LONG).show();
}
// Update global memory cache
Utils.eventCache.updateCache(event);
});
if (finalStatus == Constants.STATUS_INTERESTED) {
addEventToCalender();
}
}
};
}
@Override
public void onFailure(Call<Void> call, Throwable t) {
Toast.makeText(getContext(), "Network Error", Toast.LENGTH_LONG).show();
}
private void zoomImageFromThumb ( final ImageView thumbView){
// If there's an animation in progress, cancel it
// immediately and proceed with this one.
if (mCurrentAnimator != null) {
mCurrentAnimator.cancel();
}
});
};
}
private void addEventToCalender() {
SharedPreferences sharedPref = getContext().getSharedPreferences(Constants.PREF_NAME, Context.MODE_PRIVATE);
String savedOption = sharedPref.getString(Constants.CALENDAR_DIALOG, Constants.CALENDAR_DIALOG_ALWAYS_ASK);
if (savedOption.equals(Constants.CALENDAR_DIALOG_YES)) {
createAddToCalendarIntent();
} else if (savedOption.equals(Constants.CALENDAR_DIALOG_ALWAYS_ASK)) {
showAddEventToCalendarDialog();
}
}
// Load the high-resolution "zoomed-in" image.
expandedImageView = (ImageView) getActivity().findViewById(
R.id.expanded_image_event);
expandedImageView.setImageDrawable(thumbView.getDrawable());
// Calculate the starting and ending bounds for the zoomed-in image.
// This step involves lots of math. Yay, math.
startBounds = new Rect();
final Rect finalBounds = new Rect();
final Point globalOffset = new Point();
// The start bounds are the global visible rectangle of the thumbnail,
// and the final bounds are the global visible rectangle of the container
// view. Also set the container view's offset as the origin for the
// bounds, since that's the origin for the positioning animation
// properties (X, Y).
thumbView.getGlobalVisibleRect(startBounds);
getActivity().findViewById(R.id.container_event)
.getGlobalVisibleRect(finalBounds, globalOffset);
startBounds.offset(-globalOffset.x, -globalOffset.y);
finalBounds.offset(-globalOffset.x, -globalOffset.y);
// Adjust the start bounds to be the same aspect ratio as the final
// bounds using the "center crop" technique. This prevents undesirable
// stretching during the animation. Also calculate the start scaling
// factor (the end scaling factor is always 1.0).
float startScale;
if ((float) finalBounds.width() / finalBounds.height()
> (float) startBounds.width() / startBounds.height()) {
// Extend start bounds horizontally
startScale = (float) startBounds.height() / finalBounds.height();
float startWidth = startScale * finalBounds.width();
float deltaWidth = (startWidth - startBounds.width()) / 2;
startBounds.left -= deltaWidth;
startBounds.right += deltaWidth;
private void saveCalendarDialogPreference(boolean dontAskAgain, boolean yes) {
SharedPreferences sharedPref = getActivity().getSharedPreferences(Constants.PREF_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
if (!dontAskAgain) {
editor.putString(Constants.CALENDAR_DIALOG, Constants.CALENDAR_DIALOG_ALWAYS_ASK);
editor.commit();
} else {
if (yes) {
editor.putString(Constants.CALENDAR_DIALOG, Constants.CALENDAR_DIALOG_YES);
editor.commit();
} else {
// Extend start bounds vertically
startScale = (float) startBounds.width() / finalBounds.width();
float startHeight = startScale * finalBounds.height();
float deltaHeight = (startHeight - startBounds.height()) / 2;
startBounds.top -= deltaHeight;
startBounds.bottom += deltaHeight;
editor.putString(Constants.CALENDAR_DIALOG, Constants.CALENDAR_DIALOG_NO);
editor.commit();
}
}
}
// Hide the thumbnail and show the zoomed-in view. When the animation
// begins, it will position the zoomed-in view in the place of the
// thumbnail.
thumbView.setAlpha(0f);
expandedImageView.setVisibility(View.VISIBLE);
// Set the pivot point for SCALE_X and SCALE_Y transformations
// to the top-left corner of the zoomed-in view (the default
// is the center of the view).
expandedImageView.setPivotX(0f);
expandedImageView.setPivotY(0f);
// Construct and run the parallel animation of the four translation and
// scale properties (X, Y, SCALE_X, and SCALE_Y).
AnimatorSet set = new AnimatorSet();
set
.play(ObjectAnimator.ofFloat(expandedImageView, View.X,
startBounds.left, finalBounds.left))
.with(ObjectAnimator.ofFloat(expandedImageView, View.Y,
startBounds.top, finalBounds.top))
.with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_X,
startScale, 1f))
.with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_Y,
startScale, 1f));
set.setDuration(mShortAnimationDuration);
set.setInterpolator(new DecelerateInterpolator());
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mCurrentAnimator = null;
expandedImageView.setBackgroundColor(Color.parseColor("#9E9E9E"));
}
private void showAddEventToCalendarDialog() {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getContext());
LayoutInflater layoutInflater = LayoutInflater.from(getContext());
View layout = layoutInflater.inflate(R.layout.calendar_dialog_checkbox, null);
dialogBuilder.setView(layout);
CheckBox dontShowAgain = layout.findViewById(R.id.skip);
dialogBuilder.setTitle("Add to Calendar")
.setMessage("You will be notified about this event by InstiApp. Do you also want to add this event to your calendar?")
.setPositiveButton("Yes", (dialog, which) -> {
createAddToCalendarIntent();
saveCalendarDialogPreference(dontShowAgain.isChecked(), true);
})
.setNegativeButton("No", (dialog, which) -> {
dialog.cancel();
saveCalendarDialogPreference(dontShowAgain.isChecked(), false);
})
.create()
.show();
}
@Override
public void onAnimationCancel(Animator animation) {
mCurrentAnimator = null;
}
});
set.start();
mCurrentAnimator = set;
private void createAddToCalendarIntent() {
Intent intent = new Intent(Intent.ACTION_INSERT);
intent.setType("vnd.android.cursor.item/event");
intent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, event.getEventStartTime().getTime());
intent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, event.getEventEndTime().getTime());
intent.putExtra(CalendarContract.EXTRA_EVENT_ALL_DAY, event.isAllDayEvent());
intent.putExtra(CalendarContract.Events.TITLE, event.getTitle());
intent.putExtra(CalendarContract.Events.DESCRIPTION, event.getEventDescription());
intent.putExtra(CalendarContract.Events.EVENT_LOCATION, event.getEventVenueString());
startActivity(intent);
}
private void zoomImageFromThumb(final ImageView thumbView) {
// If there's an animation in progress, cancel it
// immediately and proceed with this one.
if (mCurrentAnimator != null) {
mCurrentAnimator.cancel();
}
startScaleFinal = startScale;
zoomMode = true;
// Load the high-resolution "zoomed-in" image.
expandedImageView = getActivity().findViewById(
R.id.expanded_image_event);
expandedImageView.setImageDrawable(thumbView.getDrawable());
// Calculate the starting and ending bounds for the zoomed-in image.
// This step involves lots of math. Yay, math.
startBounds = new Rect();
final Rect finalBounds = new Rect();
final Point globalOffset = new Point();
// The start bounds are the global visible rectangle of the thumbnail,
// and the final bounds are the global visible rectangle of the container
// view. Also set the container view's offset as the origin for the
// bounds, since that's the origin for the positioning animation
// properties (X, Y).
thumbView.getGlobalVisibleRect(startBounds);
getActivity().findViewById(R.id.container_event)
.getGlobalVisibleRect(finalBounds, globalOffset);
startBounds.offset(-globalOffset.x, -globalOffset.y);
finalBounds.offset(-globalOffset.x, -globalOffset.y);
// Adjust the start bounds to be the same aspect ratio as the final
// bounds using the "center crop" technique. This prevents undesirable
// stretching during the animation. Also calculate the start scaling
// factor (the end scaling factor is always 1.0).
float startScale;
if ((float) finalBounds.width() / finalBounds.height()
> (float) startBounds.width() / startBounds.height()) {
// Extend start bounds horizontally
startScale = (float) startBounds.height() / finalBounds.height();
float startWidth = startScale * finalBounds.width();
float deltaWidth = (startWidth - startBounds.width()) / 2;
startBounds.left -= deltaWidth;
startBounds.right += deltaWidth;
} else {
// Extend start bounds vertically
startScale = (float) startBounds.width() / finalBounds.width();
float startHeight = startScale * finalBounds.height();
float deltaHeight = (startHeight - startBounds.height()) / 2;
startBounds.top -= deltaHeight;
startBounds.bottom += deltaHeight;
}
private void zoomOut ( final ImageView expandedImageView, Rect startBounds,
float startScaleFinal, final View thumbView){
expandedImageView.setBackgroundColor(0x00000000);
if (mCurrentAnimator != null) {
mCurrentAnimator.cancel();
// Hide the thumbnail and show the zoomed-in view. When the animation
// begins, it will position the zoomed-in view in the place of the
// thumbnail.
thumbView.setAlpha(0f);
expandedImageView.setVisibility(View.VISIBLE);
// Set the pivot point for SCALE_X and SCALE_Y transformations
// to the top-left corner of the zoomed-in view (the default
// is the center of the view).
expandedImageView.setPivotX(0f);
expandedImageView.setPivotY(0f);
// Construct and run the parallel animation of the four translation and
// scale properties (X, Y, SCALE_X, and SCALE_Y).
AnimatorSet set = new AnimatorSet();
set
.play(ObjectAnimator.ofFloat(expandedImageView, View.X,
startBounds.left, finalBounds.left))
.with(ObjectAnimator.ofFloat(expandedImageView, View.Y,
startBounds.top, finalBounds.top))
.with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_X,
startScale, 1f))
.with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_Y,
startScale, 1f));
set.setDuration(mShortAnimationDuration);
set.setInterpolator(new DecelerateInterpolator());
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mCurrentAnimator = null;
expandedImageView.setBackgroundColor(Color.parseColor("#9E9E9E"));
}
// Animate the four positioning/sizing properties in parallel,
// back to their original values.
AnimatorSet set = new AnimatorSet();
set.play(ObjectAnimator
.ofFloat(expandedImageView, View.X, startBounds.left))
.with(ObjectAnimator
.ofFloat(expandedImageView,
View.Y, startBounds.top))
.with(ObjectAnimator
.ofFloat(expandedImageView,
View.SCALE_X, startScaleFinal))
.with(ObjectAnimator
.ofFloat(expandedImageView,
View.SCALE_Y, startScaleFinal));
set.setDuration(mShortAnimationDuration);
set.setInterpolator(new DecelerateInterpolator());
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
thumbView.setAlpha(1f);
expandedImageView.setVisibility(View.GONE);
mCurrentAnimator = null;
}
@Override
public void onAnimationCancel(Animator animation) {
mCurrentAnimator = null;
}
});
set.start();
mCurrentAnimator = set;
@Override
public void onAnimationCancel(Animator animation) {
thumbView.setAlpha(1f);
expandedImageView.setVisibility(View.GONE);
mCurrentAnimator = null;
}
});
set.start();
mCurrentAnimator = set;
startScaleFinal = startScale;
zoomMode = true;
}
private void zoomOut(final ImageView expandedImageView, Rect startBounds,
float startScaleFinal, final View thumbView) {
expandedImageView.setBackgroundColor(0x00000000);
if (mCurrentAnimator != null) {
mCurrentAnimator.cancel();
}
// Animate the four positioning/sizing properties in parallel,
// back to their original values.
AnimatorSet set = new AnimatorSet();
set.play(ObjectAnimator
.ofFloat(expandedImageView, View.X, startBounds.left))
.with(ObjectAnimator
.ofFloat(expandedImageView,
View.Y, startBounds.top))
.with(ObjectAnimator
.ofFloat(expandedImageView,
View.SCALE_X, startScaleFinal))
.with(ObjectAnimator
.ofFloat(expandedImageView,
View.SCALE_Y, startScaleFinal));
set.setDuration(mShortAnimationDuration);
set.setInterpolator(new DecelerateInterpolator());
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
thumbView.setAlpha(1f);
expandedImageView.setVisibility(View.GONE);
mCurrentAnimator = null;
}
@Override
public void onAnimationCancel(Animator animation) {
thumbView.setAlpha(1f);
expandedImageView.setVisibility(View.GONE);
mCurrentAnimator = null;
}
});
set.start();
mCurrentAnimator = set;
}
}
......@@ -5,6 +5,8 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.SwitchPreferenceCompat;
......@@ -37,64 +39,54 @@ public class SettingsFragment extends PreferenceFragmentCompat {
// Show contact number
showContactPref = (SwitchPreferenceCompat) findPreference("show_contact");
showContactPref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object o) {
toggleShowContact((SwitchPreferenceCompat) preference, o);
return false;
}
showContactPref.setOnPreferenceChangeListener((preference, option) -> {
toggleShowContact((SwitchPreferenceCompat) preference, option);
return false;
});
showContactPref.setEnabled(false);
// Dark Theme
SwitchPreferenceCompat darkThemePref = (SwitchPreferenceCompat) findPreference("dark_theme");
darkThemePref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object o) {
toggleDarkTheme((SwitchPreferenceCompat) preference, o);
return true;
}
darkThemePref.setOnPreferenceChangeListener((preference, option) -> {
toggleDarkTheme((boolean) option);
return true;
});
darkThemePref.setChecked(sharedPref.getBoolean(Constants.DARK_THEME, false));
// Add to Calendar
ListPreference calendarPref = (ListPreference) findPreference("add_to_calendar");
calendarPref.setOnPreferenceChangeListener((preference, option) -> {
toggleCalendarDialog((String) option);
return true;
});
calendarPref.setValue(sharedPref.getString(Constants.CALENDAR_DIALOG, Constants.CALENDAR_DIALOG_ALWAYS_ASK));
// Update Profile
Preference profilePref = findPreference("profile");
profilePref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
openWebURL("https://gymkhana.iitb.ac.in/sso/user");
return false;
}
profilePref.setOnPreferenceClickListener(preference -> {
openWebURL("https://gymkhana.iitb.ac.in/sso/user");
return false;
});
// Feedback
Preference feedbackPref = findPreference("feedback");
feedbackPref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
openWebURL("https://insti.app/feedback");
return false;
}
feedbackPref.setOnPreferenceClickListener(preference -> {
openWebURL("https://insti.app/feedback");
return false;
});
// About
Preference aboutPref = findPreference("about");
aboutPref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
openAbout();
return false;
}
aboutPref.setOnPreferenceClickListener(preference -> {
openAbout();
return false;
});
// Logout
Preference logoutPref = findPreference("logout");
logoutPref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
logout();
return false;
}
logoutPref.setOnPreferenceClickListener(preference -> {
logout();
return false;
});
// Disable buttons if not logged in
......@@ -139,8 +131,8 @@ public class SettingsFragment extends PreferenceFragmentCompat {
}
}
public void toggleShowContact(final SwitchPreferenceCompat showContactPref, Object o) {
final boolean isChecked = (boolean) o;
private void toggleShowContact(final SwitchPreferenceCompat showContactPref, Object option) {
final boolean isChecked = (boolean) option;
showContactPref.setEnabled(false);
RetrofitInterface retrofitInterface = Utils.getRetrofitInterface();
retrofitInterface.patchUserMe(Utils.getSessionIDHeader(), new UserShowContactPatchRequest(isChecked)).enqueue(new Callback<User>() {
......@@ -166,17 +158,29 @@ public class SettingsFragment extends PreferenceFragmentCompat {
});
}
public void toggleDarkTheme(final SwitchPreferenceCompat showContactPref, Object o) {
editor.putBoolean(Constants.DARK_THEME, (boolean) o);
private void toggleDarkTheme(boolean option) {
editor.putBoolean(Constants.DARK_THEME, option);
editor.commit();
Utils.changeTheme(this, option);
}
private void toggleCalendarDialog(String option) {
// Using strings.xml values for populating ListPreference. `option` comes from strings.xml
// Using Constants for updating SharedPrefs. `choice` comes from Constants.
String choice = Constants.CALENDAR_DIALOG_ALWAYS_ASK;
if (option.equals(getString(R.string.calendar_yes))) choice = Constants.CALENDAR_DIALOG_YES;
else if (option.equals(getString(R.string.calendar_no))) choice = Constants.CALENDAR_DIALOG_NO;
editor.putString(Constants.CALENDAR_DIALOG, choice);
editor.commit();
Utils.changeTheme(this, (boolean) o);
}
public void openAbout() {
private void openAbout() {
Utils.updateFragment(new AboutFragment(), getActivity());
}
public void logout() {
private void logout() {
final SessionManager sessionManager = new SessionManager(getContext());
RetrofitInterface retrofitInterface = Utils.getRetrofitInterface();
retrofitInterface.logout(Utils.getSessionIDHeader()).enqueue(new EmptyCallback<Void>() {
......
<vector android:height="36dp" android:tint="#767676"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="36dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M17,12h-5v5h5v-5zM16,1v2L8,3L8,1L6,1v2L5,3c-1.11,0 -1.99,0.9 -1.99,2L3,19c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2h-1L18,1h-2zM19,19L5,19L5,8h14v11z"/>
</vector>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout_root"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:padding="20dp" >
<CheckBox
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/skip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Remember my choice and don't ask me again" >
</CheckBox>
</LinearLayout>
\ No newline at end of file
......@@ -27,6 +27,17 @@
<item>QIP</item>
</string-array>
<string-array name="add_to_calendar_options">
<item>@string/calendar_yes</item>
<item>@string/calendar_no</item>
<item>@string/calendar_always_ask</item>
</string-array>
<!-- Add to Calendar Preference options -->
<string name="calendar_yes">Yes</string>
<string name="calendar_no">No</string>
<string name="calendar_always_ask">Always ask</string>
<string name="default_notification_channel_id">INSTIAPP_NOTIFS</string>
<!--NSS side-->
......
......@@ -15,6 +15,14 @@
app:summary="Note: this feature is in beta"
android:icon="@drawable/ic_color_lens_gray_36dp"/>
<ListPreference
app:key="add_to_calendar"
app:title="Add to Calendar"
app:summary="Add to calendar on Going/Interested press"
app:entries="@array/add_to_calendar_options"
app:entryValues="@array/add_to_calendar_options"
android:icon="@drawable/ic_event_gray_36dp"/>
<Preference
app:key="profile"
app:title="Update Profile"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment