Skip to content

Commit

Permalink
Merge pull request #327 from criticalmaps/apiv2
Browse files Browse the repository at this point in the history
Use new API architecture
  • Loading branch information
cbalster committed Jun 4, 2023
2 parents 2f0d2f0 + e03131f commit 4dfc5c2
Show file tree
Hide file tree
Showing 19 changed files with 511 additions and 287 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,50 +15,32 @@

import de.stephanlindauer.criticalmaps.R;
import de.stephanlindauer.criticalmaps.databinding.ViewChatmessageBinding;
import de.stephanlindauer.criticalmaps.interfaces.IChatMessage;
import de.stephanlindauer.criticalmaps.model.chat.ReceivedChatMessage;
import de.stephanlindauer.criticalmaps.utils.TimeToWordStringConverter;

public class ChatMessageAdapter extends RecyclerView.Adapter<ChatMessageAdapter.ChatMessageViewHolder> {

private List<IChatMessage> chatMessages;
private List<ReceivedChatMessage> chatMessages;

static class ChatMessageViewHolder extends RecyclerView.ViewHolder {
private final ViewChatmessageBinding binding;
private final DateFormat dateFormatter = DateFormat.getDateTimeInstance(
DateFormat.DEFAULT, DateFormat.SHORT, Locale.getDefault());
private ObjectAnimator sendingAnimator;

ChatMessageViewHolder(ViewChatmessageBinding binding) {
super(binding.getRoot());
this.binding = binding;
}

void bind(IChatMessage message) {
void bind(ReceivedChatMessage message) {
binding.chatmessageMessageText.setText(message.getMessage());
if (message instanceof ReceivedChatMessage) {
dateFormatter.setTimeZone(TimeZone.getDefault());
binding.chatmessageLabelText.setText(TimeToWordStringConverter.getTimeAgo(
((ReceivedChatMessage) message).getTimestamp(), itemView.getContext()));
} else {
binding.chatmessageLabelText.setText(R.string.chat_sending);

sendingAnimator = (ObjectAnimator) AnimatorInflater.loadAnimator(
itemView.getContext(), R.animator.map_gps_fab_searching_animation);
sendingAnimator.setTarget(binding.chatmessageLabelText);
sendingAnimator.start();
}
}

void clearAnimation() {
if (sendingAnimator != null) {
sendingAnimator.cancel();
binding.chatmessageLabelText.setAlpha(1f);
}
dateFormatter.setTimeZone(TimeZone.getDefault());
binding.chatmessageLabelText.setText(TimeToWordStringConverter.getTimeAgo(
message.getTimestamp(), itemView.getContext()));
}
}

public ChatMessageAdapter(List<IChatMessage> chatMessages) {
public ChatMessageAdapter(List<ReceivedChatMessage> chatMessages) {
this.chatMessages = chatMessages;
}

Expand All @@ -77,17 +59,12 @@ public void onBindViewHolder(@NonNull ChatMessageViewHolder holder, int position
holder.bind(chatMessages.get(position));
}

@Override
public void onViewDetachedFromWindow(@NonNull ChatMessageViewHolder holder) {
holder.clearAnimation();
}

@Override
public int getItemCount() {
return chatMessages.size();
}

public void updateData(List<IChatMessage> savedAndOutgoingMessages) {
public void updateData(List<ReceivedChatMessage> savedAndOutgoingMessages) {
this.chatMessages = savedAndOutgoingMessages;
notifyDataSetChanged();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
Expand All @@ -22,24 +23,34 @@

import com.squareup.otto.Subscribe;

import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import javax.inject.Inject;
import javax.inject.Provider;

import de.stephanlindauer.criticalmaps.App;
import de.stephanlindauer.criticalmaps.R;
import de.stephanlindauer.criticalmaps.adapter.ChatMessageAdapter;
import de.stephanlindauer.criticalmaps.databinding.FragmentChatBinding;
import de.stephanlindauer.criticalmaps.events.NetworkConnectivityChangedEvent;
import de.stephanlindauer.criticalmaps.events.NewServerResponseEvent;
import de.stephanlindauer.criticalmaps.interfaces.IChatMessage;
import de.stephanlindauer.criticalmaps.handler.GetChatmessagesHandler;
import de.stephanlindauer.criticalmaps.handler.PostChatmessagesHandler;
import de.stephanlindauer.criticalmaps.model.ChatModel;
import de.stephanlindauer.criticalmaps.model.chat.OutgoingChatMessage;
import de.stephanlindauer.criticalmaps.model.chat.ReceivedChatMessage;
import de.stephanlindauer.criticalmaps.provider.EventBus;
import de.stephanlindauer.criticalmaps.utils.AxtUtils.SimpleTextWatcher;


public class ChatFragment extends Fragment {
@Inject
Provider<GetChatmessagesHandler> getChatmessagesHandler;

@Inject
ChatModel chatModel;

Expand All @@ -49,6 +60,10 @@ public class ChatFragment extends Fragment {
private boolean isTextInputEnabled = true;
private ChatMessageAdapter chatMessageAdapter;
private FragmentChatBinding binding;
// private ObjectAnimator sendingAnimator;
private Timer timerGetChatmessages;

private final int SERVER_SYNC_INTERVAL = 20 * 1000; // 20 sec

@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Expand All @@ -70,9 +85,9 @@ public void onActivityCreated(final Bundle savedState) {
binding.chatMessagesRecyclerview.setAdapter(chatMessageAdapter);
displayNewData();

binding.chatMessageTextinputlayout.setCounterMaxLength(IChatMessage.MAX_LENGTH);
binding.chatMessageTextinputlayout.setCounterMaxLength(ChatModel.MESSAGE_MAX_LENGTH);
binding.chatMessageEdittext.setFilters(
new InputFilter[]{new InputFilter.LengthFilter(IChatMessage.MAX_LENGTH)});
new InputFilter[]{new InputFilter.LengthFilter(ChatModel.MESSAGE_MAX_LENGTH)});
binding.chatMessageEdittext.setOnEditorActionListener(
(v, actionId, event) -> handleEditorAction(actionId));

Expand Down Expand Up @@ -130,18 +145,57 @@ private void handleSendClicked() {
return;
}

chatModel.setNewOutgoingMessage(new OutgoingChatMessage(message));
// TODO handle UI state while sending, even though it shouldn't be noticeable

JSONObject messageObject = chatModel.createNewOutgoingMessage(message);
new PostChatmessagesHandler(messageObject, new Runnable() {
@Override
public void run() {
// TODO check if still alive; else bail!
// TODO reset UI state
// clearAnimation();

// Restart timer task so sent message shows up in list immediately
stopGetChatmessagesTimer();
startGetChatmessagesTimer();
}
}, new Runnable() {
@Override
public void run() {
// TODO check if still alive; else bail!
// TODO reset UI state
Toast.makeText(getContext(), R.string.something_went_wrong, Toast.LENGTH_LONG).show();
}
}).execute();

binding.chatMessageEdittext.setText("");
displayNewData();
}

/*
private void setSendingAnimation() {
binding.chatmessageLabelText.setText(R.string.chat_sending);
sendingAnimator = (ObjectAnimator) AnimatorInflater.loadAnimator(
itemView.getContext(), R.animator.map_gps_fab_searching_animation);
sendingAnimator.setTarget(binding.chatmessageLabelText);
sendingAnimator.start();
}
private void clearAnimation() {
if (sendingAnimator != null) {
sendingAnimator.cancel();
binding.chatmessageLabelText.setAlpha(1f);
}
}
*/

private void displayNewData() {
final List<IChatMessage> savedAndOutgoingMessages = chatModel.getSavedAndOutgoingMessages();
chatMessageAdapter.updateData(savedAndOutgoingMessages);
final List<ReceivedChatMessage> receivedChatMessages = chatModel.getReceivedChatMessages();
chatMessageAdapter.updateData(receivedChatMessages);

if (binding.chatMessagesRecyclerview.getScrollState() == RecyclerView.SCROLL_STATE_IDLE) {
binding.chatMessagesRecyclerview.scrollToPosition(savedAndOutgoingMessages.size() - 1);
binding.chatMessagesRecyclerview.scrollToPosition(receivedChatMessages.size() - 1);
}
}

Expand All @@ -150,18 +204,22 @@ public void onResume() {
super.onResume();
displayNewData();
eventBus.register(this);
startGetChatmessagesTimer();
}

@Override
public void onPause() {
super.onPause();
stopGetChatmessagesTimer();
eventBus.unregister(this);
hideKeyBoard(binding.chatMessageEdittext);
}

@Override
public void onDestroyView() {
super.onDestroyView();
// TODO
// clearAnimation();
binding = null;
}

Expand All @@ -175,6 +233,12 @@ public void handleNewServerData(NewServerResponseEvent e) {
@Subscribe
public void handleNetworkConnectivityChanged(NetworkConnectivityChangedEvent e) {
setTextInputState(e.isConnected);

if (e.isConnected && timerGetChatmessages == null) {
startGetChatmessagesTimer();
} else {
stopGetChatmessagesTimer();
}
}

private void setTextInputState(final boolean dataEnabled) {
Expand All @@ -195,4 +259,25 @@ private void updateSendButtonEnabledState() {
final String message = binding.chatMessageEdittext.getText().toString();
setSendButtonEnabledWithAnimation(!message.trim().isEmpty());
}

private void startGetChatmessagesTimer() {
stopGetChatmessagesTimer();

timerGetChatmessages = new Timer();

TimerTask timerTaskPullServer = new TimerTask() {
@Override
public void run() {
getChatmessagesHandler.get().execute();
}
};
timerGetChatmessages.scheduleAtFixedRate(timerTaskPullServer, 0, SERVER_SYNC_INTERVAL);
}

private void stopGetChatmessagesTimer() {
if (timerGetChatmessages != null) {
timerGetChatmessages.cancel();
timerGetChatmessages = null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@
import org.osmdroid.views.overlay.gestures.RotationGestureOverlay;
import org.osmdroid.views.overlay.infowindow.InfoWindow;

import java.util.Timer;
import java.util.TimerTask;

import javax.inject.Inject;
import javax.inject.Provider;

import de.stephanlindauer.criticalmaps.App;
import de.stephanlindauer.criticalmaps.R;
Expand All @@ -43,6 +47,7 @@
import de.stephanlindauer.criticalmaps.events.NetworkConnectivityChangedEvent;
import de.stephanlindauer.criticalmaps.events.NewLocationEvent;
import de.stephanlindauer.criticalmaps.events.NewServerResponseEvent;
import de.stephanlindauer.criticalmaps.handler.GetLocationHandler;
import de.stephanlindauer.criticalmaps.handler.ShowGpxHandler;
import de.stephanlindauer.criticalmaps.managers.LocationUpdateManager;
import de.stephanlindauer.criticalmaps.model.OtherUsersLocationModel;
Expand All @@ -54,6 +59,7 @@
import de.stephanlindauer.criticalmaps.utils.MapViewUtils;
import info.metadude.android.typedpreferences.BooleanPreference;


public class MapFragment extends Fragment {
private final static String KEY_MAP_ZOOMLEVEL = "map_zoomlevel";
private final static String KEY_MAP_POSITION = "map_position";
Expand All @@ -62,6 +68,10 @@ public class MapFragment extends Fragment {

private final static double DEFAULT_ZOOM_LEVEL = 12;
private final static double NO_GPS_PERMISSION_ZOOM_LEVEL = 3;
private final int SERVER_SYNC_INTERVAL = 30 * 1000; // 30 sec

@Inject
Provider<GetLocationHandler> getLocationHandler;

@Inject
OwnLocationModel ownLocationModel;
Expand Down Expand Up @@ -95,6 +105,8 @@ public class MapFragment extends Fragment {

private FragmentMapBinding binding;

private Timer timerGetLocation;

private final View.OnClickListener centerLocationOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
Expand Down Expand Up @@ -304,8 +316,8 @@ private void refreshView() {
@Override
public void onResume() {
super.onResume();
eventBus.register(this);

eventBus.register(this);
sharedPreferences.registerOnSharedPreferenceChangeListener(
observerModeOnSharedPreferenceChangeListener);

Expand All @@ -314,6 +326,8 @@ public void onResume() {
} else {
zoomToLocation(defaultGeoPoint, NO_GPS_PERMISSION_ZOOM_LEVEL);
}

startGetLocationTimer();
}

private void handleFirstLocationUpdate() {
Expand All @@ -335,8 +349,9 @@ public void onSaveInstanceState(@NonNull Bundle outState) {
@Override
public void onPause() {
super.onPause();
eventBus.unregister(this);

stopGetLocationTimer();
eventBus.unregister(this);
sharedPreferences.unregisterOnSharedPreferenceChangeListener(
observerModeOnSharedPreferenceChangeListener);
}
Expand Down Expand Up @@ -376,6 +391,12 @@ public void handleNetworkConnectivityChanged(NetworkConnectivityChangedEvent e)
} else {
binding.mapNoDataConnectivityFab.show();
}

if (e.isConnected && timerGetLocation == null) {
startGetLocationTimer();
} else {
stopGetLocationTimer();
}
}

@Subscribe
Expand Down Expand Up @@ -472,4 +493,25 @@ private void animateToLocation(final GeoPoint location) {
private void setToLocation(final GeoPoint location) {
mapView.getController().setCenter(location);
}

private void startGetLocationTimer() {
stopGetLocationTimer();

timerGetLocation = new Timer();

TimerTask timerTaskPullServer = new TimerTask() {
@Override
public void run() {
getLocationHandler.get().execute();
}
};
timerGetLocation.scheduleAtFixedRate(timerTaskPullServer, 0, SERVER_SYNC_INTERVAL);
}

private void stopGetLocationTimer() {
if (timerGetLocation != null) {
timerGetLocation.cancel();
timerGetLocation = null;
}
}
}
Loading

0 comments on commit 4dfc5c2

Please sign in to comment.