From 3de1749b0dfbff90d77da5b0cd69a0d103ac858b Mon Sep 17 00:00:00 2001 From: pegasko Date: Fri, 7 Jun 2024 02:59:07 +0300 Subject: [PATCH] sometimes you just have to buy a lobster --- Yeeemp/app/src/main/AndroidManifest.xml | 23 +++- .../java/art/pegasko/yeeemp/base/Event.java | 4 +- .../art/pegasko/yeeemp/base/EventMaker.java | 3 +- .../java/art/pegasko/yeeemp/base/Queue.java | 1 + .../art/pegasko/yeeemp/base/QueueMaker.java | 2 + .../art/pegasko/yeeemp/impl/EventImpl.java | 28 ++--- .../pegasko/yeeemp/impl/EventMakerImpl.java | 39 +++++- .../art/pegasko/yeeemp/impl/QueueImpl.java | 56 ++++++++- .../pegasko/yeeemp/impl/QueueMakerImpl.java | 71 ++++++++++- .../java/art/pegasko/yeeemp/impl/TagImpl.java | 8 +- .../art/pegasko/yeeemp/impl/TagMakerImpl.java | 7 +- .../yeeemp/ui/activity/EventListActivity.java | 112 +++++++++++++++++ .../ui/activity/EventRecyclerViewAdapter.java | 117 ++++++++++++++++++ .../yeeemp/ui/activity/FirstFragment.java | 61 --------- ...inActivity.java => QueueListActivity.java} | 49 +++----- .../ui/activity/QueueRecyclerViewAdapter.java | 79 ++++++++---- .../yeeemp/ui/activity/SecondFragment.java | 61 --------- .../art/pegasko/yeeemp/ui/activity/Utils.java | 29 +++++ .../drawable-v24/ic_launcher_foreground.xml | 16 +++ .../res/drawable/ic_launcher_background.xml | 16 +++ .../drawable/pegasko_listitem_background.xml | 16 +++ .../main/res/layout/activity_event_list.xml | 53 ++++++++ ...ivity_main.xml => activity_queue_list.xml} | 22 +++- ...ontent_main.xml => content_event_list.xml} | 20 ++- .../main/res/layout/content_queue_list.xml | 36 ++++++ .../src/main/res/layout/event_list_item.xml | 75 +++++++++++ .../src/main/res/layout/fragment_first.xml | 34 ----- .../src/main/res/layout/fragment_second.xml | 34 ----- .../src/main/res/layout/queue_list_item.xml | 65 ++++++++-- .../res/menu/event_list_item_action_menu.xml | 22 ++++ .../res/menu/queue_list_item_action_menu.xml | 16 +++ .../res/mipmap-anydpi-v26/ic_launcher.xml | 16 +++ .../mipmap-anydpi-v26/ic_launcher_round.xml | 16 +++ .../app/src/main/res/navigation/nav_graph.xml | 28 ----- .../src/main/res/navigation/nav_graph2.xml | 28 ----- .../app/src/main/res/values-land/dimens.xml | 16 +++ .../app/src/main/res/values-night/themes.xml | 16 +++ Yeeemp/app/src/main/res/values-v23/themes.xml | 20 ++- .../src/main/res/values-w1240dp/dimens.xml | 16 +++ .../app/src/main/res/values-w600dp/dimens.xml | 16 +++ Yeeemp/app/src/main/res/values/colors.xml | 16 +++ Yeeemp/app/src/main/res/values/dimens.xml | 26 ++++ Yeeemp/app/src/main/res/values/strings.xml | 16 +++ Yeeemp/app/src/main/res/values/themes.xml | 20 ++- Yeeemp/app/src/main/res/xml/backup_rules.xml | 16 +++ .../main/res/xml/data_extraction_rules.xml | 16 +++ 46 files changed, 1098 insertions(+), 359 deletions(-) create mode 100644 Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/EventListActivity.java create mode 100644 Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/EventRecyclerViewAdapter.java delete mode 100644 Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/FirstFragment.java rename Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/{MainActivity.java => QueueListActivity.java} (59%) delete mode 100644 Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/SecondFragment.java create mode 100644 Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/Utils.java create mode 100644 Yeeemp/app/src/main/res/layout/activity_event_list.xml rename Yeeemp/app/src/main/res/layout/{activity_main.xml => activity_queue_list.xml} (64%) rename Yeeemp/app/src/main/res/layout/{content_main.xml => content_event_list.xml} (55%) create mode 100644 Yeeemp/app/src/main/res/layout/content_queue_list.xml create mode 100644 Yeeemp/app/src/main/res/layout/event_list_item.xml delete mode 100644 Yeeemp/app/src/main/res/layout/fragment_first.xml delete mode 100644 Yeeemp/app/src/main/res/layout/fragment_second.xml create mode 100644 Yeeemp/app/src/main/res/menu/event_list_item_action_menu.xml delete mode 100644 Yeeemp/app/src/main/res/navigation/nav_graph.xml delete mode 100644 Yeeemp/app/src/main/res/navigation/nav_graph2.xml diff --git a/Yeeemp/app/src/main/AndroidManifest.xml b/Yeeemp/app/src/main/AndroidManifest.xml index 347cd7b..7d82f9e 100644 --- a/Yeeemp/app/src/main/AndroidManifest.xml +++ b/Yeeemp/app/src/main/AndroidManifest.xml @@ -1,3 +1,19 @@ + + @@ -13,7 +29,7 @@ android:theme="@style/Theme.Yeeemp" tools:targetApi="31" > @@ -22,6 +38,11 @@ + + \ No newline at end of file diff --git a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/base/Event.java b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/base/Event.java index 511cd94..978310a 100644 --- a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/base/Event.java +++ b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/base/Event.java @@ -20,8 +20,8 @@ public interface Event { int getId(); long getTimestamp(); void setTimestamp(long timestamp); - String getMessage(); - void setMessage(String message); + String getComment(); + void setComment(String comment); void addTag(Tag tag); void removeTag(Tag tag); Tag[] getTags(); diff --git a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/base/EventMaker.java b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/base/EventMaker.java index 17ee337..7eb8fae 100644 --- a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/base/EventMaker.java +++ b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/base/EventMaker.java @@ -17,5 +17,6 @@ package art.pegasko.yeeemp.base; public interface EventMaker { - Event createInQueue(Queue queue); + Event create(); + void delete(Event event); } diff --git a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/base/Queue.java b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/base/Queue.java index 898f724..8295d98 100644 --- a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/base/Queue.java +++ b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/base/Queue.java @@ -21,6 +21,7 @@ public interface Queue { String getName(); void setName(String name); Event[] getEvents(); + int getEventCount(); void addEvent(Event event); void removeEvent(Event event); Tag[] getGlobalTags(); diff --git a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/base/QueueMaker.java b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/base/QueueMaker.java index 4d43924..52b1a70 100644 --- a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/base/QueueMaker.java +++ b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/base/QueueMaker.java @@ -17,6 +17,8 @@ package art.pegasko.yeeemp.base; public interface QueueMaker { + Queue getById(int id); Queue create(); + void delete(Queue queue); Queue[] list(); } diff --git a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/impl/EventImpl.java b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/impl/EventImpl.java index 6938e55..28ea33f 100644 --- a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/impl/EventImpl.java +++ b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/impl/EventImpl.java @@ -25,19 +25,16 @@ import android.util.Log; import androidx.annotation.NonNull; import art.pegasko.yeeemp.base.Event; -import art.pegasko.yeeemp.base.Queue; import art.pegasko.yeeemp.base.Tag; public class EventImpl implements Event { public static final String TAG = EventImpl.class.getSimpleName(); private final SQLiteDatabase db; - private final Queue queue; private final int id; - protected EventImpl(SQLiteDatabase db, Queue queue, int id) { + protected EventImpl(SQLiteDatabase db, int id) { this.db = db; - this.queue = queue; this.id = id; } @@ -52,8 +49,8 @@ public class EventImpl implements Event { Cursor cursor = db.query( "event", new String[] { "timestamp" }, - "query_id = ? AND id = ?", - new String[] { Integer.toString(queue.getId()), Integer.toString(this.getId()) }, + "id = ?", + new String[] { Integer.toString(this.getId()) }, null, null, null @@ -82,11 +79,11 @@ public class EventImpl implements Event { } @Override - public String getMessage() { + public String getComment() { synchronized (this.db) { Cursor cursor = db.query( "event", - new String[] { "message" }, + new String[] { "comment" }, "id = ?", new String[] { Integer.toString(this.getId()) }, null, @@ -103,10 +100,10 @@ public class EventImpl implements Event { } @Override - public void setMessage(String message) { + public void setComment(String comment) { synchronized (this.db) { ContentValues cv = new ContentValues(); - cv.put("message", message); + cv.put("comment", comment); db.update( "event", cv, @@ -148,7 +145,7 @@ public class EventImpl implements Event { cv.put("tag_id", tag.getId()); db.insertOrThrow("event_tag", null, cv); } catch (SQLiteException e) { - Log.w(TAG, e); + Log.wtf(TAG, e); } } } @@ -169,7 +166,7 @@ public class EventImpl implements Event { new String[] { Integer.toString(this.getId()), Integer.toString(tag.getId()) } ); } catch (SQLiteException e) { - Log.w(TAG, e); + Log.wtf(TAG, e); } } } @@ -197,7 +194,6 @@ public class EventImpl implements Event { while (cursor.moveToNext()) { tags[index++] = new TagImpl( this.db, - this.queue, cursor.getInt(0) ); } @@ -210,12 +206,12 @@ public class EventImpl implements Event { @Override public String toString() { StringBuilder sb = new StringBuilder(); - sb.append("Queue{id="); + sb.append("Event{id="); sb.append(this.getId()); sb.append(",timestamp="); sb.append(this.getTimestamp()); - sb.append(",message="); - sb.append(this.getMessage()); + sb.append(",comment="); + sb.append(this.getComment()); sb.append("}"); return sb.toString(); } diff --git a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/impl/EventMakerImpl.java b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/impl/EventMakerImpl.java index 4146606..9f81365 100644 --- a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/impl/EventMakerImpl.java +++ b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/impl/EventMakerImpl.java @@ -17,14 +17,12 @@ package art.pegasko.yeeemp.impl; import android.content.ContentValues; -import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteException; import android.util.Log; import art.pegasko.yeeemp.base.Event; import art.pegasko.yeeemp.base.EventMaker; -import art.pegasko.yeeemp.base.Queue; public class EventMakerImpl implements EventMaker { public static final String TAG = EventMakerImpl.class.getSimpleName(); @@ -36,22 +34,51 @@ public class EventMakerImpl implements EventMaker { } @Override - public Event createInQueue(Queue queue) { + public Event create() { synchronized (this.db) { try { ContentValues cv = new ContentValues(); - cv.put("queue_id", queue.getId()); + cv.put("id", (Integer) null); long rowId = db.insertOrThrow("event", null, cv); return new EventImpl( this.db, - queue, (int) rowId ); } catch (SQLiteException e) { - Log.w(TAG, e); + Log.wtf(TAG, e); } return null; } } + + @Override + public void delete(Event event) { + synchronized (this.db) { + try { + // Delete queue <-> event + db.delete( + "queue_event", + "event_id = ?", + new String[] { Integer.toString(event.getId()) } + ); + + // Delete event <-> tag + db.delete( + "event_tag", + "event_id = ?", + new String[] { Integer.toString(event.getId()) } + ); + + // Delete event + db.delete( + "event", + "id = ?", + new String[] { Integer.toString(event.getId()) } + ); + } catch (SQLiteException e) { + Log.wtf(TAG, e); + } + } + } } diff --git a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/impl/QueueImpl.java b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/impl/QueueImpl.java index 890c8fb..a90dc34 100644 --- a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/impl/QueueImpl.java +++ b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/impl/QueueImpl.java @@ -27,6 +27,7 @@ import androidx.annotation.NonNull; import art.pegasko.yeeemp.base.Event; import art.pegasko.yeeemp.base.Queue; import art.pegasko.yeeemp.base.Tag; +import kotlin.NotImplementedError; public class QueueImpl implements Queue { public static final String TAG = QueueImpl.class.getSimpleName(); @@ -81,16 +82,62 @@ public class QueueImpl implements Queue { @Override public Event[] getEvents() { - return new Event[0]; + synchronized (this.db) { + Cursor cursor = db.query( + "queue_event", + new String[] { "event_id" }, + "queue_id = ?", + new String[] { Integer.toString(this.getId()) }, + null, + null, + null + ); + + if (cursor == null) { + return new Event[0]; + } + + Event[] events = new Event[cursor.getCount()]; + + int index = 0; + while (cursor.moveToNext()) { + events[index++] = new EventImpl( + this.db, + cursor.getInt(0) + ); + } + + return events; + } + } + + @Override + public int getEventCount() { + synchronized (this.db) { + Cursor cursor = db.query( + "queue_event", + new String[] { "count(*)" }, + "queue_id = ?", + new String[] { Integer.toString(this.getId()) }, + null, + null, + null + ); + + if (!Utils.findResult(cursor)) + return 0; + + return cursor.getInt(0); + } } /** !synchronized */ protected boolean hasEvent(Event event) { synchronized (this.db) { Cursor cursor = db.query( - "query_event", + "queue_event", new String[] { "1" }, - "query_id = ? AND event_id = ?", + "queue_id = ? AND event_id = ?", new String[] { Integer.toString(this.getId()), Integer.toString(event.getId()) }, null, null, @@ -137,7 +184,7 @@ public class QueueImpl implements Queue { new String[] { Integer.toString(this.getId()), Integer.toString(event.getId()) } ); } catch (SQLiteException e) { - Log.w(TAG, e); + Log.wtf(TAG, e); } } } @@ -165,7 +212,6 @@ public class QueueImpl implements Queue { while (cursor.moveToNext()) { tags[index++] = new TagImpl( this.db, - this, cursor.getInt(0) ); } diff --git a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/impl/QueueMakerImpl.java b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/impl/QueueMakerImpl.java index 581c89f..208bf2a 100644 --- a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/impl/QueueMakerImpl.java +++ b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/impl/QueueMakerImpl.java @@ -22,6 +22,8 @@ import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteException; import android.util.Log; +import art.pegasko.yeeemp.base.Event; +import art.pegasko.yeeemp.base.EventMaker; import art.pegasko.yeeemp.base.Queue; import art.pegasko.yeeemp.base.QueueMaker; @@ -34,6 +36,31 @@ public class QueueMakerImpl implements QueueMaker { this.db = db; } + @Override + public Queue getById(int id) { + synchronized (this.db) { + try { + Cursor cursor = db.query( + "queue", + new String[] { "1" }, + "id = ?", + new String[] { Integer.toString(id) }, + null, + null, + null + ); + + if (Utils.findResult(cursor)) + return new QueueImpl(this.db, id); + + } catch (SQLiteException e) { + Log.wtf(TAG, e); + } + + return null; + } + } + @Override public Queue create() { synchronized (this.db) { @@ -46,7 +73,7 @@ public class QueueMakerImpl implements QueueMaker { (int) rowId ); } catch (SQLiteException e) { - Log.w(TAG, e); + Log.wtf(TAG, e); } return null; @@ -83,4 +110,46 @@ public class QueueMakerImpl implements QueueMaker { return queues; } } + + @Override + public void delete(Queue queue) { + synchronized (this.db) { + + // Drop events + try { + for (Event event: queue.getEvents()) { + db.delete( + "event", + "id = ?", + new String[] { Integer.toString(event.getId()) } + ); + } + } catch (SQLiteException e) { + Log.wtf(TAG, e); + return; + } + + // Drop queue <-> event + try { + db.delete( + "queue_event", + "queue_id = ?", + new String[] { Integer.toString(queue.getId()) } + ); + } catch (SQLiteException e) { + Log.wtf(TAG, e); + } + + // Drop queue + try { + db.delete( + "queue", + "id = ?", + new String[] { Integer.toString(queue.getId()) } + ); + } catch (SQLiteException e) { + Log.wtf(TAG, e); + } + } + } } diff --git a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/impl/TagImpl.java b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/impl/TagImpl.java index 9607e99..229446c 100644 --- a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/impl/TagImpl.java +++ b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/impl/TagImpl.java @@ -28,12 +28,10 @@ public class TagImpl implements Tag { public static final String TAG = TagImpl.class.getSimpleName(); private final SQLiteDatabase db; - private final Queue queue; private final int id; - protected TagImpl(SQLiteDatabase db, Queue queue, int id) { + protected TagImpl(SQLiteDatabase db, int id) { this.db = db; - this.queue = queue; this.id = id; } @@ -48,8 +46,8 @@ public class TagImpl implements Tag { Cursor cursor = db.query( "tag", new String[] { "name" }, - "query_id = ? AND id = ?", - new String[] { Integer.toString(queue.getId()), Integer.toString(this.getId()) }, + "id = ?", + new String[] { Integer.toString(this.getId()) }, null, null, null diff --git a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/impl/TagMakerImpl.java b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/impl/TagMakerImpl.java index 859f63e..ce1da8a 100644 --- a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/impl/TagMakerImpl.java +++ b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/impl/TagMakerImpl.java @@ -41,7 +41,7 @@ public class TagMakerImpl implements TagMaker { Cursor cursor = db.query( "tag", new String[] { "id", "name" }, - "query_id = ? AND name = ?", + "queue_id = ? AND name = ?", new String[] { Integer.toString(queue.getId()), name }, null, null, @@ -50,12 +50,11 @@ public class TagMakerImpl implements TagMaker { if (Utils.findResult(cursor)) { return new TagImpl( db, - queue, cursor.getInt(0) ); } } catch (SQLiteException e) { - Log.w(TAG, e); + Log.wtf(TAG, e); } return null; @@ -69,7 +68,7 @@ public class TagMakerImpl implements TagMaker { cv.put("name", name); db.insertOrThrow("tag", null, cv); } catch (SQLiteException e) { - Log.w(TAG, e); + Log.wtf(TAG, e); return false; } return true; diff --git a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/EventListActivity.java b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/EventListActivity.java new file mode 100644 index 0000000..4d91a5c --- /dev/null +++ b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/EventListActivity.java @@ -0,0 +1,112 @@ +/** + * Copyright 2024 pegasko + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package art.pegasko.yeeemp.ui.activity; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.snackbar.Snackbar; + +import art.pegasko.yeeemp.R; +import art.pegasko.yeeemp.base.Event; +import art.pegasko.yeeemp.base.Queue; +import art.pegasko.yeeemp.base.Wrapper; +import art.pegasko.yeeemp.databinding.ActivityEventListBinding; +import art.pegasko.yeeemp.impl.Init; + +public class EventListActivity extends AppCompatActivity { + public static final String TAG = EventListActivity.class.getSimpleName(); + + private ActivityEventListBinding binding; + private RecyclerView eventList; + private EventRecyclerViewAdapter eventListAdapter; + private Queue queue; + + private void updateList() { + runOnUiThread(() -> { + eventListAdapter.reloadItems(); + }); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Init.initDB(getApplicationContext()); + + // Get Queue ID from Intent + Bundle extras = getIntent().getExtras(); + if (extras == null) { + Log.e(TAG, "Missing Intent arguments (queue_id)"); + finish(); + return; + } + + int queue_id = extras.getInt("queue_id", -1); + if (queue_id == -1) { + Log.e(TAG, "Missing Intent arguments (queue_id)"); + finish(); + return; + } + + queue = Wrapper.getQueueMaker().getById(queue_id); + if (queue == null) { + Log.e(TAG, "Missing Intent arguments (queue_id)"); + finish(); + return; + } + + binding = ActivityEventListBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + setSupportActionBar(binding.toolbar); + + /* Queue list */ + eventListAdapter = new EventRecyclerViewAdapter(queue); + eventList = findViewById(R.id.content_event_list__list); + eventList.setLayoutManager(new LinearLayoutManager(this)); + eventList.setAdapter(eventListAdapter); + + /* FAB Listeners */ + binding.fab.setOnLongClickListener((View view) -> { + Snackbar.make(view, "Create Event", Snackbar.LENGTH_LONG) + .setAnchorView(R.id.fab) + .setAction("Action", null).show(); + + return true; + }); + binding.fab.setOnClickListener(view -> { + Log.w(TAG, "TODO: Open editor"); + + Event event = Wrapper.getEventMaker().create(); + event.setTimestamp(System.currentTimeMillis()); + event.setComment("Lobster number " + System.currentTimeMillis()); + queue.addEvent(event); + + Log.w(TAG, "Create: " + event.toString() + " in " + queue); + + updateList(); + }); + + /* Fill lists */ + updateList(); + } +} diff --git a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/EventRecyclerViewAdapter.java b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/EventRecyclerViewAdapter.java new file mode 100644 index 0000000..0957b1f --- /dev/null +++ b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/EventRecyclerViewAdapter.java @@ -0,0 +1,117 @@ +/** + * Copyright 2024 pegasko + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package art.pegasko.yeeemp.ui.activity; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.text.InputType; +import android.view.LayoutInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.EditText; +import android.widget.PopupMenu; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import art.pegasko.yeeemp.R; +import art.pegasko.yeeemp.base.Event; +import art.pegasko.yeeemp.base.Queue; +import art.pegasko.yeeemp.base.Wrapper; +import art.pegasko.yeeemp.databinding.EventListItemBinding; +import art.pegasko.yeeemp.databinding.QueueListItemBinding; + +class EventRecyclerViewAdapter extends RecyclerView.Adapter { + public static final String TAG = EventRecyclerViewAdapter.class.getSimpleName(); + + private final Queue queue; + private Event[] events; + + public EventRecyclerViewAdapter(Queue queue) { + super(); + this.queue = queue; + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) { + View view = ( + LayoutInflater + .from(viewGroup.getContext()) + .inflate(R.layout.event_list_item, viewGroup, false) + ); + + return new ViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder viewHolder, int position) { + viewHolder.getBinding().eventListItemTimestamp.setText(Utils.formatTs(events[position].getTimestamp())); + + viewHolder.getBinding().eventListItemItem.setOnLongClickListener((View view) -> { + PopupMenu popupMenu = new PopupMenu(view.getContext(), viewHolder.getBinding().eventListItemItem); + popupMenu.getMenuInflater().inflate(R.menu.event_list_item_action_menu, popupMenu.getMenu()); + popupMenu.setOnMenuItemClickListener((MenuItem menuItem) -> { + if (menuItem.getItemId() == R.id.event_list_item_action_menu_delete) { + new AlertDialog.Builder(view.getContext()) + .setTitle("Delete event") + .setMessage("Are you sure you want to delete this event?") + .setPositiveButton(android.R.string.yes, (dialog, which) -> { + Wrapper.getEventMaker().delete(events[position]); + + reloadItems(); + }) + .setNegativeButton(android.R.string.no, null) + .setIcon(android.R.drawable.ic_dialog_alert) + .show(); + } + return true; + }); + + popupMenu.show(); + + return true; + }); + +// viewHolder.queueStats.setText(Integer.toString(events[position].getEventCount())); + } + + @Override + public int getItemCount() { + return this.events.length; + } + + public static class ViewHolder extends RecyclerView.ViewHolder { + private EventListItemBinding binding; + + public ViewHolder(@NonNull View itemView) { + super(itemView); + this.binding = EventListItemBinding.bind(itemView); + } + + public EventListItemBinding getBinding() { + return this.binding; + } + } + + public void reloadItems() { + this.events = this.queue.getEvents(); + this.notifyDataSetChanged(); + } +} diff --git a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/FirstFragment.java b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/FirstFragment.java deleted file mode 100644 index 6f50327..0000000 --- a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/FirstFragment.java +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Copyright 2024 pegasko - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package art.pegasko.yeeemp.ui.activity; - -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; -import androidx.navigation.fragment.NavHostFragment; - -import art.pegasko.yeeemp.R; -import art.pegasko.yeeemp.databinding.FragmentFirstBinding; - -public class FirstFragment extends Fragment { - -private FragmentFirstBinding binding; - - @Override - public View onCreateView( - @NonNull LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState - ) { - - binding = FragmentFirstBinding.inflate(inflater, container, false); - return binding.getRoot(); - - } - - public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - - binding.buttonFirst.setOnClickListener(v -> - NavHostFragment.findNavController(FirstFragment.this) - .navigate(R.id.action_FirstFragment_to_SecondFragment) - ); - } - -@Override - public void onDestroyView() { - super.onDestroyView(); - binding = null; - } - -} \ No newline at end of file diff --git a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/MainActivity.java b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/QueueListActivity.java similarity index 59% rename from Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/MainActivity.java rename to Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/QueueListActivity.java index 198a936..8c6726f 100644 --- a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/MainActivity.java +++ b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/QueueListActivity.java @@ -22,26 +22,23 @@ import androidx.appcompat.app.AppCompatActivity; import android.util.Log; import android.view.View; -import androidx.navigation.NavController; -import androidx.navigation.Navigation; + import androidx.navigation.ui.AppBarConfiguration; -import androidx.navigation.ui.NavigationUI; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import art.pegasko.yeeemp.base.Queue; import art.pegasko.yeeemp.base.Wrapper; -import art.pegasko.yeeemp.databinding.ActivityMainBinding; +import art.pegasko.yeeemp.databinding.ActivityQueueListBinding; import art.pegasko.yeeemp.R; -import art.pegasko.yeeemp.impl.EventImpl; import art.pegasko.yeeemp.impl.Init; -public class MainActivity extends AppCompatActivity { - public static final String TAG = MainActivity.class.getSimpleName(); +public class QueueListActivity extends AppCompatActivity { + public static final String TAG = QueueListActivity.class.getSimpleName(); private AppBarConfiguration appBarConfiguration; - private ActivityMainBinding binding; + private ActivityQueueListBinding binding; private RecyclerView queueList; private QueueRecyclerViewAdapter queueListAdapter; @@ -57,20 +54,16 @@ public class MainActivity extends AppCompatActivity { Init.initDB(getApplicationContext()); - binding = ActivityMainBinding.inflate(getLayoutInflater()); + binding = ActivityQueueListBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); - setSupportActionBar(binding.toolbar); + /* Queue list */ queueListAdapter = new QueueRecyclerViewAdapter(); - queueList = findViewById(R.id.content_main__queue_list); + queueList = findViewById(R.id.content_queue_list__list); queueList.setLayoutManager(new LinearLayoutManager(this)); queueList.setAdapter(queueListAdapter); -// NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main); -// appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build(); -// NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration); - /* FAB Listeners */ binding.fab.setOnLongClickListener((View view) -> { Snackbar.make(view, "Create Queue", Snackbar.LENGTH_LONG) @@ -79,25 +72,23 @@ public class MainActivity extends AppCompatActivity { return true; }); - binding.fab.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - Queue q = Wrapper.getQueueMaker().create(); - q.setName("New Queue"); - Log.w(TAG, "Create: " + q.toString()); + binding.fab.setOnClickListener(view -> { + Queue q = Wrapper.getQueueMaker().create(); + q.setName("New Queue"); + Log.w(TAG, "Create: " + q.toString()); - updateList(); - } + updateList(); }); /* Fill lists */ updateList(); } -// @Override -// public boolean onSupportNavigateUp() { -// NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main); -// return NavigationUI.navigateUp(navController, appBarConfiguration) -// || super.onSupportNavigateUp(); -// } + @Override + protected void onResume() { + super.onResume(); + + /* Ekchualle we returned from somewhere */ + updateList(); + } } \ No newline at end of file diff --git a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/QueueRecyclerViewAdapter.java b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/QueueRecyclerViewAdapter.java index 103fba8..67d3f77 100644 --- a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/QueueRecyclerViewAdapter.java +++ b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/QueueRecyclerViewAdapter.java @@ -1,7 +1,25 @@ +/** + * Copyright 2024 pegasko + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package art.pegasko.yeeemp.ui.activity; import android.app.AlertDialog; import android.content.DialogInterface; +import android.content.Intent; +import android.os.Bundle; import android.text.InputType; import android.util.Log; import android.view.LayoutInflater; @@ -10,19 +28,17 @@ import android.view.View; import android.view.ViewGroup; import android.widget.EditText; import android.widget.PopupMenu; -import android.widget.TextView; -import android.widget.Toast; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import art.pegasko.yeeemp.R; +import art.pegasko.yeeemp.base.Event; import art.pegasko.yeeemp.base.Queue; -import art.pegasko.yeeemp.base.QueueMaker; import art.pegasko.yeeemp.base.Wrapper; -import art.pegasko.yeeemp.impl.EventImpl; +import art.pegasko.yeeemp.databinding.QueueListItemBinding; -public class QueueRecyclerViewAdapter extends RecyclerView.Adapter { +class QueueRecyclerViewAdapter extends RecyclerView.Adapter { public static final String TAG = QueueRecyclerViewAdapter.class.getSimpleName(); private Queue[] queues; @@ -41,20 +57,20 @@ public class QueueRecyclerViewAdapter extends RecyclerView.Adapter { - PopupMenu popupMenu = new PopupMenu(view.getContext(), viewHolder.queueItem); + viewHolder.getBinding().queueListItemTitle.setText(queues[position].getName()); + + viewHolder.getBinding().queueListItemItem.setOnLongClickListener((View view) -> { + PopupMenu popupMenu = new PopupMenu(view.getContext(), viewHolder.getBinding().queueListItemItem); popupMenu.getMenuInflater().inflate(R.menu.queue_list_item_action_menu, popupMenu.getMenu()); popupMenu.setOnMenuItemClickListener((MenuItem menuItem) -> { if (menuItem.getItemId() == R.id.queue_list_item_action_menu_delete) { new AlertDialog.Builder(view.getContext()) - .setTitle("Delete entry") + .setTitle("Delete queue") .setMessage("Are you sure you want to delete this queue?") - .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { -// Wrapper.getQueueMaker().delete - Log.e(TAG, "Not implemented action"); - } + .setPositiveButton(android.R.string.yes, (dialog, which) -> { + Wrapper.getQueueMaker().delete(queues[position]); + + reloadItems(); }) .setNegativeButton(android.R.string.no, null) .setIcon(android.R.drawable.ic_dialog_alert) @@ -85,6 +101,30 @@ public class QueueRecyclerViewAdapter extends RecyclerView.Adapter { + Bundle extra = new Bundle(); + extra.putInt("queue_id", queues[position].getId()); + + Intent intent = new Intent(view.getContext(), EventListActivity.class); + intent.putExtras(extra); + + view.getContext().startActivity(intent); + }); + + viewHolder.getBinding().queueListItemStats.setText(Integer.toString(queues[position].getEventCount())); + + viewHolder.getBinding().queueListItemPlus.setOnClickListener((View view) -> { + Log.w(TAG, "TODO: Open editor"); + + Event event = Wrapper.getEventMaker().create(); + event.setTimestamp(System.currentTimeMillis()); + event.setComment("Lobster number " + System.currentTimeMillis()); + queues[position].addEvent(event); + + Log.w(TAG, "Create: " + event.toString() + " in " + queues[position]); + + reloadItems(); + }); } @Override @@ -93,18 +133,15 @@ public class QueueRecyclerViewAdapter extends RecyclerView.Adapter - NavHostFragment.findNavController(SecondFragment.this) - .navigate(R.id.action_SecondFragment_to_FirstFragment) - ); - } - -@Override - public void onDestroyView() { - super.onDestroyView(); - binding = null; - } - -} \ No newline at end of file diff --git a/Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/Utils.java b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/Utils.java new file mode 100644 index 0000000..7810dbf --- /dev/null +++ b/Yeeemp/app/src/main/java/art/pegasko/yeeemp/ui/activity/Utils.java @@ -0,0 +1,29 @@ +/** + * Copyright 2024 pegasko + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package art.pegasko.yeeemp.ui.activity; + +import java.text.SimpleDateFormat; +import java.util.Date; + +public class Utils { + public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; + + public static String formatTs(long timestamp) { + SimpleDateFormat sdf = new SimpleDateFormat(Utils.DATE_FORMAT); + return sdf.format(timestamp); + } +} diff --git a/Yeeemp/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/Yeeemp/app/src/main/res/drawable-v24/ic_launcher_foreground.xml index 2b068d1..92d0a4d 100644 --- a/Yeeemp/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +++ b/Yeeemp/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -1,3 +1,19 @@ + + + + diff --git a/Yeeemp/app/src/main/res/layout/activity_event_list.xml b/Yeeemp/app/src/main/res/layout/activity_event_list.xml new file mode 100644 index 0000000..3d1b7aa --- /dev/null +++ b/Yeeemp/app/src/main/res/layout/activity_event_list.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Yeeemp/app/src/main/res/layout/activity_main.xml b/Yeeemp/app/src/main/res/layout/activity_queue_list.xml similarity index 64% rename from Yeeemp/app/src/main/res/layout/activity_main.xml rename to Yeeemp/app/src/main/res/layout/activity_queue_list.xml index f1a0546..e471230 100644 --- a/Yeeemp/app/src/main/res/layout/activity_main.xml +++ b/Yeeemp/app/src/main/res/layout/activity_queue_list.xml @@ -1,3 +1,19 @@ + + + tools:context=".ui.activity.QueueListActivity"> - + + android:backgroundTint="@color/pegasko_green" /> \ No newline at end of file diff --git a/Yeeemp/app/src/main/res/layout/content_main.xml b/Yeeemp/app/src/main/res/layout/content_event_list.xml similarity index 55% rename from Yeeemp/app/src/main/res/layout/content_main.xml rename to Yeeemp/app/src/main/res/layout/content_event_list.xml index f1bb748..e2e137e 100644 --- a/Yeeemp/app/src/main/res/layout/content_main.xml +++ b/Yeeemp/app/src/main/res/layout/content_event_list.xml @@ -1,10 +1,26 @@ + + + android:id="@+id/content_event_list__list" /> \ No newline at end of file diff --git a/Yeeemp/app/src/main/res/layout/content_queue_list.xml b/Yeeemp/app/src/main/res/layout/content_queue_list.xml new file mode 100644 index 0000000..e22591d --- /dev/null +++ b/Yeeemp/app/src/main/res/layout/content_queue_list.xml @@ -0,0 +1,36 @@ + + + + + + + + \ No newline at end of file diff --git a/Yeeemp/app/src/main/res/layout/event_list_item.xml b/Yeeemp/app/src/main/res/layout/event_list_item.xml new file mode 100644 index 0000000..58414df --- /dev/null +++ b/Yeeemp/app/src/main/res/layout/event_list_item.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/Yeeemp/app/src/main/res/layout/fragment_first.xml b/Yeeemp/app/src/main/res/layout/fragment_first.xml deleted file mode 100644 index fcb2229..0000000 --- a/Yeeemp/app/src/main/res/layout/fragment_first.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - -