Skip to content

Commit 5c982b7

Browse files
committedJul 12, 2021
Added Missing Words Fragments
1 parent 71d5c99 commit 5c982b7

29 files changed

+975
-282
lines changed
 

‎.DS_Store

0 Bytes
Binary file not shown.

‎AdminApp/.DS_Store

-2 KB
Binary file not shown.

‎AdminApp/app/.DS_Store

0 Bytes
Binary file not shown.

‎AdminApp/app/release/app-release.apk

525 KB
Binary file not shown.

‎AdminApp/app/src/.DS_Store

0 Bytes
Binary file not shown.

‎AdminApp/app/src/main/.DS_Store

0 Bytes
Binary file not shown.

‎AdminApp/app/src/main/java/com/yashkasera/livstoryuploaddata/MainActivity.java

+119-155
Large diffs are not rendered by default.

‎AdminApp/app/src/main/java/com/yashkasera/livstoryuploaddata/UploadDataActivity.java

+22-1
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@
2424
import com.google.android.material.textfield.TextInputLayout;
2525
import com.google.firebase.auth.FirebaseAuth;
2626
import com.google.firebase.auth.FirebaseUser;
27+
import com.google.firebase.firestore.FieldValue;
2728
import com.google.firebase.firestore.FirebaseFirestore;
28-
import com.yashkasera.livstoryuploaddata.R;
29+
import com.yashkasera.livstoryuploaddata.model.WordModel;
2930

3031
import java.io.ByteArrayOutputStream;
3132
import java.io.File;
@@ -51,6 +52,7 @@ public class UploadDataActivity extends AppCompatActivity {
5152
String[] keyword;
5253
ProgressDialog progressDialog;
5354
private FirebaseAuth mAuth;
55+
private WordModel wordModel;
5456

5557
public static String bytesToHex(byte[] in) {
5658
final StringBuilder builder = new StringBuilder();
@@ -75,6 +77,9 @@ protected void onCreate(Bundle savedInstanceState) {
7577
name = findViewById(R.id.name);
7678
progressDialog = new ProgressDialog(context);
7779
progressDialog.setMessage("Loading");
80+
wordModel = (WordModel) getIntent().getSerializableExtra("word");
81+
if (wordModel != null)
82+
keywords.setText(wordModel.getWord());
7883
db = FirebaseFirestore.getInstance();
7984
if (context.getPackageManager().checkPermission(Manifest.permission.READ_EXTERNAL_STORAGE,
8085
context.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
@@ -154,6 +159,22 @@ public void onStopTrackingTouch(SeekBar seekBar) {
154159
keywords1.setError(null);
155160
type1.setError(null);
156161
uri = null;
162+
if (wordModel != null) {
163+
db.collection("report")
164+
.document(getIntent().getStringExtra("from"))
165+
.update(wordModel.getWord(), FieldValue.delete())
166+
.addOnCompleteListener(task1 -> {
167+
if (task1.isSuccessful()) {
168+
Toast.makeText(context, "Keyword added successfully!", Toast.LENGTH_SHORT).show();
169+
if (getIntent().getStringExtra("from").equalsIgnoreCase("model"))
170+
MainActivity.modelWordModelArrayList.remove(wordModel);
171+
else if (getIntent().getStringExtra("from").equalsIgnoreCase("user"))
172+
MainActivity.userWordModelArrayList.remove(wordModel);
173+
setResult(1, getIntent());
174+
finish();
175+
}
176+
});
177+
}
157178
} else {
158179
Toast.makeText(context, "File could not be uploaded!", Toast.LENGTH_SHORT).show();
159180
progressDialog.dismiss();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.yashkasera.livstoryuploaddata;
2+
3+
4+
import androidx.annotation.NonNull;
5+
import androidx.fragment.app.Fragment;
6+
import androidx.fragment.app.FragmentManager;
7+
import androidx.fragment.app.FragmentPagerAdapter;
8+
9+
import com.yashkasera.livstoryuploaddata.fragment.ModelMissingWords;
10+
import com.yashkasera.livstoryuploaddata.fragment.PlayAudioFragment;
11+
import com.yashkasera.livstoryuploaddata.fragment.UserMissingWords;
12+
13+
public class ViewPagerAdapter extends FragmentPagerAdapter {
14+
15+
16+
public ViewPagerAdapter(@NonNull FragmentManager fm) {
17+
super(fm);
18+
}
19+
20+
@NonNull
21+
@Override
22+
public Fragment getItem(int position) {
23+
if (position == 0)
24+
return new PlayAudioFragment();
25+
else if (position == 1)
26+
return new ModelMissingWords();
27+
else
28+
return new UserMissingWords();
29+
}
30+
31+
@Override
32+
public int getCount() {
33+
return 3;
34+
}
35+
36+
@Override
37+
public CharSequence getPageTitle(int position) {
38+
if (position == 0)
39+
return "Audio";
40+
else if (position == 1)
41+
return "Model";
42+
else
43+
return "User";
44+
}
45+
46+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package com.yashkasera.livstoryuploaddata.adapter;
2+
3+
import android.content.Context;
4+
import android.content.Intent;
5+
import android.view.LayoutInflater;
6+
import android.view.View;
7+
import android.view.ViewGroup;
8+
import android.widget.ProgressBar;
9+
import android.widget.TextView;
10+
11+
import androidx.annotation.NonNull;
12+
import androidx.recyclerview.widget.RecyclerView;
13+
14+
import com.google.android.material.chip.Chip;
15+
import com.yashkasera.livstoryuploaddata.R;
16+
import com.yashkasera.livstoryuploaddata.UploadDataActivity;
17+
import com.yashkasera.livstoryuploaddata.model.WordModel;
18+
19+
import org.jetbrains.annotations.NotNull;
20+
21+
import java.util.ArrayList;
22+
23+
public class MissingWordRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
24+
private final int VIEW_TYPE_ITEM = 0;
25+
private final int VIEW_TYPE_LOADING = 1;
26+
Context context;
27+
ArrayList<WordModel> list;
28+
29+
public MissingWordRecyclerAdapter(Context context, ArrayList<WordModel> map) {
30+
this.context = context;
31+
this.list = map;
32+
}
33+
34+
@NonNull
35+
@NotNull
36+
@Override
37+
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) {
38+
if (viewType == VIEW_TYPE_ITEM)
39+
return new ItemViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_word, parent, false));
40+
else
41+
return new LoadingViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_loading, parent, false));
42+
43+
}
44+
45+
@Override
46+
public void onBindViewHolder(@NonNull @NotNull RecyclerView.ViewHolder holder, int position) {
47+
if (holder instanceof ItemViewHolder)
48+
populateItemRows((ItemViewHolder) holder, position);
49+
}
50+
51+
private void populateItemRows(ItemViewHolder holder, int position) {
52+
holder.word.setText(list.get(position).getWord());
53+
holder.count.setText(String.valueOf(list.get(position).getCount()));
54+
}
55+
56+
@Override
57+
public int getItemCount() {
58+
return list.size();
59+
}
60+
61+
public void setList(ArrayList<WordModel> list) {
62+
this.list = list;
63+
notifyDataSetChanged();
64+
}
65+
66+
private static class LoadingViewHolder extends RecyclerView.ViewHolder {
67+
public ProgressBar progressBar;
68+
69+
public LoadingViewHolder(@NonNull View itemView) {
70+
super(itemView);
71+
progressBar = itemView.findViewById(R.id.progressBar);
72+
}
73+
}
74+
75+
public class ItemViewHolder extends RecyclerView.ViewHolder {
76+
public TextView word;
77+
public Chip count;
78+
public View mView;
79+
80+
public ItemViewHolder(@NonNull @NotNull View itemView) {
81+
super(itemView);
82+
mView = itemView;
83+
word = itemView.findViewById(R.id.word);
84+
count = itemView.findViewById(R.id.count);
85+
}
86+
}
87+
}

‎AdminApp/app/src/main/java/com/yashkasera/livstoryuploaddata/adapter/RecyclerAdapter.java

-85
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
package com.yashkasera.livstoryuploaddata.adapter;
2+
3+
import android.content.Context;
4+
import android.content.res.ColorStateList;
5+
import android.view.LayoutInflater;
6+
import android.view.View;
7+
import android.view.ViewGroup;
8+
import android.widget.ProgressBar;
9+
import android.widget.TextView;
10+
11+
import androidx.annotation.NonNull;
12+
import androidx.core.content.ContextCompat;
13+
import androidx.recyclerview.widget.RecyclerView;
14+
15+
import com.google.android.material.chip.Chip;
16+
import com.google.android.material.chip.ChipGroup;
17+
import com.yashkasera.livstoryuploaddata.R;
18+
import com.yashkasera.livstoryuploaddata.model.SoundModel;
19+
20+
import org.jetbrains.annotations.NotNull;
21+
22+
import java.util.ArrayList;
23+
24+
import static com.yashkasera.livstoryuploaddata.MainActivity.soundModelArrayList;
25+
26+
public class SoundRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
27+
28+
private final Context context;
29+
private final int VIEW_TYPE_ITEM = 0;
30+
private final int VIEW_TYPE_LOADING = 1;
31+
32+
public SoundRecyclerAdapter(Context context) {
33+
this.context = context;
34+
}
35+
36+
@NonNull
37+
@NotNull
38+
@Override
39+
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) {
40+
View view;
41+
if (viewType == VIEW_TYPE_ITEM) {
42+
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_sound, parent, false);
43+
return new ItemViewHolder(view);
44+
} else {
45+
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_loading, parent, false);
46+
return new LoadingViewHolder(view);
47+
}
48+
}
49+
50+
@Override
51+
public void onBindViewHolder(@NonNull @NotNull RecyclerView.ViewHolder holder, int position) {
52+
if (holder instanceof ItemViewHolder)
53+
populateItemRows((ItemViewHolder) holder, position);
54+
}
55+
56+
private void populateItemRows(ItemViewHolder holder, int position) {
57+
holder.textView.setText(soundModelArrayList.get(position).getType());
58+
holder.chipGroup.removeAllViews();
59+
for (String keyword : soundModelArrayList.get(position).getKeywords()) {
60+
Chip chip = new Chip(context);
61+
chip.setText(keyword);
62+
chip.setTextColor(ColorStateList.valueOf(ContextCompat.getColor(context,
63+
R.color.colorAccent)));
64+
chip.setChipBackgroundColor(ColorStateList.valueOf(ContextCompat.getColor(context,
65+
R.color.chipBackgroundColor)));
66+
chip.setChipStrokeColor(ColorStateList.valueOf(ContextCompat.getColor(context,
67+
R.color.colorAccent)));
68+
chip.setTextStartPaddingResource(R.dimen.margin_medium);
69+
chip.setTextEndPaddingResource(R.dimen.margin_medium);
70+
chip.setChipStrokeWidthResource(R.dimen.strokeWidth);
71+
holder.chipGroup.addView(chip);
72+
}
73+
}
74+
75+
@Override
76+
public int getItemViewType(int position) {
77+
if (soundModelArrayList.get(position) == null)
78+
return VIEW_TYPE_LOADING;
79+
else
80+
return soundModelArrayList.get(position) == null ? VIEW_TYPE_LOADING : VIEW_TYPE_ITEM;
81+
}
82+
83+
@Override
84+
public int getItemCount() {
85+
return soundModelArrayList.size();
86+
}
87+
88+
public void addItem(SoundModel soundModel) {
89+
soundModelArrayList.add(soundModel);
90+
notifyItemInserted(soundModelArrayList.size() - 1);
91+
}
92+
93+
public void removeItem(SoundModel soundModel) {
94+
int position = soundModelArrayList.indexOf(soundModel);
95+
soundModelArrayList.remove(soundModel);
96+
notifyItemRemoved(position);
97+
}
98+
99+
private static class ItemViewHolder extends RecyclerView.ViewHolder {
100+
public final TextView textView;
101+
public final ChipGroup chipGroup;
102+
public final ProgressBar progressBar;
103+
public final View mView;
104+
105+
public ItemViewHolder(@NonNull @NotNull View itemView) {
106+
super(itemView);
107+
mView = itemView;
108+
textView = itemView.findViewById(R.id.textView);
109+
chipGroup = itemView.findViewById(R.id.chipGroup);
110+
progressBar = itemView.findViewById(R.id.progressBar);
111+
}
112+
}
113+
114+
private static class LoadingViewHolder extends RecyclerView.ViewHolder {
115+
public ProgressBar progressBar;
116+
117+
public LoadingViewHolder(@NonNull View itemView) {
118+
super(itemView);
119+
progressBar = itemView.findViewById(R.id.progressBar);
120+
}
121+
}
122+
123+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package com.yashkasera.livstoryuploaddata.fragment;
2+
3+
import android.content.Context;
4+
import android.content.Intent;
5+
import android.os.Build;
6+
import android.os.Bundle;
7+
import android.util.Log;
8+
import android.view.LayoutInflater;
9+
import android.view.View;
10+
import android.view.ViewGroup;
11+
import android.widget.Toast;
12+
13+
import androidx.annotation.NonNull;
14+
import androidx.annotation.Nullable;
15+
import androidx.fragment.app.Fragment;
16+
import androidx.recyclerview.widget.DividerItemDecoration;
17+
import androidx.recyclerview.widget.LinearLayoutManager;
18+
import androidx.recyclerview.widget.RecyclerView;
19+
20+
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
21+
import com.google.firebase.firestore.FieldValue;
22+
import com.google.firebase.firestore.FirebaseFirestore;
23+
import com.yashkasera.livstoryuploaddata.R;
24+
import com.yashkasera.livstoryuploaddata.UploadDataActivity;
25+
import com.yashkasera.livstoryuploaddata.adapter.MissingWordRecyclerAdapter;
26+
import com.yashkasera.livstoryuploaddata.model.WordModel;
27+
import com.yashkasera.livstoryuploaddata.util.ClickListener;
28+
import com.yashkasera.livstoryuploaddata.util.RecyclerTouchListener;
29+
30+
import org.jetbrains.annotations.NotNull;
31+
32+
import java.util.ArrayList;
33+
import java.util.Map;
34+
35+
import static com.yashkasera.livstoryuploaddata.MainActivity.modelWordModelArrayList;
36+
37+
public class ModelMissingWords extends Fragment {
38+
private static final String TAG = "ModelMissingWords";
39+
private FirebaseFirestore db = FirebaseFirestore.getInstance();
40+
private MissingWordRecyclerAdapter adapter;
41+
private Context context;
42+
43+
public ModelMissingWords() {
44+
}
45+
46+
@Nullable
47+
@org.jetbrains.annotations.Nullable
48+
@Override
49+
public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
50+
context = requireContext();
51+
return inflater.inflate(R.layout.fragment_recycler_view, container, false);
52+
}
53+
54+
@Override
55+
public void onActivityResult(int requestCode, int resultCode, @Nullable @org.jetbrains.annotations.Nullable Intent data) {
56+
super.onActivityResult(requestCode, resultCode, data);
57+
if (requestCode == 1001 && resultCode == 1) {
58+
if (data != null) {
59+
modelWordModelArrayList.remove(data.getIntExtra("position", -1));
60+
adapter.notifyItemRemoved(data.getIntExtra("position", -1));
61+
}
62+
}
63+
}
64+
65+
@Override
66+
public void onViewCreated(@NonNull @NotNull View view, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
67+
super.onViewCreated(view, savedInstanceState);
68+
RecyclerView recyclerView = view.findViewById(R.id.recyclerView);
69+
recyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
70+
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(requireContext(), DividerItemDecoration.VERTICAL);
71+
recyclerView.addItemDecoration(dividerItemDecoration);
72+
adapter = new MissingWordRecyclerAdapter(requireContext(), new ArrayList<>());
73+
recyclerView.setAdapter(adapter);
74+
if (modelWordModelArrayList.size() != 0) {
75+
adapter.setList(modelWordModelArrayList);
76+
} else {
77+
db.collection("report")
78+
.document("model")
79+
.get()
80+
.addOnCompleteListener(task -> {
81+
if (task.isSuccessful()) {
82+
ArrayList<WordModel> list = new ArrayList<>();
83+
for (Map.Entry<String, Object> entry : task.getResult().getData().entrySet())
84+
list.add(new WordModel(entry.getKey(), (long) entry.getValue()));
85+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
86+
list.sort((o1, o2) -> o1.getCount() >= o2.getCount() ? -1 : 1);
87+
modelWordModelArrayList.addAll(list);
88+
adapter.setList(modelWordModelArrayList);
89+
} else
90+
Log.d(TAG, "onComplete() returned: " + task.getException());
91+
});
92+
}
93+
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(context, recyclerView, new ClickListener() {
94+
@Override
95+
public void onClick(View view, int position) {
96+
Intent intent = new Intent(context, UploadDataActivity.class);
97+
intent.putExtra("word", modelWordModelArrayList.get(position));
98+
intent.putExtra("from", "model");
99+
intent.putExtra("position", position);
100+
startActivityForResult(intent, 1001);
101+
}
102+
103+
@Override
104+
public void onLongClick(View view, int position) {
105+
if (modelWordModelArrayList.get(position) != null)
106+
new MaterialAlertDialogBuilder(context)
107+
.setTitle("Confirm Delete")
108+
.setMessage("Are you sure you want to delete this sound? This action cannot be undone.")
109+
.setPositiveButton("Delete", (dialog, which) -> db.collection("report")
110+
.document("model")
111+
.update(modelWordModelArrayList.get(position).getWord(), FieldValue.delete())
112+
.addOnCompleteListener(task -> {
113+
if (task.isSuccessful()) {
114+
Toast.makeText(context, "Suggestion deleted Successfully!", Toast.LENGTH_SHORT).show();
115+
adapter.notifyItemRemoved(position);
116+
modelWordModelArrayList.remove(position);
117+
} else {
118+
Toast.makeText(context, "Could not delete sound! Please try again later", Toast.LENGTH_SHORT).show();
119+
}
120+
121+
}))
122+
.setNegativeButton("Cancel", (dialog, which) -> dialog.dismiss())
123+
.show();
124+
}
125+
}));
126+
127+
}
128+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
package com.yashkasera.livstoryuploaddata.fragment;
2+
3+
import android.content.Context;
4+
import android.os.Bundle;
5+
import android.util.Log;
6+
import android.view.LayoutInflater;
7+
import android.view.View;
8+
import android.view.ViewGroup;
9+
import android.widget.AbsListView;
10+
import android.widget.Toast;
11+
12+
import androidx.annotation.NonNull;
13+
import androidx.annotation.Nullable;
14+
import androidx.fragment.app.Fragment;
15+
import androidx.recyclerview.widget.DividerItemDecoration;
16+
import androidx.recyclerview.widget.LinearLayoutManager;
17+
import androidx.recyclerview.widget.RecyclerView;
18+
19+
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
20+
import com.google.android.material.snackbar.BaseTransientBottomBar;
21+
import com.google.android.material.snackbar.Snackbar;
22+
import com.google.firebase.firestore.DocumentSnapshot;
23+
import com.google.firebase.firestore.FirebaseFirestore;
24+
import com.google.firebase.firestore.QueryDocumentSnapshot;
25+
import com.yashkasera.livstoryuploaddata.R;
26+
import com.yashkasera.livstoryuploaddata.adapter.SoundRecyclerAdapter;
27+
import com.yashkasera.livstoryuploaddata.model.SoundModel;
28+
import com.yashkasera.livstoryuploaddata.util.ClickListener;
29+
import com.yashkasera.livstoryuploaddata.util.RecyclerTouchListener;
30+
31+
import org.jetbrains.annotations.NotNull;
32+
33+
import java.util.List;
34+
import java.util.Objects;
35+
36+
import static com.yashkasera.livstoryuploaddata.MainActivity.lastVisibleSound;
37+
import static com.yashkasera.livstoryuploaddata.MainActivity.playPosition;
38+
import static com.yashkasera.livstoryuploaddata.MainActivity.soundModelArrayList;
39+
40+
public class PlayAudioFragment extends Fragment {
41+
private static final String TAG = "PlayAudioFragment";
42+
private final int limit = 10;
43+
SoundRecyclerAdapter soundRecyclerAdapter;
44+
FirebaseFirestore db = FirebaseFirestore.getInstance();
45+
private Context context;
46+
private boolean isScrolling = false;
47+
private boolean isLastItemReached = false;
48+
49+
public PlayAudioFragment() {
50+
}
51+
52+
@Nullable
53+
@org.jetbrains.annotations.Nullable
54+
@Override
55+
public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable ViewGroup container,
56+
@Nullable Bundle savedInstanceState) {
57+
context = requireContext();
58+
return inflater.inflate(R.layout.fragment_play_audio, container, false);
59+
}
60+
61+
@Override
62+
public void onViewCreated(@NonNull @NotNull View view, @Nullable Bundle savedInstanceState) {
63+
super.onViewCreated(view, savedInstanceState);
64+
RecyclerView recyclerView = view.findViewById(R.id.recyclerView);
65+
soundRecyclerAdapter = new SoundRecyclerAdapter(context);
66+
recyclerView.setLayoutManager(new LinearLayoutManager(context));
67+
recyclerView.setAdapter(soundRecyclerAdapter);
68+
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(context,
69+
DividerItemDecoration.VERTICAL);
70+
recyclerView.addItemDecoration(dividerItemDecoration);
71+
if (soundModelArrayList.size() == 0) {
72+
soundRecyclerAdapter.addItem(null);
73+
db.collection("sounds")
74+
.orderBy("type")
75+
.limit(limit)
76+
.get()
77+
.addOnCompleteListener(task -> {
78+
if (task.isSuccessful()) {
79+
soundRecyclerAdapter.removeItem(null);
80+
for (QueryDocumentSnapshot document : Objects.requireNonNull(task.getResult())) {
81+
SoundModel soundModel = new SoundModel(
82+
document.getId(),
83+
document.getString("type"),
84+
document.getString("media"),
85+
(List<String>) document.get("keywords")
86+
);
87+
soundRecyclerAdapter.addItem(soundModel);
88+
}
89+
lastVisibleSound = task.getResult().getDocuments().get(task.getResult().size() - 1);
90+
} else {
91+
soundRecyclerAdapter.removeItem(null);
92+
Log.w(TAG, "Error getting documents.", task.getException());
93+
if (view != null)
94+
Snackbar.make(view.findViewById(android.R.id.content), "Unable to fetch records!",
95+
BaseTransientBottomBar.LENGTH_INDEFINITE).show();
96+
}
97+
});
98+
}
99+
RecyclerView.OnScrollListener onScrollListener = new RecyclerView.OnScrollListener() {
100+
@Override
101+
public void onScrollStateChanged(@NotNull RecyclerView recyclerView, int newState) {
102+
super.onScrollStateChanged(recyclerView, newState);
103+
if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
104+
isScrolling = true;
105+
}
106+
}
107+
108+
@Override
109+
public void onScrolled(@NotNull RecyclerView recyclerView, int dx, int dy) {
110+
super.onScrolled(recyclerView, dx, dy);
111+
LinearLayoutManager linearLayoutManager = ((LinearLayoutManager) recyclerView.getLayoutManager());
112+
int firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition();
113+
int visibleItemCount = linearLayoutManager.getChildCount();
114+
int totalItemCount = linearLayoutManager.getItemCount();
115+
if (isScrolling && (firstVisibleItemPosition + visibleItemCount == totalItemCount) &&
116+
!isLastItemReached && !soundModelArrayList.contains(null)) {
117+
isScrolling = false;
118+
soundRecyclerAdapter.addItem(null);
119+
db.collection("sounds")
120+
.orderBy("type")
121+
.startAfter(lastVisibleSound).limit(limit)
122+
.get()
123+
.addOnCompleteListener(t -> {
124+
if (t.isSuccessful()) {
125+
soundRecyclerAdapter.removeItem(null);
126+
for (DocumentSnapshot document : Objects.requireNonNull(t.getResult())) {
127+
SoundModel soundModel = new SoundModel(
128+
document.getId(),
129+
document.getString("type"),
130+
document.getString("media"),
131+
(List<String>) document.get("keywords")
132+
);
133+
soundRecyclerAdapter.addItem(soundModel);
134+
}
135+
lastVisibleSound = t.getResult().getDocuments().get(t.getResult().size() - 1);
136+
if (t.getResult().size() < limit) {
137+
isLastItemReached = true;
138+
}
139+
} else
140+
soundRecyclerAdapter.removeItem(null);
141+
});
142+
}
143+
}
144+
};
145+
recyclerView.addOnScrollListener(onScrollListener);
146+
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(context, recyclerView, new ClickListener() {
147+
@Override
148+
public void onClick(View view, int position) {
149+
if (soundModelArrayList.get(position) != null) playPosition.setValue(position);
150+
151+
}
152+
153+
@Override
154+
public void onLongClick(View view, int position) {
155+
if (soundModelArrayList.get(position) != null)
156+
new MaterialAlertDialogBuilder(context)
157+
.setTitle("Confirm Delete")
158+
.setMessage("Are you sure you want to delete this sound? This action cannot be undone.")
159+
.setPositiveButton("Delete", (dialog, which) -> db.collection("sounds")
160+
.document(soundModelArrayList.get(position).getId())
161+
.delete()
162+
.addOnCompleteListener(task -> {
163+
if (task.isSuccessful()) {
164+
Toast.makeText(context, "Sound deleted Successfully!", Toast.LENGTH_SHORT).show();
165+
soundRecyclerAdapter.notifyItemRemoved(position);
166+
soundModelArrayList.remove(position);
167+
} else {
168+
Toast.makeText(context, "Could not delete sound! Please try again later", Toast.LENGTH_SHORT).show();
169+
}
170+
171+
}))
172+
.setNegativeButton("Cancel", (dialog, which) -> dialog.dismiss())
173+
.show();
174+
}
175+
}));
176+
177+
178+
}
179+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package com.yashkasera.livstoryuploaddata.fragment;
2+
3+
import android.content.Context;
4+
import android.content.Intent;
5+
import android.os.Build;
6+
import android.os.Bundle;
7+
import android.util.Log;
8+
import android.view.LayoutInflater;
9+
import android.view.View;
10+
import android.view.ViewGroup;
11+
import android.widget.Toast;
12+
13+
import androidx.annotation.NonNull;
14+
import androidx.annotation.Nullable;
15+
import androidx.fragment.app.Fragment;
16+
import androidx.recyclerview.widget.DividerItemDecoration;
17+
import androidx.recyclerview.widget.LinearLayoutManager;
18+
import androidx.recyclerview.widget.RecyclerView;
19+
20+
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
21+
import com.google.firebase.firestore.FieldValue;
22+
import com.google.firebase.firestore.FirebaseFirestore;
23+
import com.yashkasera.livstoryuploaddata.R;
24+
import com.yashkasera.livstoryuploaddata.UploadDataActivity;
25+
import com.yashkasera.livstoryuploaddata.adapter.MissingWordRecyclerAdapter;
26+
import com.yashkasera.livstoryuploaddata.model.WordModel;
27+
import com.yashkasera.livstoryuploaddata.util.ClickListener;
28+
import com.yashkasera.livstoryuploaddata.util.RecyclerTouchListener;
29+
30+
import org.jetbrains.annotations.NotNull;
31+
32+
import java.util.ArrayList;
33+
import java.util.Map;
34+
35+
import static com.yashkasera.livstoryuploaddata.MainActivity.modelWordModelArrayList;
36+
import static com.yashkasera.livstoryuploaddata.MainActivity.userWordModelArrayList;
37+
38+
public class UserMissingWords extends Fragment {
39+
private static final String TAG = "UserMissingWords";
40+
private FirebaseFirestore db = FirebaseFirestore.getInstance();
41+
private MissingWordRecyclerAdapter adapter;
42+
private Context context;
43+
44+
public UserMissingWords() {
45+
}
46+
47+
@Nullable
48+
@Override
49+
public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
50+
context = requireContext();
51+
return inflater.inflate(R.layout.fragment_recycler_view, container, false);
52+
}
53+
54+
@Override
55+
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
56+
super.onActivityResult(requestCode, resultCode, data);
57+
if (requestCode == 1002 && resultCode == 1) {
58+
if (data != null) {
59+
modelWordModelArrayList.remove(data.getIntExtra("position", -1));
60+
adapter.notifyItemRemoved(data.getIntExtra("position", -1));
61+
}
62+
}
63+
}
64+
65+
@Override
66+
public void onViewCreated(@NonNull @NotNull View view, @Nullable Bundle savedInstanceState) {
67+
super.onViewCreated(view, savedInstanceState);
68+
RecyclerView recyclerView = view.findViewById(R.id.recyclerView);
69+
recyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
70+
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(requireContext(), DividerItemDecoration.VERTICAL);
71+
recyclerView.addItemDecoration(dividerItemDecoration);
72+
adapter = new MissingWordRecyclerAdapter(requireContext(), new ArrayList<>());
73+
recyclerView.setAdapter(adapter);
74+
if (userWordModelArrayList.size() != 0) {
75+
adapter.setList(userWordModelArrayList);
76+
} else {
77+
db.collection("report")
78+
.document("user")
79+
.get()
80+
.addOnCompleteListener(task -> {
81+
if (task.isSuccessful()) {
82+
ArrayList<WordModel> list = new ArrayList<>();
83+
for (Map.Entry<String, Object> entry : task.getResult().getData().entrySet())
84+
list.add(new WordModel(entry.getKey(), (long) entry.getValue()));
85+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
86+
list.sort((o1, o2) -> o1.getCount() >= o2.getCount() ? -1 : 1);
87+
userWordModelArrayList.addAll(list);
88+
adapter.setList(userWordModelArrayList);
89+
} else
90+
Log.d(TAG, "onComplete() returned: " + task.getException());
91+
});
92+
}
93+
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(context, recyclerView, new ClickListener() {
94+
@Override
95+
public void onClick(View view, int position) {
96+
Intent intent = new Intent(context, UploadDataActivity.class);
97+
intent.putExtra("word", userWordModelArrayList.get(position));
98+
intent.putExtra("from", "user");
99+
intent.putExtra("position", position);
100+
startActivityForResult(intent, 1002);
101+
}
102+
103+
@Override
104+
public void onLongClick(View view, int position) {
105+
if (userWordModelArrayList.get(position) != null)
106+
new MaterialAlertDialogBuilder(context)
107+
.setTitle("Confirm Delete")
108+
.setMessage("Are you sure you want to delete this sound? This action cannot be undone.")
109+
.setPositiveButton("Delete", (dialog, which) -> db.collection("report")
110+
.document("user")
111+
.update(userWordModelArrayList.get(position).getWord(), FieldValue.delete())
112+
.addOnCompleteListener(task -> {
113+
if (task.isSuccessful()) {
114+
Toast.makeText(context, "Suggestion deleted Successfully!", Toast.LENGTH_SHORT).show();
115+
adapter.notifyItemRemoved(position);
116+
userWordModelArrayList.remove(position);
117+
} else {
118+
Toast.makeText(context, "Could not delete sound! Please try again later", Toast.LENGTH_SHORT).show();
119+
}
120+
121+
}))
122+
.setNegativeButton("Cancel", (dialog, which) -> dialog.dismiss())
123+
.show();
124+
}
125+
}));
126+
}
127+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.yashkasera.livstoryuploaddata.model;
2+
3+
import java.io.Serializable;
4+
5+
public class WordModel implements Serializable {
6+
private String word;
7+
private long count;
8+
9+
public WordModel(String word, long count) {
10+
this.word = word;
11+
this.count = count;
12+
}
13+
14+
public String getWord() {
15+
return word;
16+
}
17+
18+
public void setWord(String word) {
19+
this.word = word;
20+
}
21+
22+
public long getCount() {
23+
return count;
24+
}
25+
26+
public void setCount(int count) {
27+
this.count = count;
28+
}
29+
}

