This commit is contained in:
2022-06-19 14:03:39 +02:00
parent 9e9ece3a9c
commit 9452f1910d
7 changed files with 479 additions and 465 deletions

View File

@@ -9,7 +9,8 @@
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme"> android:theme="@style/AppTheme">
<activity android:name=".LoginActivity"> <activity android:name=".LoginActivity"
android:exported="true">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />

View File

@@ -142,7 +142,7 @@ public class ChatFragment extends Fragment {
// Convert epoch timestamp to formatted date string // Convert epoch timestamp to formatted date string
Date date = new Date(timestamp * 1000L); Date date = new Date(timestamp * 1000L);
this.date = new SimpleDateFormat("dd.MM.YYYY HH:mm", Locale.getDefault()).format(date); this.date = new SimpleDateFormat("dd.MM.yyyy HH:mm", Locale.getDefault()).format(date);
// Check if the sender's user id still exist in the database. // Check if the sender's user id still exist in the database.
// If so, extract their nickname // If so, extract their nickname

View File

@@ -35,7 +35,6 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Objects;
public class HomeFragment extends Fragment { public class HomeFragment extends Fragment {
private View root; private View root;
@@ -44,7 +43,6 @@ public class HomeFragment extends Fragment {
private DataSnapshot dsUsers, dsGames; private DataSnapshot dsUsers, dsGames;
private ProgressBar progressBar; private ProgressBar progressBar;
private TextView welcome, nextDate, nextHost; private TextView welcome, nextDate, nextHost;
private Button btnSignOut, btnVote, btnSuggest;
private Spinner spinnerGames; private Spinner spinnerGames;
private Map<Long, Integer> games = new HashMap<>(); private Map<Long, Integer> games = new HashMap<>();
private String userNickname, nextDateID; private String userNickname, nextDateID;
@@ -55,11 +53,11 @@ public class HomeFragment extends Fragment {
welcome = root.findViewById(R.id.text_home); welcome = root.findViewById(R.id.text_home);
nextDate = root.findViewById(R.id.text_home2); nextDate = root.findViewById(R.id.text_home2);
nextHost = root.findViewById(R.id.text_home5); nextHost = root.findViewById(R.id.text_home5);
btnSignOut = root.findViewById(R.id.logout);
btnVote = root.findViewById(R.id.vote);
btnSuggest = root.findViewById(R.id.suggest);
spinnerGames = root.findViewById(R.id.spinner_games); spinnerGames = root.findViewById(R.id.spinner_games);
progressBar = root.findViewById(R.id.progressBar); progressBar = root.findViewById(R.id.progressBar);
Button btnSignOut = root.findViewById(R.id.logout);
Button btnVote = root.findViewById(R.id.vote);
Button btnSuggest = root.findViewById(R.id.suggest);
// Set button listeners // Set button listeners
btnSignOut.setOnClickListener(v -> signOutUser()); btnSignOut.setOnClickListener(v -> signOutUser());
@@ -76,28 +74,41 @@ public class HomeFragment extends Fragment {
refGames = FirebaseDatabase.getInstance().getReference("spiele"); refGames = FirebaseDatabase.getInstance().getReference("spiele");
refUsers = FirebaseDatabase.getInstance().getReference("spieler"); refUsers = FirebaseDatabase.getInstance().getReference("spieler");
// Get list of registered users from database // Get a list of all players from the database and store as DataSnapshot,
refUsers.addValueEventListener(new ValueEventListener() { // then check whether a new event needs to be added to the database.
refUsers.addListenerForSingleValueEvent(new ValueEventListener() {
@Override @Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) { public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
dsUsers = dataSnapshot; dsUsers = dataSnapshot;
setValues(); updateUI();
checkUpcomingEvent();
} }
@Override @Override
public void onCancelled(@NonNull DatabaseError databaseError) { public void onCancelled(@NonNull DatabaseError databaseError) {
Toast.makeText(getContext(), R.string.db_comm_err, Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), R.string.db_comm_err, Toast.LENGTH_SHORT).show();
} }
}); });
// Get list of available games from database // Update the UI whenever the list of players changes in the database
refUsers.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
dsUsers = dataSnapshot;
updateUI();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Toast.makeText(getContext(), R.string.db_comm_err, Toast.LENGTH_SHORT).show();
}
});
// Update the UI whenever the list of games changes in the database
refGames.addValueEventListener(new ValueEventListener() { refGames.addValueEventListener(new ValueEventListener() {
@Override @Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) { public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
dsGames = dataSnapshot; dsGames = dataSnapshot;
updateGamesList(); updateGamesList();
} }
@Override @Override
public void onCancelled(@NonNull DatabaseError databaseError) { public void onCancelled(@NonNull DatabaseError databaseError) {
Toast.makeText(getContext(), R.string.db_comm_err, Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), R.string.db_comm_err, Toast.LENGTH_SHORT).show();
@@ -116,15 +127,90 @@ public class HomeFragment extends Fragment {
if(isActive) { if(isActive) {
progressBar.setVisibility(View.VISIBLE); progressBar.setVisibility(View.VISIBLE);
// Disable user interaction while progress bar is visible // Disable user interaction while progress bar is visible
Objects.requireNonNull(getActivity()).getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, requireActivity().getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
} else if(progressBar.getVisibility() == View.VISIBLE) { } else if(progressBar.getVisibility() == View.VISIBLE) {
progressBar.setVisibility(View.GONE); progressBar.setVisibility(View.GONE);
// Re-enable user interaction when progress bar is gone // Re-enable user interaction when progress bar is gone
Objects.requireNonNull(getActivity()).getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); requireActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
} }
} }
/**
*
* Then get the most recent event next and check if .
* If so, a new event is added.
*/
private void checkUpcomingEvent() {
refEventDates.orderByKey().limitToLast(1).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
nextDateID = ds.getKey();
long epoch = Long.parseLong(nextDateID);
if(epoch < (System.currentTimeMillis() / 1000L)) {
addUpcomingEvent(epoch);
}
Date date = new Date(epoch * 1000L);
String s = new SimpleDateFormat("dd. MMMM yyyy", Locale.getDefault()).format(date);
nextDate.setText(s);
String sNextHostUID = (String) ds.child("gastgeber").getValue();
String sNextHost = (String)dsUsers.child(sNextHostUID).child("nickname").getValue();
nextHost.setText(sNextHost);
if(ds.hasChild("abstimmung_spiele")) {
games = new HashMap<>();
for(DataSnapshot dataSnapshot1 : ds.child("abstimmung_spiele").getChildren()) {
long curInt = (long)dataSnapshot1.getValue();
if(games.containsKey(curInt)) games.put(curInt, games.get(curInt)+1);
else games.put(curInt, 1);
}
}
}
setProgressBar(false);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Toast.makeText(getContext(), R.string.db_comm_err, Toast.LENGTH_SHORT).show();
}
});
}
/**
* Determines the date and host of the next event and writes the details to the database.
* If this was a real life app and not just an example project, it would be advisable to handle
* event setup automatically with scheduled functions running on the server (a possible
* solution could be Google Cloud Functions for Firebase).
* @param prevEventTimestamp Unix epoch time of the previous event
*/
private void addUpcomingEvent(long prevEventTimestamp) {
// Programmatically determine the host of the upcoming event by iterating through the list
// of registered users and comparing the epoch timestamps of their most recently hosted event.
// The lowest timestamp will determine the new host.
String nextHostUID = null;
long ll = 0;
for(DataSnapshot dataSnapshot : dsUsers.getChildren()) {
long ts = (long)dataSnapshot.child("zuletzt_gehostet").getValue();
if(ll == 0 || ts < ll) {
ll = ts;
nextHostUID = dataSnapshot.getKey();
}
}
// Calculate epoch timestamp of upcoming event
// It will take place exactly 1 week after the last event.
// 7 days * 24 hours * 60 minutes * 60 seconds = 604800
long nextEventTimestamp = prevEventTimestamp + 604800;
// Write to database
refEventDates.child(String.valueOf(nextEventTimestamp)).child("gastgeber").setValue(nextHostUID);
refUsers.child(nextHostUID).child("zuletzt_gehostet").setValue(nextEventTimestamp);
}
/** /**
* Displays a popup dialog with an text input field. The user is supposed to type in the title * Displays a popup dialog with an text input field. The user is supposed to type in the title
* of a game that he would like to add to the database. * of a game that he would like to add to the database.
@@ -167,90 +253,18 @@ public class HomeFragment extends Fragment {
spinnerGames.setAdapter(adapter); spinnerGames.setAdapter(adapter);
} }
private void setValues() { private void updateUI() {
// Get details of upcoming event from database
refEventDates.orderByKey().limitToLast(1).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
nextDateID = ds.getKey();
long epoch = Long.parseLong(nextDateID);
if(epoch < (System.currentTimeMillis() / 1000L)) {
addUpcomingEvent(epoch);
return;
}
Date date = new Date(epoch * 1000L);
String s = new SimpleDateFormat("dd. MMMM YYYY", Locale.getDefault()).format(date);
nextDate.setText(s);
String sNextHostUID = (String) ds.child("gastgeber").getValue();
String sNextHost = (String)dsUsers.child(sNextHostUID).child("nickname").getValue();
nextHost.setText(sNextHost + "'s place");
if(ds.hasChild("abstimmung_spiele")) {
games = new HashMap<>();
for(DataSnapshot dataSnapshot1 : ds.child("abstimmung_spiele").getChildren()) {
long curInt = (long)dataSnapshot1.getValue();
if(games.containsKey(curInt)) games.put(curInt, games.get(curInt)+1);
else games.put(curInt, 1);
}
}
}
updateGamesList();
setProgressBar(false);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Toast.makeText(getContext(), R.string.db_comm_err, Toast.LENGTH_SHORT).show();
}
});
userNickname = (String)dsUsers.child(mUser.getUid()).child("nickname").getValue(); userNickname = (String)dsUsers.child(mUser.getUid()).child("nickname").getValue();
String sWelcome = userNickname + getString(R.string.welcome_back); String sWelcome = userNickname + getString(R.string.welcome_back);
welcome.setText(sWelcome); welcome.setText(sWelcome);
} }
/**
* Determines the date and host of the next event and writes the details to the database.
* If this was a real life app and not just an example project, it would be advisable to handle
* event setup automatically with scheduled functions running on the server (a possible
* solution could be Google Cloud Functions for Firebase).
* @param prevEventTimestamp Unix epoch time of the previous event
*/
private void addUpcomingEvent(long prevEventTimestamp) {
// Programmatically determine the host of the upcoming event by iterating through the list
// of registered users and comparing the epoch timestamps of their most recently hosted event.
// The lowest timestamp will determine the new host.
String nextHostUID = null;
long ll = 0;
for(DataSnapshot dataSnapshot : dsUsers.getChildren()) {
long ts = (long)dataSnapshot.child("zuletzt_gehostet").getValue();
if(ll == 0 || ts < ll) {
ll = ts;
nextHostUID = dataSnapshot.getKey();
}
}
// Calculate epoch timestamp of upcoming event
// It will take place exactly 1 week after the last event.
// 7 days * 24 hours * 60 minutes * 60 seconds = 604800
long nextEventTimestamp = prevEventTimestamp + 604800;
// Write to database
refEventDates.child(String.valueOf(nextEventTimestamp)).child("gastgeber").setValue(nextHostUID);
}
/** /**
* Signs out the current Firebase user and switches to the login interface. * Signs out the current Firebase user and switches to the login interface.
*/ */
private void signOutUser() { private void signOutUser() {
FirebaseAuth.getInstance().signOut(); FirebaseAuth.getInstance().signOut();
startActivity(new Intent(getActivity(), LoginActivity.class)); startActivity(new Intent(getActivity(), LoginActivity.class));
Objects.requireNonNull(getActivity()).finish(); requireActivity().finish();
} }
} }