‎AdminApp/app/src/main/res/drawable/button_gradient.xml

-9
This file was deleted.

‎AdminApp/app/src/main/res/drawable/gradient.xml

-9
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="24dp"
3+
android:height="24dp"
4+
android:viewportWidth="24"
5+
android:viewportHeight="24"
6+
android:tint="?attr/colorControlNormal">
7+
<path
8+
android:fillColor="@android:color/white"
9+
android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
10+
</vector>

‎AdminApp/app/src/main/res/layout/activity_main.xml

+21-17
Original file line numberDiff line numberDiff line change
@@ -25,32 +25,36 @@
2525
app:titleTextColor="#DEFFFFFF" />
2626
</com.google.android.material.appbar.AppBarLayout>
2727

28-
<androidx.recyclerview.widget.RecyclerView
29-
android:id="@+id/recyclerView"
28+
<com.google.android.material.tabs.TabLayout
29+
android:id="@+id/tabLayout"
3030
android:layout_width="match_parent"
31-
android:layout_height="0dp"
32-
app:layout_constraintBottom_toTopOf="@+id/relativeLayout"
31+
android:layout_height="wrap_content"
32+
android:layout_gravity="bottom"
33+
android:backgroundTint="@color/backgroundColor"
3334
app:layout_constraintEnd_toEndOf="parent"
3435
app:layout_constraintStart_toStartOf="parent"
3536
app:layout_constraintTop_toBottomOf="@+id/appbar"
36-
tools:listitem="@layout/item_sound" />
37+
app:layout_scrollFlags="noScroll"
38+
app:tabIndicatorColor="@color/textColor"
39+
app:tabSelectedTextColor="@color/textColor">
3740