View File

@@ -1,240 +1,239 @@
package com.example.iubhgamerapp.ui; package com.example.iubhgamerapp.ui;
import android.os.Bundle; import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
import android.widget.RatingBar; import android.widget.RatingBar;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import com.example.iubhgamerapp.R; import com.example.iubhgamerapp.R;
import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser; import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot; import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError; import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference; import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase; import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener; import com.google.firebase.database.ValueEventListener;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
public class RateFragment extends Fragment { public class RatingFragment extends Fragment {
private EventDate selectedEvent; private EventDate selectedEvent;
private FirebaseUser mUser; private FirebaseUser mUser;
private DatabaseReference refUsers, refEvents; private DatabaseReference refUsers, refEvents;
private View root; private View root;
private List<EventDate> eventDates; private List<EventDate> eventDates;
private Map<String, String> users; private Map<String, String> users;
private Spinner spinnerPastEvents; private Spinner spinnerPastEvents;
private RatingBar rbOverall, rbFood, rbHost; private RatingBar rbOverall, rbFood, rbHost;
private TextView tvHost; private TextView tvHost;
private TextView tvOverallRatings, tvFoodRatings, tvHostRatings; private TextView tvOverallRatings, tvFoodRatings, tvHostRatings;
private Button btnRate;
public View onCreateView(@NonNull LayoutInflater inflater,
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ViewGroup container, Bundle savedInstanceState) { root = inflater.inflate(R.layout.fragment_rating, container, false);
root = inflater.inflate(R.layout.fragment_rate, container, false); spinnerPastEvents = root.findViewById(R.id.spinner_rating);
spinnerPastEvents = root.findViewById(R.id.spinner_rating); rbOverall = root.findViewById(R.id.ratingBar_overall);
rbOverall = root.findViewById(R.id.ratingBar_overall); rbFood = root.findViewById(R.id.ratingBar_food);
rbFood = root.findViewById(R.id.ratingBar_food); rbHost = root.findViewById(R.id.ratingBar_host);
rbHost = root.findViewById(R.id.ratingBar_host); tvHost = root.findViewById(R.id.textView_rateHost);
tvHost = root.findViewById(R.id.textView_rateHost); tvOverallRatings = root.findViewById(R.id.textView_rate1);
tvOverallRatings = root.findViewById(R.id.textView_rate1); tvFoodRatings = root.findViewById(R.id.textView_rate2);
tvFoodRatings = root.findViewById(R.id.textView_rate2); tvHostRatings = root.findViewById(R.id.textView_rate3);
tvHostRatings = root.findViewById(R.id.textView_rate3); Button btnRate = root.findViewById(R.id.rate);
btnRate = root.findViewById(R.id.rate);
// Set rate button listener
// Set rate button listener btnRate.setOnClickListener(v -> ratePastEvent());
btnRate.setOnClickListener(v -> ratePastEvent());
// Set spinner listener
// Set spinner listener spinnerPastEvents.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
spinnerPastEvents.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override
@Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { selectedEvent = eventDates.get(position);
selectedEvent = eventDates.get(position);
rbOverall.setRating(selectedEvent.ownOverallRating);
rbOverall.setRating(selectedEvent.ownOverallRating); rbFood.setRating(selectedEvent.ownFoodRating);
rbFood.setRating(selectedEvent.ownFoodRating); rbHost.setRating(selectedEvent.ownHostRating);
rbHost.setRating(selectedEvent.ownHostRating);
tvHost.setText("Host (" + selectedEvent.hostName + ")");
tvHost.setText("Host (" + selectedEvent.hostName + ")");
String sNoRatings = getString(R.string.zero_ratings);
String sNoRatings = getString(R.string.zero_ratings);
String str1 = getString(R.string.other_ratings, selectedEvent.avgOverallRating, selectedEvent.overallRatingsCount);
String str1 = getString(R.string.other_ratings, selectedEvent.avgOverallRating, selectedEvent.overallRatingsCount); tvOverallRatings.setText(selectedEvent.overallRatingsCount > 0 ? str1 : sNoRatings);
tvOverallRatings.setText(selectedEvent.overallRatingsCount > 0 ? str1 : sNoRatings);
String str2 = getString(R.string.other_ratings, selectedEvent.avgFoodRating, selectedEvent.foodRatingsCount);
String str2 = getString(R.string.other_ratings, selectedEvent.avgFoodRating, selectedEvent.foodRatingsCount); tvFoodRatings.setText(selectedEvent.foodRatingsCount > 0 ? str2 : sNoRatings);
tvFoodRatings.setText(selectedEvent.foodRatingsCount > 0 ? str2 : sNoRatings);
String str3 = getString(R.string.other_ratings, selectedEvent.avgHostRating, selectedEvent.hostRatingsCount);
String str3 = getString(R.string.other_ratings, selectedEvent.avgHostRating, selectedEvent.hostRatingsCount); tvHostRatings.setText(selectedEvent.hostRatingsCount > 0 ? str3 : sNoRatings);
tvHostRatings.setText(selectedEvent.hostRatingsCount > 0 ? str3 : sNoRatings); }
}
@Override
@Override public void onNothingSelected(AdapterView<?> parent) {
public void onNothingSelected(AdapterView<?> parent) { // Nothing to do here
// Nothing to do here }
} });
});
// Connect to Firebase realtime database
// Connect to Firebase realtime database mUser = FirebaseAuth.getInstance().getCurrentUser();
mUser = FirebaseAuth.getInstance().getCurrentUser(); refUsers = FirebaseDatabase.getInstance().getReference().child("spieler");
refUsers = FirebaseDatabase.getInstance().getReference().child("spieler"); refEvents = FirebaseDatabase.getInstance().getReference().child("termine");
refEvents = FirebaseDatabase.getInstance().getReference().child("termine");
// Get list of registered users from Firebase database
// Get list of registered users from Firebase database refUsers.addValueEventListener(new ValueEventListener() {
refUsers.addValueEventListener(new ValueEventListener() { @Override
@Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
public void onDataChange(@NonNull DataSnapshot dataSnapshot) { // Save users in HashMap object (key = UID; value = nickname)
// Save users in HashMap object (key = UID; value = nickname) users = new HashMap<>();
users = new HashMap<>(); for(DataSnapshot ds : dataSnapshot.getChildren()) {
for(DataSnapshot ds : dataSnapshot.getChildren()) { users.put(ds.getKey(), (String)ds.child("nickname").getValue());
users.put(ds.getKey(), (String)ds.child("nickname").getValue()); }
}
getPastEvents();
getPastEvents(); }
}
@Override
@Override public void onCancelled(@NonNull DatabaseError databaseError) {
public void onCancelled(@NonNull DatabaseError databaseError) { Toast.makeText(getContext(), R.string.db_comm_err, Toast.LENGTH_SHORT).show();
Toast.makeText(getContext(), R.string.db_comm_err, Toast.LENGTH_SHORT).show(); }
} });
});
return root;
return root; }
}
/**
/** * Writes the user's rating of the selected event to database.
* Writes the user's rating of the selected event to database. */
*/ private void ratePastEvent() {
private void ratePastEvent() { long ownOverallRating = (long)rbOverall.getRating();
long ownOverallRating = (long)rbOverall.getRating(); long ownFoodRating = (long)rbFood.getRating();
long ownFoodRating = (long)rbFood.getRating(); long ownHostRating = (long)rbHost.getRating();
long ownHostRating = (long)rbHost.getRating();
// Write ratings to database IF the user rated every required item
// Write ratings to database IF the user rated every required item if(ownOverallRating > 0 && ownFoodRating > 0 && ownHostRating > 0) {
if(ownOverallRating > 0 && ownFoodRating > 0 && ownHostRating > 0) { DatabaseReference refRatings = refEvents.child(String.valueOf(selectedEvent.epochTimestamp)).child("bewertungen");
DatabaseReference refRatings = refEvents.child(String.valueOf(selectedEvent.epochTimestamp)).child("bewertungen"); refRatings.child("allgemein").child(mUser.getUid()).setValue(ownOverallRating);
refRatings.child("allgemein").child(mUser.getUid()).setValue(ownOverallRating); refRatings.child("essen").child(mUser.getUid()).setValue(ownFoodRating);
refRatings.child("essen").child(mUser.getUid()).setValue(ownFoodRating); refRatings.child("gastgeber").child(mUser.getUid()).setValue(ownHostRating);
refRatings.child("gastgeber").child(mUser.getUid()).setValue(ownHostRating); }
} // Otherwise, display error message
// Otherwise, display error message else {
else { Toast.makeText(getContext(), R.string.rate_error, Toast.LENGTH_SHORT).show();
Toast.makeText(getContext(), R.string.rate_error, Toast.LENGTH_SHORT).show(); }
} }
}
/**
/** * Reads the most recent events from the database. The user can rate the overall experience,
* Reads the most recent events from the database. The user can rate the overall experience, * food & drinks as well as the event host.
* food & drinks as well as the event host. * Only the last 3 events can be rated.
* Only the last 3 events can be rated. */
*/ private void getPastEvents() {
private void getPastEvents() { refEvents.orderByKey().limitToLast(4).addValueEventListener(new ValueEventListener() {
refEvents.orderByKey().limitToLast(4).addValueEventListener(new ValueEventListener() { @Override
@Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
public void onDataChange(@NonNull DataSnapshot dataSnapshot) { // Iterate through events to extract metadata
// Iterate through events to extract metadata eventDates = new ArrayList<>();
eventDates = new ArrayList<>(); for(DataSnapshot ds : dataSnapshot.getChildren()) {
for(DataSnapshot ds : dataSnapshot.getChildren()) { // Check if the event date is actually in the future.
// Check if the event date is actually in the future. // Skip it, as only past events are unlocked for rating.
// Skip it, as only past events are unlocked for rating. long epochTimestamp = Long.parseLong(ds.getKey());
long epochTimestamp = Long.parseLong(ds.getKey()); if(epochTimestamp > (System.currentTimeMillis() / 1000L)) break;
if(epochTimestamp > (System.currentTimeMillis() / 1000L)) break;
// Extract event host user id
// Extract event host user id String hostUID = (String)ds.child("gastgeber").getValue();
String hostUID = (String)ds.child("gastgeber").getValue();
// Extract individual rating data
// Extract individual rating data Map<String, Long> overallRatings = new HashMap<>();
Map<String, Long> overallRatings = new HashMap<>(); Map<String, Long> foodRatings = new HashMap<>();
Map<String, Long> foodRatings = new HashMap<>(); Map<String, Long> hostRatings = new HashMap<>();
Map<String, Long> hostRatings = new HashMap<>(); for(DataSnapshot dsOverallRatings : ds.child("bewertungen").child("allgemein").getChildren()) {
for(DataSnapshot dsOverallRatings : ds.child("bewertungen").child("allgemein").getChildren()) { overallRatings.put(dsOverallRatings.getKey(), (long)dsOverallRatings.getValue());
overallRatings.put(dsOverallRatings.getKey(), (long)dsOverallRatings.getValue()); }
} for(DataSnapshot dsFoodRatings : ds.child("bewertungen").child("essen").getChildren()) {
for(DataSnapshot dsFoodRatings : ds.child("bewertungen").child("essen").getChildren()) { foodRatings.put(dsFoodRatings.getKey(), (long)dsFoodRatings.getValue());
foodRatings.put(dsFoodRatings.getKey(), (long)dsFoodRatings.getValue()); }
} for(DataSnapshot dsHostRatings : ds.child("bewertungen").child("gastgeber").getChildren()) {
for(DataSnapshot dsHostRatings : ds.child("bewertungen").child("gastgeber").getChildren()) { hostRatings.put(dsHostRatings.getKey(), (long)dsHostRatings.getValue());
hostRatings.put(dsHostRatings.getKey(), (long)dsHostRatings.getValue()); }
}
// Add event to ArrayList to make data available to other methods
// Add event to ArrayList to make data available to other methods eventDates.add(new EventDate(epochTimestamp, hostUID, overallRatings, foodRatings, hostRatings));
eventDates.add(new EventDate(epochTimestamp, hostUID, overallRatings, foodRatings, hostRatings)); }
}
// Update spinner; set selection to most recent event
// Update spinner; set selection to most recent event List<String> spinnerEntries = new ArrayList<>();
List<String> spinnerEntries = new ArrayList<>(); for(int i = 0; i < eventDates.size(); i++) spinnerEntries.add(eventDates.get(i).getFormattedDate());
for(int i = 0; i < eventDates.size(); i++) spinnerEntries.add(eventDates.get(i).getFormattedDate()); ArrayAdapter<String> adapter = new ArrayAdapter<>(root.getContext(),
ArrayAdapter<String> adapter = new ArrayAdapter<>(root.getContext(), android.R.layout.simple_spinner_item, spinnerEntries);
android.R.layout.simple_spinner_item, spinnerEntries); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinnerPastEvents.setAdapter(adapter);
spinnerPastEvents.setAdapter(adapter); spinnerPastEvents.setSelection(adapter.getCount() - 1);
spinnerPastEvents.setSelection(adapter.getCount() - 1); }
}
@Override
@Override public void onCancelled(@NonNull DatabaseError databaseError) {
public void onCancelled(@NonNull DatabaseError databaseError) { Toast.makeText(getContext(), R.string.db_comm_err, Toast.LENGTH_SHORT).show();
Toast.makeText(getContext(), R.string.db_comm_err, Toast.LENGTH_SHORT).show(); }
} });
}); }
}
class EventDate {
class EventDate { final long epochTimestamp;
final long epochTimestamp; final long ownOverallRating, ownFoodRating, ownHostRating;
final long ownOverallRating, ownFoodRating, ownHostRating; final int overallRatingsCount, foodRatingsCount, hostRatingsCount;
final int overallRatingsCount, foodRatingsCount, hostRatingsCount; final long avgOverallRating, avgFoodRating, avgHostRating;
final long avgOverallRating, avgFoodRating, avgHostRating; final String hostName;
final String hostName;
EventDate(long epochTimestamp, String hostUID, Map<String, Long> overallRatings, Map<String, Long> foodRatings, Map<String, Long> hostRatings) {
EventDate(long epochTimestamp, String hostUID, Map<String, Long> overallRatings, Map<String, Long> foodRatings, Map<String, Long> hostRatings) { final String ownUID = mUser.getUid();
final String ownUID = mUser.getUid(); this.epochTimestamp = epochTimestamp;
this.epochTimestamp = epochTimestamp; this.hostName = users.get(hostUID);
this.hostName = users.get(hostUID);
this.overallRatingsCount = overallRatings.size();
this.overallRatingsCount = overallRatings.size(); this.foodRatingsCount = foodRatings.size();
this.foodRatingsCount = foodRatings.size(); this.hostRatingsCount = hostRatings.size();
this.hostRatingsCount = hostRatings.size();
if(overallRatings.containsKey(ownUID)) ownOverallRating = overallRatings.get(ownUID);
if(overallRatings.containsKey(ownUID)) ownOverallRating = overallRatings.get(ownUID); else ownOverallRating = 0;
else ownOverallRating = 0;
if(foodRatings.containsKey(ownUID)) ownFoodRating = foodRatings.get(ownUID);
if(foodRatings.containsKey(ownUID)) ownFoodRating = foodRatings.get(ownUID); else ownFoodRating = 0;
else ownFoodRating = 0;
if(hostRatings.containsKey(ownUID)) ownHostRating = hostRatings.get(ownUID);
if(hostRatings.containsKey(ownUID)) ownHostRating = hostRatings.get(ownUID); else ownHostRating = 0;
else ownHostRating = 0;
long temp = 0;
long temp = 0; for(Map.Entry<String, Long> entry : overallRatings.entrySet()) temp += entry.getValue();
for(Map.Entry<String, Long> entry : overallRatings.entrySet()) temp += entry.getValue(); avgOverallRating = overallRatingsCount > 0 ? temp / overallRatingsCount : 0;
avgOverallRating = overallRatingsCount > 0 ? temp / overallRatingsCount : 0;
temp = 0;
temp = 0; for(Map.Entry<String, Long> entry : foodRatings.entrySet()) temp += entry.getValue();
for(Map.Entry<String, Long> entry : foodRatings.entrySet()) temp += entry.getValue(); avgFoodRating = foodRatingsCount > 0 ? temp / foodRatingsCount : 0;
avgFoodRating = foodRatingsCount > 0 ? temp / foodRatingsCount : 0;
temp = 0;
temp = 0; for(Map.Entry<String, Long> entry : hostRatings.entrySet()) temp += entry.getValue();
for(Map.Entry<String, Long> entry : hostRatings.entrySet()) temp += entry.getValue(); avgHostRating = hostRatingsCount > 0 ? temp / hostRatingsCount : 0;
avgHostRating = hostRatingsCount > 0 ? temp / hostRatingsCount : 0; }
}
String getFormattedDate() {
String getFormattedDate() { Date date = new Date(this.epochTimestamp * 1000L);
Date date = new Date(this.epochTimestamp * 1000L); return new SimpleDateFormat("EEEE, dd. MMMM yyyy", Locale.getDefault()).format(date);
return new SimpleDateFormat("EEEE, dd. MMMM YYYY", Locale.getDefault()).format(date); }
} }
}
} }