38-
<com.google.android.material.floatingactionbutton.FloatingActionButton
39-
android:id="@+id/add"
40-
android:layout_width="wrap_content"
41-
android:layout_height="wrap_content"
42-
android:layout_marginEnd="16dp"
43-
android:layout_marginBottom="16dp"
44-
android:src="@android:drawable/ic_input_add"
45-
app:layout_constraintBottom_toTopOf="@id/relativeLayout"
46-
app:layout_constraintEnd_toEndOf="parent" />
41+
</com.google.android.material.tabs.TabLayout>
42+
43+
<androidx.viewpager.widget.ViewPager
44+
android:id="@+id/viewPager"
45+
android:layout_width="match_parent"
46+
android:layout_height="0dp"
47+
app:layout_constraintBottom_toTopOf="@+id/relativeLayout"
48+
app:layout_constraintEnd_toEndOf="parent"
49+
app:layout_constraintStart_toStartOf="parent"
50+
app:layout_constraintTop_toBottomOf="@+id/tabLayout" />
4751

4852
<RelativeLayout
4953
android:id="@+id/relativeLayout"
5054
android:layout_width="match_parent"
5155
android:layout_height="wrap_content"
5256
android:background="@color/cardBackgroundColor"
53-
android:paddingHorizontal="16dp"
57+
android:padding="16dp"
5458
app:layout_constraintBottom_toBottomOf="parent"
5559
app:layout_constraintEnd_toEndOf="parent"
5660
app:layout_constraintStart_toStartOf="parent">
@@ -59,8 +63,8 @@
5963
android:id="@+id/progressBar"
6064
style="?android:attr/progressBarStyleHorizontal"
6165
android:layout_width="match_parent"
62-
android:layout_alignParentTop="true"
63-
android:layout_height="wrap_content" />
66+
android:layout_height="wrap_content"
67+
android:layout_alignParentTop="true" />
6468

6569
<TextView
6670
android:id="@+id/keywords"

‎AdminApp/app/src/main/res/layout/activity_sign_in.xml

+2-2
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@
5858
android:id="@+id/email"
5959
android:layout_width="match_parent"
6060
android:layout_height="wrap_content"
61+
android:inputType="textEmailAddress"
6162
android:textColor="@color/textColor" />
62-
android:inputType="textEmailAddress" />
6363
</com.google.android.material.textfield.TextInputLayout>
6464

6565
<com.google.android.material.textfield.TextInputLayout
@@ -85,8 +85,8 @@
8585
android:id="@+id/password"
8686
android:layout_width="match_parent"
8787
android:layout_height="wrap_content"
88+
android:inputType="textPassword"
8889
android:textColor="@color/textColor" />
89-
android:inputType="textEmailAddress" />
9090
</com.google.android.material.textfield.TextInputLayout>
9191

9292
<Button

‎AdminApp/app/src/main/res/layout/activity_upload_data.xml

-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
</com.google.android.material.appbar.AppBarLayout>
2424

2525
<androidx.core.widget.NestedScrollView
26-
android:id="@+id/nestedScrollView"
2726
android:layout_width="match_parent"
2827
android:layout_height="0dp"
2928
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:app="http://schemas.android.com/apk/res-auto"
4+
android:layout_width="match_parent"
5+
android:layout_height="match_parent"
6+
xmlns:tools="http://schemas.android.com/tools">
7+
8+
<androidx.recyclerview.widget.RecyclerView
9+
android:id="@+id/recyclerView"
10+
android:layout_width="match_parent"
11+
android:layout_height="0dp"
12+
app:layout_constraintBottom_toBottomOf="parent"
13+
app:layout_constraintEnd_toEndOf="parent"
14+
app:layout_constraintStart_toStartOf="parent"
15+
app:layout_constraintTop_toTopOf="parent"
16+
tools:listitem="@layout/item_sound" />
17+
18+
</androidx.constraintlayout.widget.ConstraintLayout>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:id="@+id/recyclerView"
4+
android:layout_width="match_parent"
5+
android:layout_height="match_parent"/>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:layout_width="match_parent"
4+
android:layout_height="wrap_content"
5+
android:layout_margin="8dp"
6+
android:orientation="vertical">
7+
8+
<ProgressBar
9+
android:id="@+id/progressBar"
10+
android:layout_width="wrap_content"
11+
android:layout_height="wrap_content"
12+
android:layout_gravity="center_horizontal"
13+
android:indeterminate="true"
14+
android:indeterminateTint="@color/colorAccent"
15+
android:paddingLeft="8dp"
16+
android:paddingRight="8dp" />
17+
18+
</LinearLayout>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:app="http://schemas.android.com/apk/res-auto"
4+
android:layout_width="match_parent"
5+
android:layout_height="wrap_content"
6+
android:clickable="true"
7+
android:focusable="true"
8+
android:foreground="?android:attr/selectableItemBackground"
9+
android:padding="@dimen/margin_medium">
10+
11+
<TextView
12+
android:id="@+id/word"
13+
android:layout_width="wrap_content"
14+
android:layout_height="wrap_content"
15+
android:layout_alignParentStart="true"
16+
android:layout_centerVertical="true"
17+
android:layout_marginEnd="8dp"
18+
android:layout_toStartOf="@id/count"
19+
android:textColor="@color/textColor"
20+
android:textSize="18sp" />
21+
22+
<com.google.android.material.chip.Chip
23+
android:id="@+id/count"
24+
android:layout_width="wrap_content"
25+
android:layout_height="wrap_content"
26+
android:layout_alignParentEnd="true"
27+
android:layout_centerVertical="true"
28+
android:text="100"
29+
android:textColor="@color/colorAccent"
30+
app:chipBackgroundColor="@color/cardBackgroundColor"
31+
app:chipStrokeColor="@color/colorAccent"
32+
app:chipStrokeWidth="2dp" />
33+
34+
</RelativeLayout>

‎AdminApp/app/src/main/res/menu/menu_main.xml

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<menu xmlns:android="http://schemas.android.com/apk/res/android">
2+
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
3+
xmlns:android="http://schemas.android.com/apk/res/android">
34

5+
<item
6+
android:id="@+id/add"
7+
android:icon="@drawable/ic_baseline_add_24"
8+
android:title="Add"
9+
app:showAsAction="always" />
410
<item
511
android:id="@+id/logout"
612
android:title="Logout" />

‎AdminApp/app/src/main/res/values/colors.xml

-2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44
<color name="teal_700">#FF018786</color>
55
<color name="white">#FFFFFFFF</color>
66
<color name="cardBackgroundColor">#2B3768</color>
7-
<color name="fabTintColor">#2D396B</color>
87
<color name="chipBackgroundColor">#1B2559</color>
9-
<color name="cardTextColor">#94D0CC</color>
108
<color name="textColor">#F1F1F1</color>
119
<color name="textColorSecondary">#99F1F1F1</color>
1210
<color name="colorAccent">#FFCB4C</color>

‎App/.DS_Store

2 KB
Binary file not shown.

0 commit comments

Comments
 (0)
Please sign in to comment.