View File

@@ -67,7 +67,7 @@
android:id="@+id/text_home4" android:id="@+id/text_home4"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="The next event will be held on" android:text="The next event will be on"
android:textAlignment="center" android:textAlignment="center"
android:textSize="14sp" /> android:textSize="14sp" />
@@ -84,7 +84,7 @@
android:id="@+id/text_home3" android:id="@+id/text_home3"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="at" android:text="hosted by"
android:textAlignment="center" android:textAlignment="center"
android:textSize="14sp" /> android:textSize="14sp" />

View File

@@ -1,134 +1,134 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:id="@+id/cardView4" android:id="@+id/cardView4"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="24dp" android:layout_marginStart="24dp"
android:layout_marginLeft="24dp" android:layout_marginLeft="24dp"
android:layout_marginTop="24dp" android:layout_marginTop="24dp"
android:layout_marginEnd="24dp" android:layout_marginEnd="24dp"
android:layout_marginRight="24dp" android:layout_marginRight="24dp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"> app:layout_constraintTop_toTopOf="parent">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:layout_marginRight="8dp" android:layout_marginRight="8dp"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:gravity="center" android:gravity="center"
android:orientation="vertical"> android:orientation="vertical">
<TextView <TextView
android:id="@+id/textView" android:id="@+id/textView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Select past event" /> android:text="Select past event" />
<Spinner <Spinner
android:id="@+id/spinner_rating" android:id="@+id/spinner_rating"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"/> android:layout_marginBottom="8dp"/>
<View <View
android:id="@+id/divider4" android:id="@+id/divider4"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="8dp" android:layout_height="8dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:background="?android:attr/listDivider" /> android:background="?android:attr/listDivider" />
<TextView <TextView
android:id="@+id/textView2" android:id="@+id/textView2"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Overall" /> android:text="Overall" />
<RatingBar <RatingBar
android:id="@+id/ratingBar_overall" android:id="@+id/ratingBar_overall"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:numStars="5" android:numStars="5"
android:stepSize="1" /> android:stepSize="1" />
<TextView <TextView
android:id="@+id/textView_rate1" android:id="@+id/textView_rate1"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
<View <View
android:id="@+id/divider2" android:id="@+id/divider2"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="8dp" android:layout_height="8dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:background="?android:attr/listDivider" /> android:background="?android:attr/listDivider" />
<TextView <TextView
android:id="@+id/textView3" android:id="@+id/textView3"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Food and Drinks" /> android:text="Food and Drinks" />
<RatingBar <RatingBar
android:id="@+id/ratingBar_food" android:id="@+id/ratingBar_food"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:numStars="5" android:numStars="5"
android:stepSize="1" /> android:stepSize="1" />
<TextView <TextView
android:id="@+id/textView_rate2" android:id="@+id/textView_rate2"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
<View <View
android:id="@+id/divider3" android:id="@+id/divider3"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="8dp" android:layout_height="8dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:background="?android:attr/listDivider" /> android:background="?android:attr/listDivider" />
<TextView <TextView
android:id="@+id/textView_rateHost" android:id="@+id/textView_rateHost"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
<RatingBar <RatingBar
android:id="@+id/ratingBar_host" android:id="@+id/ratingBar_host"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:numStars="5" android:numStars="5"
android:stepSize="1" /> android:stepSize="1" />
<TextView <TextView
android:id="@+id/textView_rate3" android:id="@+id/textView_rate3"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
<Button <Button
android:id="@+id/rate" android:id="@+id/rate"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="24dp" android:layout_marginTop="24dp"
android:text="@string/title_rate" /> android:text="@string/title_rate" />
</LinearLayout> </LinearLayout>
</androidx.cardview.widget.CardView> </androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -13,9 +13,9 @@
<fragment <fragment
android:id="@+id/navigation_rate" android:id="@+id/navigation_rate"
android:name="com.example.iubhgamerapp.ui.RateFragment" android:name="com.example.iubhgamerapp.ui.RatingFragment"
android:label="@string/title_rate" android:label="@string/title_rate"
tools:layout="@layout/fragment_rate" /> tools:layout="@layout/fragment_rating" />
<fragment <fragment
android:id="@+id/navigation_chat" android:id="@+id/navigation_chat"