From 738e04a9d5ac968777d7d26e22e9c97cc88a44d8 Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Sun, 3 Dec 2023 12:11:36 -0600 Subject: [PATCH 01/52] initial points shop branch --- .../org/hackillinois/android/repository/LeaderboardRepository.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/org/hackillinois/android/repository/LeaderboardRepository.kt b/app/src/main/java/org/hackillinois/android/repository/LeaderboardRepository.kt index 6dff80dbe..bb8d60c65 100644 --- a/app/src/main/java/org/hackillinois/android/repository/LeaderboardRepository.kt +++ b/app/src/main/java/org/hackillinois/android/repository/LeaderboardRepository.kt @@ -15,6 +15,7 @@ class LeaderboardRepository { fun fetchLeaderboard(): LiveData> { // 'refreshAll()' coroutine is called only when leaderboard button on bottom app bar clicked refreshAll() + // locally stored database val lb = leaderboardDao.getLeaderboard() Log.d("LEADERBOARD CALL", lb.value.toString()) return lb From 5ab21e02e2c22bdbdbed67c858f2b2630bdd721b Mon Sep 17 00:00:00 2001 From: Leah Ludwikowski Date: Sun, 10 Dec 2023 14:33:25 -0600 Subject: [PATCH 02/52] Created model class and DAO for point shop to add to Room database --- .../6.json | 384 ++++++++++++++++++ .../hackillinois/android/database/Database.kt | 4 +- .../android/database/dao/ShopDao.kt | 28 ++ .../android/database/entity/ShopItem.kt | 16 + 4 files changed, 431 insertions(+), 1 deletion(-) create mode 100644 app/schemas/org.hackillinois.android.database.Database/6.json create mode 100644 app/src/main/java/org/hackillinois/android/database/dao/ShopDao.kt create mode 100644 app/src/main/java/org/hackillinois/android/database/entity/ShopItem.kt diff --git a/app/schemas/org.hackillinois.android.database.Database/6.json b/app/schemas/org.hackillinois.android.database.Database/6.json new file mode 100644 index 000000000..670f5a77d --- /dev/null +++ b/app/schemas/org.hackillinois.android.database.Database/6.json @@ -0,0 +1,384 @@ +{ + "formatVersion": 1, + "database": { + "version": 6, + "identityHash": "85721484037b09c072baa108f933fdda", + "entities": [ + { + "tableName": "qr_codes", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`userId` TEXT NOT NULL, `qrInfo` TEXT NOT NULL, `key` INTEGER NOT NULL, PRIMARY KEY(`key`))", + "fields": [ + { + "fieldPath": "userId", + "columnName": "userId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "qrInfo", + "columnName": "qrInfo", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "key", + "columnName": "key", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "key" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "attendees", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `firstName` TEXT NOT NULL, `lastName` TEXT NOT NULL, `dietary` TEXT NOT NULL, `key` INTEGER NOT NULL, PRIMARY KEY(`key`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "firstName", + "columnName": "firstName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "lastName", + "columnName": "lastName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dietary", + "columnName": "dietary", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "key", + "columnName": "key", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "key" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "users", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`userId` TEXT NOT NULL, `name` TEXT NOT NULL, `email` TEXT NOT NULL, `key` INTEGER NOT NULL, PRIMARY KEY(`key`))", + "fields": [ + { + "fieldPath": "userId", + "columnName": "userId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "email", + "columnName": "email", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "key", + "columnName": "key", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "key" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "events", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`eventId` TEXT NOT NULL, `name` TEXT NOT NULL, `description` TEXT NOT NULL, `startTime` INTEGER NOT NULL, `endTime` INTEGER NOT NULL, `locations` TEXT NOT NULL, `sponsor` TEXT NOT NULL, `eventType` TEXT NOT NULL, `points` TEXT NOT NULL, `isAsync` INTEGER NOT NULL, `isPrivate` INTEGER NOT NULL, `displayOnStaffCheckIn` INTEGER NOT NULL, PRIMARY KEY(`eventId`))", + "fields": [ + { + "fieldPath": "eventId", + "columnName": "eventId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "startTime", + "columnName": "startTime", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "endTime", + "columnName": "endTime", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "locations", + "columnName": "locations", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "sponsor", + "columnName": "sponsor", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "eventType", + "columnName": "eventType", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "points", + "columnName": "points", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "isAsync", + "columnName": "isAsync", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isPrivate", + "columnName": "isPrivate", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "displayOnStaffCheckIn", + "columnName": "displayOnStaffCheckIn", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "eventId" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "roles", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `roles` TEXT NOT NULL, `key` INTEGER NOT NULL, PRIMARY KEY(`key`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "roles", + "columnName": "roles", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "key", + "columnName": "key", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "key" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "profiles", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` TEXT NOT NULL, `displayName` TEXT NOT NULL, `discordTag` TEXT NOT NULL, `avatarUrl` TEXT NOT NULL, `points` INTEGER NOT NULL, `userId` TEXT NOT NULL, `foodWave` INTEGER NOT NULL, `key` INTEGER NOT NULL, PRIMARY KEY(`key`))", + "fields": [ + { + "fieldPath": "_id", + "columnName": "_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "displayName", + "columnName": "displayName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "discordTag", + "columnName": "discordTag", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "avatarUrl", + "columnName": "avatarUrl", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "points", + "columnName": "points", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "userId", + "columnName": "userId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "foodWave", + "columnName": "foodWave", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "key", + "columnName": "key", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "key" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "leaderboard", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `displayName` TEXT NOT NULL, `points` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "displayName", + "columnName": "displayName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "points", + "columnName": "points", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "shop", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `price` INTEGER NOT NULL, `isRaffle` INTEGER NOT NULL, `quantity` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "price", + "columnName": "price", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isRaffle", + "columnName": "isRaffle", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "quantity", + "columnName": "quantity", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '85721484037b09c072baa108f933fdda')" + ] + } +} \ No newline at end of file diff --git a/app/src/main/java/org/hackillinois/android/database/Database.kt b/app/src/main/java/org/hackillinois/android/database/Database.kt index 6bf61169b..40a9f36fd 100644 --- a/app/src/main/java/org/hackillinois/android/database/Database.kt +++ b/app/src/main/java/org/hackillinois/android/database/Database.kt @@ -15,8 +15,9 @@ import org.hackillinois.android.database.entity.Leaderboard Roles::class, Profile::class, Leaderboard::class, + ShopItem::class, ], - version = 5, + version = 6, ) abstract class Database : RoomDatabase() { @@ -27,4 +28,5 @@ abstract class Database : RoomDatabase() { abstract fun rolesDao(): RolesDao abstract fun profileDao(): ProfileDao abstract fun leaderboardDao(): LeaderboardDao + abstract fun shopDao(): ShopDao } diff --git a/app/src/main/java/org/hackillinois/android/database/dao/ShopDao.kt b/app/src/main/java/org/hackillinois/android/database/dao/ShopDao.kt new file mode 100644 index 000000000..c3bb8de84 --- /dev/null +++ b/app/src/main/java/org/hackillinois/android/database/dao/ShopDao.kt @@ -0,0 +1,28 @@ +package org.hackillinois.android.database.dao + +import androidx.lifecycle.LiveData +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query +import androidx.room.Transaction +import org.hackillinois.android.database.entity.ShopItem + +@Dao +interface ShopDao { + + @Query("SELECT * FROM shop") + fun getShop(): LiveData> + + @Query("DELETE FROM shop") + fun clearTable() + + @Insert(onConflict = OnConflictStrategy.REPLACE) + fun insertAll(items: List) + + @Transaction + fun clearTableAndInsertShopItems(items: List) { + clearTable() + insertAll(items) + } +} diff --git a/app/src/main/java/org/hackillinois/android/database/entity/ShopItem.kt b/app/src/main/java/org/hackillinois/android/database/entity/ShopItem.kt new file mode 100644 index 000000000..bc78d3508 --- /dev/null +++ b/app/src/main/java/org/hackillinois/android/database/entity/ShopItem.kt @@ -0,0 +1,16 @@ +package org.hackillinois.android.database.entity + +import androidx.room.Entity +import androidx.room.PrimaryKey +import androidx.room.TypeConverters +import org.hackillinois.android.database.Converters + +@Entity(tableName = "shop") +@TypeConverters(Converters::class) +data class ShopItem( + @PrimaryKey(autoGenerate = true) val id: Int, + var name: String, + var price: Int, + var isRaffle: Boolean, + var quantity: Int +) From 28dd2de90717b404672124fdca12523f98d3d0e9 Mon Sep 17 00:00:00 2001 From: Leah Ludwikowski Date: Sun, 10 Dec 2023 14:33:55 -0600 Subject: [PATCH 03/52] Created ShopRepository.kt file with instructions --- .../android/repository/ShopRepository.kt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 app/src/main/java/org/hackillinois/android/repository/ShopRepository.kt diff --git a/app/src/main/java/org/hackillinois/android/repository/ShopRepository.kt b/app/src/main/java/org/hackillinois/android/repository/ShopRepository.kt new file mode 100644 index 000000000..6c5483c9d --- /dev/null +++ b/app/src/main/java/org/hackillinois/android/repository/ShopRepository.kt @@ -0,0 +1,14 @@ +package org.hackillinois.android.repository + +import org.hackillinois.android.App + +class ShopRepository { + private val leaderboardDao = App.database.shopDao() + + // write fetchShop() and refreshAll() functions + // look at other repository functions for reference (i.e. LeaderboardRepository) + + companion object { + val instance: ShopRepository by lazy { ShopRepository() } + } +} From 991eaf9f93f08d3f9d6e3b321e9b1187c7fd0627 Mon Sep 17 00:00:00 2001 From: Leah Ludwikowski Date: Sat, 16 Dec 2023 15:16:40 -0500 Subject: [PATCH 04/52] Changed ShopItem format to have itemId --- .../6.json | 16 ++++++++-------- .../android/database/entity/ShopItem.kt | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/schemas/org.hackillinois.android.database.Database/6.json b/app/schemas/org.hackillinois.android.database.Database/6.json index 670f5a77d..21cb6f9ba 100644 --- a/app/schemas/org.hackillinois.android.database.Database/6.json +++ b/app/schemas/org.hackillinois.android.database.Database/6.json @@ -2,7 +2,7 @@ "formatVersion": 1, "database": { "version": 6, - "identityHash": "85721484037b09c072baa108f933fdda", + "identityHash": "8d245e8aeec91cee0e09b1799bf9bb37", "entities": [ { "tableName": "qr_codes", @@ -332,12 +332,12 @@ }, { "tableName": "shop", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `price` INTEGER NOT NULL, `isRaffle` INTEGER NOT NULL, `quantity` INTEGER NOT NULL)", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`itemId` TEXT NOT NULL, `name` TEXT NOT NULL, `price` INTEGER NOT NULL, `isRaffle` INTEGER NOT NULL, `quantity` INTEGER NOT NULL, PRIMARY KEY(`itemId`))", "fields": [ { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", + "fieldPath": "itemId", + "columnName": "itemId", + "affinity": "TEXT", "notNull": true }, { @@ -367,9 +367,9 @@ ], "primaryKey": { "columnNames": [ - "id" + "itemId" ], - "autoGenerate": true + "autoGenerate": false }, "indices": [], "foreignKeys": [] @@ -378,7 +378,7 @@ "views": [], "setupQueries": [ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '85721484037b09c072baa108f933fdda')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '8d245e8aeec91cee0e09b1799bf9bb37')" ] } } \ No newline at end of file diff --git a/app/src/main/java/org/hackillinois/android/database/entity/ShopItem.kt b/app/src/main/java/org/hackillinois/android/database/entity/ShopItem.kt index bc78d3508..2b7bbb2e3 100644 --- a/app/src/main/java/org/hackillinois/android/database/entity/ShopItem.kt +++ b/app/src/main/java/org/hackillinois/android/database/entity/ShopItem.kt @@ -8,7 +8,7 @@ import org.hackillinois.android.database.Converters @Entity(tableName = "shop") @TypeConverters(Converters::class) data class ShopItem( - @PrimaryKey(autoGenerate = true) val id: Int, + @PrimaryKey val itemId: String, var name: String, var price: Int, var isRaffle: Boolean, From 572664e1b1c7615dd4a8b988a1be981a86d27fb9 Mon Sep 17 00:00:00 2001 From: Leah Ludwikowski Date: Sun, 17 Dec 2023 14:45:03 -0500 Subject: [PATCH 05/52] Added api call for shop (tentative) --- app/src/main/java/org/hackillinois/android/API.kt | 6 ++++++ .../java/org/hackillinois/android/model/shop/ShopList.kt | 5 +++++ .../android/repository/LeaderboardRepository.kt | 3 +++ 3 files changed, 14 insertions(+) create mode 100644 app/src/main/java/org/hackillinois/android/model/shop/ShopList.kt diff --git a/app/src/main/java/org/hackillinois/android/API.kt b/app/src/main/java/org/hackillinois/android/API.kt index 5c981420a..ea75cdb53 100644 --- a/app/src/main/java/org/hackillinois/android/API.kt +++ b/app/src/main/java/org/hackillinois/android/API.kt @@ -5,6 +5,7 @@ import org.hackillinois.android.model.TimesWrapper import org.hackillinois.android.model.checkin.CheckIn import org.hackillinois.android.model.event.EventsList import org.hackillinois.android.model.leaderboard.LeaderboardList +import org.hackillinois.android.model.shop.ShopList import org.hackillinois.android.model.version.Version import org.hackillinois.android.notifications.DeviceToken import retrofit2.Call @@ -57,6 +58,11 @@ interface API { @GET("registration/attendee/") suspend fun attendee(): Attendee + // SHOP + + @GET("shop/") + suspend fun shop(): List + // STAFF @POST("staff/attendance/") diff --git a/app/src/main/java/org/hackillinois/android/model/shop/ShopList.kt b/app/src/main/java/org/hackillinois/android/model/shop/ShopList.kt new file mode 100644 index 000000000..ba637a54c --- /dev/null +++ b/app/src/main/java/org/hackillinois/android/model/shop/ShopList.kt @@ -0,0 +1,5 @@ +package org.hackillinois.android.model.shop + +import org.hackillinois.android.database.entity.ShopItem + +data class ShopList(val shopItems: List) diff --git a/app/src/main/java/org/hackillinois/android/repository/LeaderboardRepository.kt b/app/src/main/java/org/hackillinois/android/repository/LeaderboardRepository.kt index bb8d60c65..6ebc01855 100644 --- a/app/src/main/java/org/hackillinois/android/repository/LeaderboardRepository.kt +++ b/app/src/main/java/org/hackillinois/android/repository/LeaderboardRepository.kt @@ -24,6 +24,9 @@ class LeaderboardRepository { fun refreshAll() { GlobalScope.launch(Dispatchers.IO) { try { + val shop = App.getAPI().shop() + Log.d("SHOP", shop.toString()) + // break val leaderboard = App.getAPI().leaderboard() Log.d("LEADERBOARD REFRESH ALL", leaderboard.toString()) leaderboardDao.clearTableAndInsertProfiles(leaderboard.profiles) From 126e2c35ad2d518c1a722b366e8c3caafc5caab5 Mon Sep 17 00:00:00 2001 From: Leah Ludwikowski Date: Thu, 4 Jan 2024 08:54:23 -0500 Subject: [PATCH 06/52] fixed ktlint and added todo for api call (removed old one) --- .../main/java/org/hackillinois/android/API.kt | 4 +--- .../hackillinois/android/database/dao/ShopDao.kt | 1 - .../android/database/entity/ShopItem.kt | 16 ---------------- .../hackillinois/android/model/shop/ShopList.kt | 2 -- .../android/repository/LeaderboardRepository.kt | 3 --- 5 files changed, 1 insertion(+), 25 deletions(-) delete mode 100644 app/src/main/java/org/hackillinois/android/database/entity/ShopItem.kt diff --git a/app/src/main/java/org/hackillinois/android/API.kt b/app/src/main/java/org/hackillinois/android/API.kt index ea75cdb53..a6b2e355b 100644 --- a/app/src/main/java/org/hackillinois/android/API.kt +++ b/app/src/main/java/org/hackillinois/android/API.kt @@ -5,7 +5,6 @@ import org.hackillinois.android.model.TimesWrapper import org.hackillinois.android.model.checkin.CheckIn import org.hackillinois.android.model.event.EventsList import org.hackillinois.android.model.leaderboard.LeaderboardList -import org.hackillinois.android.model.shop.ShopList import org.hackillinois.android.model.version.Version import org.hackillinois.android.notifications.DeviceToken import retrofit2.Call @@ -60,8 +59,7 @@ interface API { // SHOP - @GET("shop/") - suspend fun shop(): List + // TODO: add api call shop() here // STAFF diff --git a/app/src/main/java/org/hackillinois/android/database/dao/ShopDao.kt b/app/src/main/java/org/hackillinois/android/database/dao/ShopDao.kt index c3bb8de84..c770f7f4b 100644 --- a/app/src/main/java/org/hackillinois/android/database/dao/ShopDao.kt +++ b/app/src/main/java/org/hackillinois/android/database/dao/ShopDao.kt @@ -6,7 +6,6 @@ import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query import androidx.room.Transaction -import org.hackillinois.android.database.entity.ShopItem @Dao interface ShopDao { diff --git a/app/src/main/java/org/hackillinois/android/database/entity/ShopItem.kt b/app/src/main/java/org/hackillinois/android/database/entity/ShopItem.kt deleted file mode 100644 index 2b7bbb2e3..000000000 --- a/app/src/main/java/org/hackillinois/android/database/entity/ShopItem.kt +++ /dev/null @@ -1,16 +0,0 @@ -package org.hackillinois.android.database.entity - -import androidx.room.Entity -import androidx.room.PrimaryKey -import androidx.room.TypeConverters -import org.hackillinois.android.database.Converters - -@Entity(tableName = "shop") -@TypeConverters(Converters::class) -data class ShopItem( - @PrimaryKey val itemId: String, - var name: String, - var price: Int, - var isRaffle: Boolean, - var quantity: Int -) diff --git a/app/src/main/java/org/hackillinois/android/model/shop/ShopList.kt b/app/src/main/java/org/hackillinois/android/model/shop/ShopList.kt index ba637a54c..2b60d95c7 100644 --- a/app/src/main/java/org/hackillinois/android/model/shop/ShopList.kt +++ b/app/src/main/java/org/hackillinois/android/model/shop/ShopList.kt @@ -1,5 +1,3 @@ package org.hackillinois.android.model.shop -import org.hackillinois.android.database.entity.ShopItem - data class ShopList(val shopItems: List) diff --git a/app/src/main/java/org/hackillinois/android/repository/LeaderboardRepository.kt b/app/src/main/java/org/hackillinois/android/repository/LeaderboardRepository.kt index 6ebc01855..bb8d60c65 100644 --- a/app/src/main/java/org/hackillinois/android/repository/LeaderboardRepository.kt +++ b/app/src/main/java/org/hackillinois/android/repository/LeaderboardRepository.kt @@ -24,9 +24,6 @@ class LeaderboardRepository { fun refreshAll() { GlobalScope.launch(Dispatchers.IO) { try { - val shop = App.getAPI().shop() - Log.d("SHOP", shop.toString()) - // break val leaderboard = App.getAPI().leaderboard() Log.d("LEADERBOARD REFRESH ALL", leaderboard.toString()) leaderboardDao.clearTableAndInsertProfiles(leaderboard.profiles) From 6c47e9c99f0e3e294f9cffedc854ca3f62144408 Mon Sep 17 00:00:00 2001 From: Leah Ludwikowski Date: Thu, 4 Jan 2024 09:02:00 -0500 Subject: [PATCH 07/52] added ShopItem back --- .../hackillinois/android/database/dao/ShopDao.kt | 1 + .../android/database/entity/ShopItem.kt | 16 ++++++++++++++++ .../hackillinois/android/model/shop/ShopList.kt | 3 --- 3 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 app/src/main/java/org/hackillinois/android/database/entity/ShopItem.kt delete mode 100644 app/src/main/java/org/hackillinois/android/model/shop/ShopList.kt diff --git a/app/src/main/java/org/hackillinois/android/database/dao/ShopDao.kt b/app/src/main/java/org/hackillinois/android/database/dao/ShopDao.kt index c770f7f4b..c3bb8de84 100644 --- a/app/src/main/java/org/hackillinois/android/database/dao/ShopDao.kt +++ b/app/src/main/java/org/hackillinois/android/database/dao/ShopDao.kt @@ -6,6 +6,7 @@ import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query import androidx.room.Transaction +import org.hackillinois.android.database.entity.ShopItem @Dao interface ShopDao { diff --git a/app/src/main/java/org/hackillinois/android/database/entity/ShopItem.kt b/app/src/main/java/org/hackillinois/android/database/entity/ShopItem.kt new file mode 100644 index 000000000..2b7bbb2e3 --- /dev/null +++ b/app/src/main/java/org/hackillinois/android/database/entity/ShopItem.kt @@ -0,0 +1,16 @@ +package org.hackillinois.android.database.entity + +import androidx.room.Entity +import androidx.room.PrimaryKey +import androidx.room.TypeConverters +import org.hackillinois.android.database.Converters + +@Entity(tableName = "shop") +@TypeConverters(Converters::class) +data class ShopItem( + @PrimaryKey val itemId: String, + var name: String, + var price: Int, + var isRaffle: Boolean, + var quantity: Int +) diff --git a/app/src/main/java/org/hackillinois/android/model/shop/ShopList.kt b/app/src/main/java/org/hackillinois/android/model/shop/ShopList.kt deleted file mode 100644 index 2b60d95c7..000000000 --- a/app/src/main/java/org/hackillinois/android/model/shop/ShopList.kt +++ /dev/null @@ -1,3 +0,0 @@ -package org.hackillinois.android.model.shop - -data class ShopList(val shopItems: List) From f1e883d9c8b32a80647d6c2f5c907d7fae0f9b10 Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Sun, 7 Jan 2024 19:04:55 -0600 Subject: [PATCH 08/52] points shop title text and color --- app/src/main/res/layout/fragment_leaderboard.xml | 4 ++-- app/src/main/res/values/strings.xml | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/layout/fragment_leaderboard.xml b/app/src/main/res/layout/fragment_leaderboard.xml index 21e5d5fa9..fce958b64 100644 --- a/app/src/main/res/layout/fragment_leaderboard.xml +++ b/app/src/main/res/layout/fragment_leaderboard.xml @@ -32,8 +32,8 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" android:fontFamily="@font/montserrat_bold" - android:textColor="@color/white" - android:text="@string/leaderboard" + android:textColor="@color/palePeach" + android:text="@string/pointshop" /> %d pts + + POINTS SHOP + PROFILE Dietary Restrictions From 1775f68e1aef21d62826b72c8254e20d8c2bb31b Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Sun, 7 Jan 2024 19:32:04 -0600 Subject: [PATCH 09/52] updated points shop background --- .../{home_bg.png => home_bg_2023.png} | Bin app/src/main/res/drawable/points_shop_bg.xml | 349 ++++++++++++++++++ .../main/res/layout/fragment_leaderboard.xml | 2 +- 3 files changed, 350 insertions(+), 1 deletion(-) rename app/src/main/res/drawable/{home_bg.png => home_bg_2023.png} (100%) create mode 100644 app/src/main/res/drawable/points_shop_bg.xml diff --git a/app/src/main/res/drawable/home_bg.png b/app/src/main/res/drawable/home_bg_2023.png similarity index 100% rename from app/src/main/res/drawable/home_bg.png rename to app/src/main/res/drawable/home_bg_2023.png diff --git a/app/src/main/res/drawable/points_shop_bg.xml b/app/src/main/res/drawable/points_shop_bg.xml new file mode 100644 index 000000000..ddf93798c --- /dev/null +++ b/app/src/main/res/drawable/points_shop_bg.xml @@ -0,0 +1,349 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_leaderboard.xml b/app/src/main/res/layout/fragment_leaderboard.xml index fce958b64..7b5b36999 100644 --- a/app/src/main/res/layout/fragment_leaderboard.xml +++ b/app/src/main/res/layout/fragment_leaderboard.xml @@ -13,7 +13,7 @@ android:layout_marginBottom="0dp" android:adjustViewBounds="true" android:scaleType="centerCrop" - android:src="@drawable/home_bg" + android:src="@drawable/points_shop_bg" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" From 53cca7a75d1817cd46f423c5cf8b719196789d55 Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Sun, 7 Jan 2024 19:35:44 -0600 Subject: [PATCH 10/52] fix build issues --- app/src/main/res/layout/fragment_event_info.xml | 2 +- app/src/main/res/layout/fragment_profile.xml | 2 +- app/src/main/res/layout/fragment_profile_not_logged_in.xml | 2 +- app/src/main/res/layout/fragment_schedule.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/res/layout/fragment_event_info.xml b/app/src/main/res/layout/fragment_event_info.xml index 2b884d122..31d7e3c18 100644 --- a/app/src/main/res/layout/fragment_event_info.xml +++ b/app/src/main/res/layout/fragment_event_info.xml @@ -11,7 +11,7 @@ android:layout_marginBottom="0dp" android:adjustViewBounds="true" android:scaleType="centerCrop" - android:src="@drawable/home_bg" + android:src="@drawable/home_bg_2023" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" diff --git a/app/src/main/res/layout/fragment_profile.xml b/app/src/main/res/layout/fragment_profile.xml index 2ca739cf4..aeb037bcd 100644 --- a/app/src/main/res/layout/fragment_profile.xml +++ b/app/src/main/res/layout/fragment_profile.xml @@ -14,7 +14,7 @@ android:layout_marginBottom="0dp" android:adjustViewBounds="true" android:scaleType="centerCrop" - android:src="@drawable/home_bg" + android:src="@drawable/home_bg_2023" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" diff --git a/app/src/main/res/layout/fragment_profile_not_logged_in.xml b/app/src/main/res/layout/fragment_profile_not_logged_in.xml index 776ffe707..be44a82df 100644 --- a/app/src/main/res/layout/fragment_profile_not_logged_in.xml +++ b/app/src/main/res/layout/fragment_profile_not_logged_in.xml @@ -17,7 +17,7 @@ app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" - android:src="@drawable/home_bg"/> + android:src="@drawable/home_bg_2023"/> + android:src="@drawable/home_bg_2023"/> Date: Sun, 7 Jan 2024 19:38:02 -0600 Subject: [PATCH 11/52] build issues --- app/src/main/res/layout/fragment_home.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 253996c68..a094b4d15 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -17,7 +17,7 @@ app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" - android:src="@drawable/home_bg"/> + android:src="@drawable/home_bg_2023"/> Date: Tue, 9 Jan 2024 21:03:10 -0600 Subject: [PATCH 12/52] imported points shop banner --- .../main/res/drawable/points_shop_banner.xml | 283 ++++++++++++++++++ 1 file changed, 283 insertions(+) create mode 100644 app/src/main/res/drawable/points_shop_banner.xml diff --git a/app/src/main/res/drawable/points_shop_banner.xml b/app/src/main/res/drawable/points_shop_banner.xml new file mode 100644 index 000000000..6b56649cc --- /dev/null +++ b/app/src/main/res/drawable/points_shop_banner.xml @@ -0,0 +1,283 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 76aef14335a2ac123dac2b03a70533e51e55ea23 Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Tue, 9 Jan 2024 22:14:43 -0600 Subject: [PATCH 13/52] implemented banner --- app/src/main/res/layout/fragment_leaderboard.xml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/layout/fragment_leaderboard.xml b/app/src/main/res/layout/fragment_leaderboard.xml index 7b5b36999..885c0b966 100644 --- a/app/src/main/res/layout/fragment_leaderboard.xml +++ b/app/src/main/res/layout/fragment_leaderboard.xml @@ -36,11 +36,20 @@ android:text="@string/pointshop" /> + + Date: Tue, 9 Jan 2024 22:36:15 -0600 Subject: [PATCH 14/52] changed leaderboard fragment name to points shop fragment --- .../android/view/leaderboard/LeaderboardFragment.kt | 8 ++++---- ...{fragment_leaderboard.xml => fragment_points_shop.xml} | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) rename app/src/main/res/layout/{fragment_leaderboard.xml => fragment_points_shop.xml} (95%) diff --git a/app/src/main/java/org/hackillinois/android/view/leaderboard/LeaderboardFragment.kt b/app/src/main/java/org/hackillinois/android/view/leaderboard/LeaderboardFragment.kt index deafd2e3a..00dfdd889 100644 --- a/app/src/main/java/org/hackillinois/android/view/leaderboard/LeaderboardFragment.kt +++ b/app/src/main/java/org/hackillinois/android/view/leaderboard/LeaderboardFragment.kt @@ -9,13 +9,13 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.core.content.ContextCompat -import androidx.core.content.ContextCompat.getDrawable import androidx.fragment.app.Fragment import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import kotlinx.android.synthetic.main.fragment_leaderboard.view.* +import kotlinx.android.synthetic.main.fragment_points_shop.view.* +import kotlinx.android.synthetic.main.fragment_points_shop.view.recyclerview_points_shop import org.hackillinois.android.R import org.hackillinois.android.database.entity.Leaderboard import org.hackillinois.android.viewmodel.LeaderboardViewModel @@ -43,11 +43,11 @@ class LeaderboardFragment : Fragment() { container: ViewGroup?, savedInstanceState: Bundle?, ): View? { - val view = inflater.inflate(R.layout.fragment_leaderboard, container, false) + val view = inflater.inflate(R.layout.fragment_points_shop, container, false) mAdapter = LeaderboardAdapter(leaderboard) - recyclerView = view.recyclerview_leaderboard.apply { + recyclerView = view.recyclerview_points_shop.apply { mLayoutManager = LinearLayoutManager(context) this.layoutManager = mLayoutManager this.adapter = mAdapter diff --git a/app/src/main/res/layout/fragment_leaderboard.xml b/app/src/main/res/layout/fragment_points_shop.xml similarity index 95% rename from app/src/main/res/layout/fragment_leaderboard.xml rename to app/src/main/res/layout/fragment_points_shop.xml index 885c0b966..a90ee95c4 100644 --- a/app/src/main/res/layout/fragment_leaderboard.xml +++ b/app/src/main/res/layout/fragment_points_shop.xml @@ -20,7 +20,7 @@ app:layout_constraintTop_toTopOf="parent" /> Date: Tue, 9 Jan 2024 22:57:41 -0600 Subject: [PATCH 15/52] added divider on top of recyclerview --- .../android/view/leaderboard/LeaderboardFragment.kt | 11 +++++++++-- ...eaderboard_divider.xml => points_shop_divider.xml} | 0 2 files changed, 9 insertions(+), 2 deletions(-) rename app/src/main/res/drawable/{leaderboard_divider.xml => points_shop_divider.xml} (100%) diff --git a/app/src/main/java/org/hackillinois/android/view/leaderboard/LeaderboardFragment.kt b/app/src/main/java/org/hackillinois/android/view/leaderboard/LeaderboardFragment.kt index 00dfdd889..ec3318018 100644 --- a/app/src/main/java/org/hackillinois/android/view/leaderboard/LeaderboardFragment.kt +++ b/app/src/main/java/org/hackillinois/android/view/leaderboard/LeaderboardFragment.kt @@ -64,18 +64,25 @@ class LeaderboardFragment : Fragment() { } class DividerItemDecorator(context: Context) : RecyclerView.ItemDecoration() { - private val mDivider: Drawable = ContextCompat.getDrawable(context, R.drawable.leaderboard_divider)!! + private val mDivider: Drawable = ContextCompat.getDrawable(context, R.drawable.points_shop_divider)!! override fun onDrawOver(canvas: Canvas, parent: RecyclerView, state: RecyclerView.State) { val dividerLeft = parent.paddingLeft val dividerRight = parent.width - parent.paddingRight val childCount = parent.childCount // how many items recyclerview has - for (i in 0..childCount - 2) { // minus 2 to account for zero index and skip last item + for (i in 0..childCount - 1) { // minus 2 to account for zero index and skip last item val child = parent.getChildAt(i) val params = child.layoutParams as RecyclerView.LayoutParams val dividerTop = child.bottom + params.bottomMargin val dividerBottom = dividerTop + mDivider.intrinsicHeight mDivider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom) mDivider.draw(canvas) + + if (i == 0) { + val topDividerTop = parent.paddingTop + val topDividerBottom = topDividerTop + mDivider.intrinsicHeight + mDivider.setBounds(dividerLeft, topDividerTop, dividerRight, topDividerBottom) + mDivider.draw(canvas) + } } } } diff --git a/app/src/main/res/drawable/leaderboard_divider.xml b/app/src/main/res/drawable/points_shop_divider.xml similarity index 100% rename from app/src/main/res/drawable/leaderboard_divider.xml rename to app/src/main/res/drawable/points_shop_divider.xml From d9beff9a504a0aee95973c4d01c3b9e491989c10 Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Tue, 9 Jan 2024 23:03:10 -0600 Subject: [PATCH 16/52] updated divider color and thickness --- .../android/view/leaderboard/LeaderboardFragment.kt | 4 ++-- app/src/main/res/drawable/points_shop_divider.xml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/hackillinois/android/view/leaderboard/LeaderboardFragment.kt b/app/src/main/java/org/hackillinois/android/view/leaderboard/LeaderboardFragment.kt index ec3318018..79a80adeb 100644 --- a/app/src/main/java/org/hackillinois/android/view/leaderboard/LeaderboardFragment.kt +++ b/app/src/main/java/org/hackillinois/android/view/leaderboard/LeaderboardFragment.kt @@ -51,7 +51,7 @@ class LeaderboardFragment : Fragment() { mLayoutManager = LinearLayoutManager(context) this.layoutManager = mLayoutManager this.adapter = mAdapter - addItemDecorationWithoutLastItem() + addDividers() } viewModel.leaderboardLiveData.observe( @@ -86,7 +86,7 @@ class LeaderboardFragment : Fragment() { } } } - fun RecyclerView.addItemDecorationWithoutLastItem() { + fun RecyclerView.addDividers() { if (layoutManager !is LinearLayoutManager) { return } diff --git a/app/src/main/res/drawable/points_shop_divider.xml b/app/src/main/res/drawable/points_shop_divider.xml index 746b2ff53..32e1fdffa 100644 --- a/app/src/main/res/drawable/points_shop_divider.xml +++ b/app/src/main/res/drawable/points_shop_divider.xml @@ -2,6 +2,6 @@ android:shape="rectangle"> - + android:height="10dp" /> + \ No newline at end of file From 37de6cf471c3a78753671f90dab972d4670302ac Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Wed, 10 Jan 2024 02:27:12 -0600 Subject: [PATCH 17/52] created separate shop files --- .../hackillinois/android/view/MainActivity.kt | 3 +- .../view/leaderboard/LeaderboardFragment.kt | 25 ++--- .../android/view/shop/ShopFragment.kt | 106 ++++++++++++++++++ .../main/res/drawable/leaderboard_divider.xml | 7 ++ .../main/res/layout/fragment_leaderboard.xml | 54 +++++++++ 5 files changed, 178 insertions(+), 17 deletions(-) create mode 100644 app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt create mode 100644 app/src/main/res/drawable/leaderboard_divider.xml create mode 100644 app/src/main/res/layout/fragment_leaderboard.xml diff --git a/app/src/main/java/org/hackillinois/android/view/MainActivity.kt b/app/src/main/java/org/hackillinois/android/view/MainActivity.kt index eb3453cea..bf38e19a7 100644 --- a/app/src/main/java/org/hackillinois/android/view/MainActivity.kt +++ b/app/src/main/java/org/hackillinois/android/view/MainActivity.kt @@ -24,6 +24,7 @@ import org.hackillinois.android.common.JWTUtilities import org.hackillinois.android.notifications.FirebaseTokenManager import org.hackillinois.android.view.home.HomeFragment import org.hackillinois.android.view.leaderboard.LeaderboardFragment +import org.hackillinois.android.view.shop.ShopFragment import org.hackillinois.android.view.profile.ProfileFragment import org.hackillinois.android.view.scanner.ScannerFragment import org.hackillinois.android.view.scanner.StaffScannerFragment @@ -87,7 +88,7 @@ class MainActivity : AppCompatActivity() { when (view) { bottomAppBar.homeButton -> switchFragment(HomeFragment(), false) bottomAppBar.scheduleButton -> switchFragment(ScheduleFragment(), false) - bottomAppBar.leaderboard -> switchFragment(LeaderboardFragment(), false) + bottomAppBar.leaderboard -> switchFragment(ShopFragment(), false) bottomAppBar.profile -> switchFragment(ProfileFragment(), false) else -> return@setOnClickListener } diff --git a/app/src/main/java/org/hackillinois/android/view/leaderboard/LeaderboardFragment.kt b/app/src/main/java/org/hackillinois/android/view/leaderboard/LeaderboardFragment.kt index 79a80adeb..cb80dd261 100644 --- a/app/src/main/java/org/hackillinois/android/view/leaderboard/LeaderboardFragment.kt +++ b/app/src/main/java/org/hackillinois/android/view/leaderboard/LeaderboardFragment.kt @@ -9,13 +9,13 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.core.content.ContextCompat +import androidx.core.content.ContextCompat.getDrawable import androidx.fragment.app.Fragment import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import kotlinx.android.synthetic.main.fragment_points_shop.view.* -import kotlinx.android.synthetic.main.fragment_points_shop.view.recyclerview_points_shop +import kotlinx.android.synthetic.main.fragment_leaderboard.view.* import org.hackillinois.android.R import org.hackillinois.android.database.entity.Leaderboard import org.hackillinois.android.viewmodel.LeaderboardViewModel @@ -43,15 +43,15 @@ class LeaderboardFragment : Fragment() { container: ViewGroup?, savedInstanceState: Bundle?, ): View? { - val view = inflater.inflate(R.layout.fragment_points_shop, container, false) + val view = inflater.inflate(R.layout.fragment_leaderboard, container, false) mAdapter = LeaderboardAdapter(leaderboard) - recyclerView = view.recyclerview_points_shop.apply { + recyclerView = view.recyclerview_leaderboard.apply { mLayoutManager = LinearLayoutManager(context) this.layoutManager = mLayoutManager this.adapter = mAdapter - addDividers() + addItemDecorationWithoutLastItem() } viewModel.leaderboardLiveData.observe( @@ -64,29 +64,22 @@ class LeaderboardFragment : Fragment() { } class DividerItemDecorator(context: Context) : RecyclerView.ItemDecoration() { - private val mDivider: Drawable = ContextCompat.getDrawable(context, R.drawable.points_shop_divider)!! + private val mDivider: Drawable = ContextCompat.getDrawable(context, R.drawable.leaderboard_divider)!! override fun onDrawOver(canvas: Canvas, parent: RecyclerView, state: RecyclerView.State) { val dividerLeft = parent.paddingLeft val dividerRight = parent.width - parent.paddingRight val childCount = parent.childCount // how many items recyclerview has - for (i in 0..childCount - 1) { // minus 2 to account for zero index and skip last item + for (i in 0..childCount - 2) { // minus 2 to account for zero index and skip last item val child = parent.getChildAt(i) val params = child.layoutParams as RecyclerView.LayoutParams val dividerTop = child.bottom + params.bottomMargin val dividerBottom = dividerTop + mDivider.intrinsicHeight mDivider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom) mDivider.draw(canvas) - - if (i == 0) { - val topDividerTop = parent.paddingTop - val topDividerBottom = topDividerTop + mDivider.intrinsicHeight - mDivider.setBounds(dividerLeft, topDividerTop, dividerRight, topDividerBottom) - mDivider.draw(canvas) - } } } } - fun RecyclerView.addDividers() { + fun RecyclerView.addItemDecorationWithoutLastItem() { if (layoutManager !is LinearLayoutManager) { return } @@ -102,4 +95,4 @@ class LeaderboardFragment : Fragment() { // var itemDecoration = DividerItemDecoration(this.context, DividerItemDecoration.VERTICAL) // itemDecoration.setDrawable(getDrawable(this.context, R.drawable.leaderboard_divider)!!) -// addItemDecoration(itemDecoration) +// addItemDecoration(itemDecoration) \ No newline at end of file diff --git a/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt b/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt new file mode 100644 index 000000000..448801deb --- /dev/null +++ b/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt @@ -0,0 +1,106 @@ +package org.hackillinois.android.view.shop + +import android.content.Context +import android.graphics.Canvas +import android.graphics.drawable.Drawable +import android.os.Bundle +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.core.content.ContextCompat +import androidx.fragment.app.Fragment +import androidx.lifecycle.Observer +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import kotlinx.android.synthetic.main.fragment_points_shop.view.* +import kotlinx.android.synthetic.main.fragment_points_shop.view.recyclerview_points_shop +import org.hackillinois.android.R +import org.hackillinois.android.database.entity.Leaderboard +import org.hackillinois.android.view.leaderboard.LeaderboardAdapter +import org.hackillinois.android.viewmodel.LeaderboardViewModel + +class ShopFragment : Fragment() { + + companion object { + fun newInstance() = ShopFragment() + } + + private lateinit var viewModel: LeaderboardViewModel + private var leaderboard: List = listOf() + private lateinit var recyclerView: RecyclerView + private lateinit var mLayoutManager: LinearLayoutManager + private lateinit var mAdapter: LeaderboardAdapter + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + viewModel = ViewModelProvider(this).get(LeaderboardViewModel::class.java) + viewModel.init() + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle?, + ): View? { + val view = inflater.inflate(R.layout.fragment_points_shop, container, false) + + mAdapter = LeaderboardAdapter(leaderboard) + + recyclerView = view.recyclerview_points_shop.apply { + mLayoutManager = LinearLayoutManager(context) + this.layoutManager = mLayoutManager + this.adapter = mAdapter + addDividers() + } + + viewModel.leaderboardLiveData.observe( + viewLifecycleOwner, + Observer { + updateLeaderboard(it) + }, + ) + return view + } + + class DividerItemDecorator(context: Context) : RecyclerView.ItemDecoration() { + private val mDivider: Drawable = ContextCompat.getDrawable(context, R.drawable.points_shop_divider)!! + override fun onDrawOver(canvas: Canvas, parent: RecyclerView, state: RecyclerView.State) { + val dividerLeft = parent.paddingLeft + val dividerRight = parent.width - parent.paddingRight + val childCount = parent.childCount // how many items recyclerview has + for (i in 0..childCount - 1) { // minus 2 to account for zero index and skip last item + val child = parent.getChildAt(i) + val params = child.layoutParams as RecyclerView.LayoutParams + val dividerTop = child.bottom + params.bottomMargin + val dividerBottom = dividerTop + mDivider.intrinsicHeight + mDivider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom) + mDivider.draw(canvas) + + if (i == 0) { + val topDividerTop = parent.paddingTop + val topDividerBottom = topDividerTop + mDivider.intrinsicHeight + mDivider.setBounds(dividerLeft, topDividerTop, dividerRight, topDividerBottom) + mDivider.draw(canvas) + } + } + } + } + fun RecyclerView.addDividers() { + if (layoutManager !is LinearLayoutManager) { + return + } + + addItemDecoration(DividerItemDecorator(context)) + } + + private fun updateLeaderboard(newLeaderboard: List) { + mAdapter.updateLeaderboard(newLeaderboard) + Log.d("UPDATE LEADERBOARD", leaderboard.toString()) + } +} + +// var itemDecoration = DividerItemDecoration(this.context, DividerItemDecoration.VERTICAL) +// itemDecoration.setDrawable(getDrawable(this.context, R.drawable.leaderboard_divider)!!) +// addItemDecoration(itemDecoration) \ No newline at end of file diff --git a/app/src/main/res/drawable/leaderboard_divider.xml b/app/src/main/res/drawable/leaderboard_divider.xml new file mode 100644 index 000000000..746b2ff53 --- /dev/null +++ b/app/src/main/res/drawable/leaderboard_divider.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_leaderboard.xml b/app/src/main/res/layout/fragment_leaderboard.xml new file mode 100644 index 000000000..c9a0ab076 --- /dev/null +++ b/app/src/main/res/layout/fragment_leaderboard.xml @@ -0,0 +1,54 @@ + + + + + + + + + + \ No newline at end of file From 5f744fb727e041dfa5607e56ad14aed5a7c95ed9 Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Wed, 10 Jan 2024 02:33:52 -0600 Subject: [PATCH 18/52] fixed ktlint --- .../main/java/org/hackillinois/android/view/MainActivity.kt | 3 +-- .../android/view/leaderboard/LeaderboardFragment.kt | 2 +- .../java/org/hackillinois/android/view/shop/ShopFragment.kt | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/hackillinois/android/view/MainActivity.kt b/app/src/main/java/org/hackillinois/android/view/MainActivity.kt index bf38e19a7..e1bdd9fb4 100644 --- a/app/src/main/java/org/hackillinois/android/view/MainActivity.kt +++ b/app/src/main/java/org/hackillinois/android/view/MainActivity.kt @@ -23,12 +23,11 @@ import org.hackillinois.android.common.FavoritesManager import org.hackillinois.android.common.JWTUtilities import org.hackillinois.android.notifications.FirebaseTokenManager import org.hackillinois.android.view.home.HomeFragment -import org.hackillinois.android.view.leaderboard.LeaderboardFragment -import org.hackillinois.android.view.shop.ShopFragment import org.hackillinois.android.view.profile.ProfileFragment import org.hackillinois.android.view.scanner.ScannerFragment import org.hackillinois.android.view.scanner.StaffScannerFragment import org.hackillinois.android.view.schedule.ScheduleFragment +import org.hackillinois.android.view.shop.ShopFragment import org.hackillinois.android.viewmodel.MainViewModel import kotlin.concurrent.thread diff --git a/app/src/main/java/org/hackillinois/android/view/leaderboard/LeaderboardFragment.kt b/app/src/main/java/org/hackillinois/android/view/leaderboard/LeaderboardFragment.kt index cb80dd261..deafd2e3a 100644 --- a/app/src/main/java/org/hackillinois/android/view/leaderboard/LeaderboardFragment.kt +++ b/app/src/main/java/org/hackillinois/android/view/leaderboard/LeaderboardFragment.kt @@ -95,4 +95,4 @@ class LeaderboardFragment : Fragment() { // var itemDecoration = DividerItemDecoration(this.context, DividerItemDecoration.VERTICAL) // itemDecoration.setDrawable(getDrawable(this.context, R.drawable.leaderboard_divider)!!) -// addItemDecoration(itemDecoration) \ No newline at end of file +// addItemDecoration(itemDecoration) diff --git a/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt b/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt index 448801deb..eaa505d3c 100644 --- a/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt +++ b/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt @@ -103,4 +103,4 @@ class ShopFragment : Fragment() { // var itemDecoration = DividerItemDecoration(this.context, DividerItemDecoration.VERTICAL) // itemDecoration.setDrawable(getDrawable(this.context, R.drawable.leaderboard_divider)!!) -// addItemDecoration(itemDecoration) \ No newline at end of file +// addItemDecoration(itemDecoration) From a20699501c614b130e026e00ba3a8e363e5da81d Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Wed, 10 Jan 2024 03:20:34 -0600 Subject: [PATCH 19/52] working on shoptile --- .../main/res/drawable/shop_potion_sticker.xml | 89 +++++++++++++++++++ app/src/main/res/layout/shop_tile.xml | 78 ++++++++++++++++ 2 files changed, 167 insertions(+) create mode 100644 app/src/main/res/drawable/shop_potion_sticker.xml create mode 100644 app/src/main/res/layout/shop_tile.xml diff --git a/app/src/main/res/drawable/shop_potion_sticker.xml b/app/src/main/res/drawable/shop_potion_sticker.xml new file mode 100644 index 000000000..af0f709c9 --- /dev/null +++ b/app/src/main/res/drawable/shop_potion_sticker.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/shop_tile.xml b/app/src/main/res/layout/shop_tile.xml new file mode 100644 index 000000000..f8a520401 --- /dev/null +++ b/app/src/main/res/layout/shop_tile.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From eb5fd02031f5ecfddc118e1478199609d4f6cf07 Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Thu, 11 Jan 2024 00:35:33 -0600 Subject: [PATCH 20/52] fixes based on leahs comments --- .../android/view/shop/ShopFragment.kt | 10 +++--- ..._shop_banner.xml => point_shop_banner.xml} | 0 .../{points_shop_bg.xml => point_shop_bg.xml} | 0 ...hop_divider.xml => point_shop_divider.xml} | 0 ...oints_shop.xml => fragment_point_shop.xml} | 33 ++++++++++++------- app/src/main/res/values/strings.xml | 2 +- 6 files changed, 27 insertions(+), 18 deletions(-) rename app/src/main/res/drawable/{points_shop_banner.xml => point_shop_banner.xml} (100%) rename app/src/main/res/drawable/{points_shop_bg.xml => point_shop_bg.xml} (100%) rename app/src/main/res/drawable/{points_shop_divider.xml => point_shop_divider.xml} (100%) rename app/src/main/res/layout/{fragment_points_shop.xml => fragment_point_shop.xml} (73%) diff --git a/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt b/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt index eaa505d3c..9b884962a 100644 --- a/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt +++ b/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt @@ -14,8 +14,8 @@ import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import kotlinx.android.synthetic.main.fragment_points_shop.view.* -import kotlinx.android.synthetic.main.fragment_points_shop.view.recyclerview_points_shop +import kotlinx.android.synthetic.main.fragment_point_shop.view.* +import kotlinx.android.synthetic.main.fragment_point_shop.view.recyclerview_point_shop import org.hackillinois.android.R import org.hackillinois.android.database.entity.Leaderboard import org.hackillinois.android.view.leaderboard.LeaderboardAdapter @@ -44,11 +44,11 @@ class ShopFragment : Fragment() { container: ViewGroup?, savedInstanceState: Bundle?, ): View? { - val view = inflater.inflate(R.layout.fragment_points_shop, container, false) + val view = inflater.inflate(R.layout.fragment_point_shop, container, false) mAdapter = LeaderboardAdapter(leaderboard) - recyclerView = view.recyclerview_points_shop.apply { + recyclerView = view.recyclerview_point_shop.apply { mLayoutManager = LinearLayoutManager(context) this.layoutManager = mLayoutManager this.adapter = mAdapter @@ -65,7 +65,7 @@ class ShopFragment : Fragment() { } class DividerItemDecorator(context: Context) : RecyclerView.ItemDecoration() { - private val mDivider: Drawable = ContextCompat.getDrawable(context, R.drawable.points_shop_divider)!! + private val mDivider: Drawable = ContextCompat.getDrawable(context, R.drawable.point_shop_divider)!! override fun onDrawOver(canvas: Canvas, parent: RecyclerView, state: RecyclerView.State) { val dividerLeft = parent.paddingLeft val dividerRight = parent.width - parent.paddingRight diff --git a/app/src/main/res/drawable/points_shop_banner.xml b/app/src/main/res/drawable/point_shop_banner.xml similarity index 100% rename from app/src/main/res/drawable/points_shop_banner.xml rename to app/src/main/res/drawable/point_shop_banner.xml diff --git a/app/src/main/res/drawable/points_shop_bg.xml b/app/src/main/res/drawable/point_shop_bg.xml similarity index 100% rename from app/src/main/res/drawable/points_shop_bg.xml rename to app/src/main/res/drawable/point_shop_bg.xml diff --git a/app/src/main/res/drawable/points_shop_divider.xml b/app/src/main/res/drawable/point_shop_divider.xml similarity index 100% rename from app/src/main/res/drawable/points_shop_divider.xml rename to app/src/main/res/drawable/point_shop_divider.xml diff --git a/app/src/main/res/layout/fragment_points_shop.xml b/app/src/main/res/layout/fragment_point_shop.xml similarity index 73% rename from app/src/main/res/layout/fragment_points_shop.xml rename to app/src/main/res/layout/fragment_point_shop.xml index a90ee95c4..59e958d24 100644 --- a/app/src/main/res/layout/fragment_points_shop.xml +++ b/app/src/main/res/layout/fragment_point_shop.xml @@ -9,18 +9,24 @@ + + - POINTS SHOP + POINT SHOP PROFILE From 8a861f86c7932fada56460d685d69099f3bab1c2 Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Thu, 11 Jan 2024 01:19:32 -0600 Subject: [PATCH 21/52] added shop files needed for api calls, made api calls --- .../main/java/org/hackillinois/android/API.kt | 4 +- .../android/model/shop/ShopList.kt | 5 ++ .../android/repository/ShopRepository.kt | 31 ++++++++++-- .../android/view/shop/ShopAdapter.kt | 50 +++++++++++++++++++ .../android/view/shop/ShopFragment.kt | 2 - .../main/res/drawable/point_shop_tile_bg.xml | 10 ++++ 6 files changed, 96 insertions(+), 6 deletions(-) create mode 100644 app/src/main/java/org/hackillinois/android/model/shop/ShopList.kt create mode 100644 app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt create mode 100644 app/src/main/res/drawable/point_shop_tile_bg.xml diff --git a/app/src/main/java/org/hackillinois/android/API.kt b/app/src/main/java/org/hackillinois/android/API.kt index 5026513e8..70fd52b76 100644 --- a/app/src/main/java/org/hackillinois/android/API.kt +++ b/app/src/main/java/org/hackillinois/android/API.kt @@ -4,6 +4,7 @@ import org.hackillinois.android.database.entity.* import org.hackillinois.android.model.checkin.CheckIn import org.hackillinois.android.model.event.EventsList import org.hackillinois.android.model.leaderboard.LeaderboardList +import org.hackillinois.android.model.shop.ShopList import org.hackillinois.android.model.version.Version import org.hackillinois.android.notifications.DeviceToken import retrofit2.Call @@ -58,7 +59,8 @@ interface API { // SHOP - // TODO: add api call shop() here + @GET("shop/") + suspend fun shop(): ShopList // STAFF diff --git a/app/src/main/java/org/hackillinois/android/model/shop/ShopList.kt b/app/src/main/java/org/hackillinois/android/model/shop/ShopList.kt new file mode 100644 index 000000000..d54893f47 --- /dev/null +++ b/app/src/main/java/org/hackillinois/android/model/shop/ShopList.kt @@ -0,0 +1,5 @@ +package org.hackillinois.android.model.shop + +import org.hackillinois.android.database.entity.ShopItem + +data class ShopList(var items: List) diff --git a/app/src/main/java/org/hackillinois/android/repository/ShopRepository.kt b/app/src/main/java/org/hackillinois/android/repository/ShopRepository.kt index 6c5483c9d..d02b3ce87 100644 --- a/app/src/main/java/org/hackillinois/android/repository/ShopRepository.kt +++ b/app/src/main/java/org/hackillinois/android/repository/ShopRepository.kt @@ -1,12 +1,37 @@ package org.hackillinois.android.repository +import android.util.Log +import androidx.lifecycle.LiveData +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch import org.hackillinois.android.App +import org.hackillinois.android.database.entity.ShopItem +import java.lang.Exception class ShopRepository { - private val leaderboardDao = App.database.shopDao() + private val shopDao = App.database.shopDao() - // write fetchShop() and refreshAll() functions - // look at other repository functions for reference (i.e. LeaderboardRepository) + fun fetchShop(): LiveData> { + // 'refreshAll()' coroutine is called only when shop button on bottom app bar clicked + refreshAll() + // locally stored database + val lb = shopDao.getShop() + Log.d("SHOP CALL", lb.value.toString()) + return lb + } + + fun refreshAll() { + GlobalScope.launch(Dispatchers.IO) { + try { + val shop = App.getAPI().shop() + Log.d("SHOP REFRESH ALL", shop.toString()) + shopDao.clearTableAndInsertShopItems(shop.items) + } catch (e: Exception) { + Log.e("SHOP REFRESH ALL", e.toString()) + } + } + } companion object { val instance: ShopRepository by lazy { ShopRepository() } diff --git a/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt b/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt new file mode 100644 index 000000000..0db920152 --- /dev/null +++ b/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt @@ -0,0 +1,50 @@ +package org.hackillinois.android.view.shop + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import kotlinx.android.synthetic.main.shop_tile.view.* +import org.hackillinois.android.R +import org.hackillinois.android.database.entity.ShopItem + +class ShopAdapter(private var itemList: List) : + RecyclerView.Adapter() { + private lateinit var context: Context + + inner class ViewHolder(parent: View) : RecyclerView.ViewHolder(parent) + + // onCreateViewHolder used to display scrollable list of items + // implemented as part of RecyclerView's adapter, responsible for creating new ViewHolder objects + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val layoutResource = R.layout.shop_tile + val view = LayoutInflater.from(parent.context).inflate(layoutResource, parent, false) + val viewHolder = ViewHolder(view) + context = parent.context + return viewHolder + } + + override fun getItemCount() = itemList.size + + // onBindViewHolder called when ViewHolder needs to be filled with data + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val item = itemList[position] + // populating views within ViewHolder with data from 'item' + // position is zero-indexed but we want the leaderboard to start at 1 + bind(item, holder.itemView, position + 1) + } + + private fun bind(item: ShopItem, itemView: View, position: Int) { + itemView.apply { + shopItemTextView.text = item.name + // shopItemImageView.image or something = item.imageurl + shopCardView.setBackgroundResource(R.drawable.point_shop_tile_bg) + } + } + + fun updateShop(shopItem: List) { + this.itemList = shopItem + notifyDataSetChanged() + } +} diff --git a/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt b/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt index 9b884962a..320f14258 100644 --- a/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt +++ b/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt @@ -4,7 +4,6 @@ import android.content.Context import android.graphics.Canvas import android.graphics.drawable.Drawable import android.os.Bundle -import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -97,7 +96,6 @@ class ShopFragment : Fragment() { private fun updateLeaderboard(newLeaderboard: List) { mAdapter.updateLeaderboard(newLeaderboard) - Log.d("UPDATE LEADERBOARD", leaderboard.toString()) } } diff --git a/app/src/main/res/drawable/point_shop_tile_bg.xml b/app/src/main/res/drawable/point_shop_tile_bg.xml new file mode 100644 index 000000000..0a9dcda45 --- /dev/null +++ b/app/src/main/res/drawable/point_shop_tile_bg.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file From 22b5a08586c308bac1d19f9314be17a0314f0cb8 Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Thu, 11 Jan 2024 01:23:55 -0600 Subject: [PATCH 22/52] added shopViewModel --- .../android/viewmodel/ShopViewModel.kt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt diff --git a/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt b/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt new file mode 100644 index 000000000..977927f30 --- /dev/null +++ b/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt @@ -0,0 +1,16 @@ +package org.hackillinois.android.viewmodel + +import androidx.lifecycle.LiveData +import androidx.lifecycle.ViewModel +import org.hackillinois.android.database.entity.ShopItem +import org.hackillinois.android.repository.ShopRepository + +class ShopViewModel : ViewModel() { + private val shopRepository = ShopRepository.instance + + lateinit var shopLiveData: LiveData> + + fun init() { + shopLiveData = shopRepository.fetchShop() + } +} From 71487520155419cc537e99b8a52c53f736015a60 Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Fri, 12 Jan 2024 23:41:54 -0600 Subject: [PATCH 23/52] updated ShopFragment --- .../android/view/shop/ShopFragment.kt | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt b/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt index 320f14258..3677bf29b 100644 --- a/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt +++ b/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt @@ -16,9 +16,8 @@ import androidx.recyclerview.widget.RecyclerView import kotlinx.android.synthetic.main.fragment_point_shop.view.* import kotlinx.android.synthetic.main.fragment_point_shop.view.recyclerview_point_shop import org.hackillinois.android.R -import org.hackillinois.android.database.entity.Leaderboard -import org.hackillinois.android.view.leaderboard.LeaderboardAdapter -import org.hackillinois.android.viewmodel.LeaderboardViewModel +import org.hackillinois.android.database.entity.ShopItem +import org.hackillinois.android.viewmodel.ShopViewModel class ShopFragment : Fragment() { @@ -26,15 +25,15 @@ class ShopFragment : Fragment() { fun newInstance() = ShopFragment() } - private lateinit var viewModel: LeaderboardViewModel - private var leaderboard: List = listOf() + private lateinit var viewModel: ShopViewModel + private var shop: List = listOf() private lateinit var recyclerView: RecyclerView private lateinit var mLayoutManager: LinearLayoutManager - private lateinit var mAdapter: LeaderboardAdapter + private lateinit var mAdapter: ShopAdapter override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - viewModel = ViewModelProvider(this).get(LeaderboardViewModel::class.java) + viewModel = ViewModelProvider(this).get(ShopViewModel::class.java) viewModel.init() } @@ -45,7 +44,7 @@ class ShopFragment : Fragment() { ): View? { val view = inflater.inflate(R.layout.fragment_point_shop, container, false) - mAdapter = LeaderboardAdapter(leaderboard) + mAdapter = ShopAdapter(shop) recyclerView = view.recyclerview_point_shop.apply { mLayoutManager = LinearLayoutManager(context) @@ -54,10 +53,10 @@ class ShopFragment : Fragment() { addDividers() } - viewModel.leaderboardLiveData.observe( + viewModel.shopLiveData.observe( viewLifecycleOwner, Observer { - updateLeaderboard(it) + updateShop(it) }, ) return view @@ -94,8 +93,8 @@ class ShopFragment : Fragment() { addItemDecoration(DividerItemDecorator(context)) } - private fun updateLeaderboard(newLeaderboard: List) { - mAdapter.updateLeaderboard(newLeaderboard) + private fun updateShop(newShop: List) { + mAdapter.updateShop(newShop) } } From 372d8732257b8bc724e21a763373dbea61c6efb8 Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Fri, 12 Jan 2024 23:49:40 -0600 Subject: [PATCH 24/52] fixed point shop textview constraints --- app/src/main/res/layout/fragment_point_shop.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/src/main/res/layout/fragment_point_shop.xml b/app/src/main/res/layout/fragment_point_shop.xml index 59e958d24..f7e619951 100644 --- a/app/src/main/res/layout/fragment_point_shop.xml +++ b/app/src/main/res/layout/fragment_point_shop.xml @@ -31,12 +31,10 @@ android:layout_height="wrap_content" android:layout_marginStart="29dp" android:layout_marginEnd="32dp" - android:layout_marginTop="30dp" android:textSize="24sp" android:gravity="start" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toBottomOf="@id/guidelineTop" android:fontFamily="@font/montserrat_bold" android:textColor="@color/palePeach" From 30068ebc0237f6d9b516d7c1f963dff60fc3f2f1 Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Sat, 13 Jan 2024 00:08:12 -0600 Subject: [PATCH 25/52] shop recyclerview displays --- app/src/main/java/org/hackillinois/android/API.kt | 3 +-- .../org/hackillinois/android/database/entity/ShopItem.kt | 3 ++- .../java/org/hackillinois/android/model/shop/ShopList.kt | 5 ----- .../org/hackillinois/android/repository/ShopRepository.kt | 2 +- 4 files changed, 4 insertions(+), 9 deletions(-) delete mode 100644 app/src/main/java/org/hackillinois/android/model/shop/ShopList.kt diff --git a/app/src/main/java/org/hackillinois/android/API.kt b/app/src/main/java/org/hackillinois/android/API.kt index 70fd52b76..5bac0bd24 100644 --- a/app/src/main/java/org/hackillinois/android/API.kt +++ b/app/src/main/java/org/hackillinois/android/API.kt @@ -4,7 +4,6 @@ import org.hackillinois.android.database.entity.* import org.hackillinois.android.model.checkin.CheckIn import org.hackillinois.android.model.event.EventsList import org.hackillinois.android.model.leaderboard.LeaderboardList -import org.hackillinois.android.model.shop.ShopList import org.hackillinois.android.model.version.Version import org.hackillinois.android.notifications.DeviceToken import retrofit2.Call @@ -60,7 +59,7 @@ interface API { // SHOP @GET("shop/") - suspend fun shop(): ShopList + suspend fun shop(): List // STAFF diff --git a/app/src/main/java/org/hackillinois/android/database/entity/ShopItem.kt b/app/src/main/java/org/hackillinois/android/database/entity/ShopItem.kt index 2b7bbb2e3..5111d5609 100644 --- a/app/src/main/java/org/hackillinois/android/database/entity/ShopItem.kt +++ b/app/src/main/java/org/hackillinois/android/database/entity/ShopItem.kt @@ -12,5 +12,6 @@ data class ShopItem( var name: String, var price: Int, var isRaffle: Boolean, - var quantity: Int + var quantity: Int, + var imageURL: String, ) diff --git a/app/src/main/java/org/hackillinois/android/model/shop/ShopList.kt b/app/src/main/java/org/hackillinois/android/model/shop/ShopList.kt deleted file mode 100644 index d54893f47..000000000 --- a/app/src/main/java/org/hackillinois/android/model/shop/ShopList.kt +++ /dev/null @@ -1,5 +0,0 @@ -package org.hackillinois.android.model.shop - -import org.hackillinois.android.database.entity.ShopItem - -data class ShopList(var items: List) diff --git a/app/src/main/java/org/hackillinois/android/repository/ShopRepository.kt b/app/src/main/java/org/hackillinois/android/repository/ShopRepository.kt index d02b3ce87..a3c106555 100644 --- a/app/src/main/java/org/hackillinois/android/repository/ShopRepository.kt +++ b/app/src/main/java/org/hackillinois/android/repository/ShopRepository.kt @@ -26,7 +26,7 @@ class ShopRepository { try { val shop = App.getAPI().shop() Log.d("SHOP REFRESH ALL", shop.toString()) - shopDao.clearTableAndInsertShopItems(shop.items) + shopDao.clearTableAndInsertShopItems(shop) } catch (e: Exception) { Log.e("SHOP REFRESH ALL", e.toString()) } From 5e9c3131ceb3326e05d42c33412b5749aaf4887a Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Sat, 13 Jan 2024 00:12:25 -0600 Subject: [PATCH 26/52] added imageURL field to ShopItem --- .../6.json | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/app/schemas/org.hackillinois.android.database.Database/6.json b/app/schemas/org.hackillinois.android.database.Database/6.json index 21cb6f9ba..3164be356 100644 --- a/app/schemas/org.hackillinois.android.database.Database/6.json +++ b/app/schemas/org.hackillinois.android.database.Database/6.json @@ -2,7 +2,7 @@ "formatVersion": 1, "database": { "version": 6, - "identityHash": "8d245e8aeec91cee0e09b1799bf9bb37", + "identityHash": "e1e02bab837cae338b4c2cc99ea2c05a", "entities": [ { "tableName": "qr_codes", @@ -332,7 +332,7 @@ }, { "tableName": "shop", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`itemId` TEXT NOT NULL, `name` TEXT NOT NULL, `price` INTEGER NOT NULL, `isRaffle` INTEGER NOT NULL, `quantity` INTEGER NOT NULL, PRIMARY KEY(`itemId`))", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`itemId` TEXT NOT NULL, `name` TEXT NOT NULL, `price` INTEGER NOT NULL, `isRaffle` INTEGER NOT NULL, `quantity` INTEGER NOT NULL, `imageURL` TEXT NOT NULL, PRIMARY KEY(`itemId`))", "fields": [ { "fieldPath": "itemId", @@ -363,6 +363,12 @@ "columnName": "quantity", "affinity": "INTEGER", "notNull": true + }, + { + "fieldPath": "imageURL", + "columnName": "imageURL", + "affinity": "TEXT", + "notNull": true } ], "primaryKey": { @@ -378,7 +384,7 @@ "views": [], "setupQueries": [ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '8d245e8aeec91cee0e09b1799bf9bb37')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'e1e02bab837cae338b4c2cc99ea2c05a')" ] } } \ No newline at end of file From 3721bfac7fecec2495b7c75a791039b95f5b8fc1 Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Sat, 13 Jan 2024 02:35:46 -0600 Subject: [PATCH 27/52] rough finish of shop_tile, imageView does not work and paddings probably need to be adjusted for textViews --- .../android/view/shop/ShopAdapter.kt | 33 ++++++++- app/src/main/res/drawable/coin.xml | 28 ++++++++ app/src/main/res/drawable/faded_coin.xml | 33 +++++++++ .../main/res/drawable/point_shop_tile_bg.xml | 6 +- .../res/drawable/rounded_dark_forest_bg.xml | 6 ++ app/src/main/res/layout/shop_tile.xml | 70 ++++++++++++++++--- app/src/main/res/values/colors.xml | 2 + 7 files changed, 164 insertions(+), 14 deletions(-) create mode 100644 app/src/main/res/drawable/coin.xml create mode 100644 app/src/main/res/drawable/faded_coin.xml create mode 100644 app/src/main/res/drawable/rounded_dark_forest_bg.xml diff --git a/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt b/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt index 0db920152..663f6cc00 100644 --- a/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt +++ b/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt @@ -1,6 +1,10 @@ package org.hackillinois.android.view.shop import android.content.Context +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.os.Handler +import android.os.Looper import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -8,6 +12,7 @@ import androidx.recyclerview.widget.RecyclerView import kotlinx.android.synthetic.main.shop_tile.view.* import org.hackillinois.android.R import org.hackillinois.android.database.entity.ShopItem +import java.util.concurrent.Executors class ShopAdapter(private var itemList: List) : RecyclerView.Adapter() { @@ -37,9 +42,33 @@ class ShopAdapter(private var itemList: List) : private fun bind(item: ShopItem, itemView: View, position: Int) { itemView.apply { - shopItemTextView.text = item.name - // shopItemImageView.image or something = item.imageurl shopCardView.setBackgroundResource(R.drawable.point_shop_tile_bg) + shopItemTextView.text = item.name + priceTextView.text = item.price.toString() + quantityTextView.text = item.quantity.toString() + // Declaring executor to parse the URL + val executor = Executors.newSingleThreadExecutor() + // Once the executor parses the URL and receives the image, handler will load it + // in the ImageView + val handler = Handler(Looper.getMainLooper()) + // Initializing the image + var image: Bitmap? = null + val imageURL = item.imageURL + executor.execute() { + try { + val `in` = java.net.URL(imageURL).openStream() + image = BitmapFactory.decodeStream(`in`) + + // Only for making changes in UI + handler.post { + shopItemImageView.setImageBitmap(image) + } + } + // If the URL doesnot point to image or any other kind of failure + catch (e: Exception) { + e.printStackTrace() + } + } } } diff --git a/app/src/main/res/drawable/coin.xml b/app/src/main/res/drawable/coin.xml new file mode 100644 index 000000000..bf8f2ff11 --- /dev/null +++ b/app/src/main/res/drawable/coin.xml @@ -0,0 +1,28 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/faded_coin.xml b/app/src/main/res/drawable/faded_coin.xml new file mode 100644 index 000000000..55fe21019 --- /dev/null +++ b/app/src/main/res/drawable/faded_coin.xml @@ -0,0 +1,33 @@ + + + + + + + + + diff --git a/app/src/main/res/drawable/point_shop_tile_bg.xml b/app/src/main/res/drawable/point_shop_tile_bg.xml index 0a9dcda45..59e79b365 100644 --- a/app/src/main/res/drawable/point_shop_tile_bg.xml +++ b/app/src/main/res/drawable/point_shop_tile_bg.xml @@ -1,10 +1,10 @@ - + - \ No newline at end of file diff --git a/app/src/main/res/drawable/rounded_dark_forest_bg.xml b/app/src/main/res/drawable/rounded_dark_forest_bg.xml new file mode 100644 index 000000000..4dc5229e1 --- /dev/null +++ b/app/src/main/res/drawable/rounded_dark_forest_bg.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/layout/shop_tile.xml b/app/src/main/res/layout/shop_tile.xml index f8a520401..d2d4c074c 100644 --- a/app/src/main/res/layout/shop_tile.xml +++ b/app/src/main/res/layout/shop_tile.xml @@ -16,9 +16,9 @@ > + android:layout_height="match_parent" + android:layout_margin="4dp"> + app:layout_constraintVertical_bias="0.483" /> + + + + + + + + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 7f4e77120..c5f11c886 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -3,6 +3,7 @@ #FFFFFF + #80FFFFFF #A5DAD5 #d7d4b8 #212121 @@ -44,6 +45,7 @@ #A5DAD5 #ACCEBE #0D3F41 + #800D3F41 #A61E00 #964C1A #662B13 From 8f7252379c960a5639d0e38e10953cd04e859559 Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Sat, 13 Jan 2024 02:44:06 -0600 Subject: [PATCH 28/52] fixed quantity string --- .../java/org/hackillinois/android/view/shop/ShopAdapter.kt | 3 ++- app/src/main/res/values/strings.xml | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt b/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt index 663f6cc00..3ce9842ff 100644 --- a/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt +++ b/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt @@ -45,7 +45,8 @@ class ShopAdapter(private var itemList: List) : shopCardView.setBackgroundResource(R.drawable.point_shop_tile_bg) shopItemTextView.text = item.name priceTextView.text = item.price.toString() - quantityTextView.text = item.quantity.toString() + val quantity = item.quantity + quantityTextView.text = resources.getString(R.string.shopquantity, quantity) // Declaring executor to parse the URL val executor = Executors.newSingleThreadExecutor() // Once the executor parses the URL and receives the image, handler will load it diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3a396774a..12256db90 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -66,8 +66,9 @@ %d pts - + POINT SHOP + %d Left PROFILE @@ -90,4 +91,6 @@ You must log in to use this feature! Go to the Profile tab to logout. + + From e976eaa644822c70deefe4e96514f358b04c0b13 Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Sat, 13 Jan 2024 03:03:35 -0600 Subject: [PATCH 29/52] trying to add autosizing text for long item names, adjusted padding --- app/src/main/res/drawable/point_shop_tile_bg.xml | 4 ++-- app/src/main/res/layout/shop_tile.xml | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/src/main/res/drawable/point_shop_tile_bg.xml b/app/src/main/res/drawable/point_shop_tile_bg.xml index 59e79b365..535498e81 100644 --- a/app/src/main/res/drawable/point_shop_tile_bg.xml +++ b/app/src/main/res/drawable/point_shop_tile_bg.xml @@ -2,9 +2,9 @@ - \ No newline at end of file diff --git a/app/src/main/res/layout/shop_tile.xml b/app/src/main/res/layout/shop_tile.xml index d2d4c074c..26ff92b61 100644 --- a/app/src/main/res/layout/shop_tile.xml +++ b/app/src/main/res/layout/shop_tile.xml @@ -45,7 +45,10 @@ android:maxLines="2" android:text="Potion Sticker" android:textColor="@color/midnight" - android:textSize="14sp" + app:autoSizeTextType="uniform" + app:autoSizeMinTextSize="3sp" + app:autoSizeMaxTextSize="14sp" + app:autoSizeStepGranularity="2sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toEndOf="@id/shopItemImageView" app:layout_constraintTop_toTopOf="parent" @@ -55,12 +58,12 @@ android:id="@+id/costandQuantityView" android:layout_width="143dp" android:layout_height="33dp" - android:layout_marginEnd="4dp" android:background="@drawable/rounded_dark_forest_bg" android:fontFamily="@font/montserrat_bold" android:gravity="center" android:maxWidth="180dp" android:maxLines="1" + app:layout_constraintStart_toEndOf="@id/shopItemImageView" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@+id/shopItemTextView" From 17c3bda9bfaaf189b4a0487ca7ead182fef5cefe Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Sat, 13 Jan 2024 03:12:39 -0600 Subject: [PATCH 30/52] changed to dark fantasy bg png --- app/src/main/res/layout/fragment_point_shop.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/layout/fragment_point_shop.xml b/app/src/main/res/layout/fragment_point_shop.xml index f7e619951..6fcee36ce 100644 --- a/app/src/main/res/layout/fragment_point_shop.xml +++ b/app/src/main/res/layout/fragment_point_shop.xml @@ -12,7 +12,7 @@ android:layout_height="0dp" android:scaleType="centerCrop" android:adjustViewBounds="true" - android:src="@drawable/point_shop_bg" + android:src="@drawable/dark_fantasy_bg_2024" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" From 5a12c9281c8c1cceb073487c5147be08f4ce49d8 Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Sat, 13 Jan 2024 04:02:55 -0600 Subject: [PATCH 31/52] added coins field in Profile.kt --- .../java/org/hackillinois/android/database/entity/Profile.kt | 1 + .../main/java/org/hackillinois/android/view/shop/ShopAdapter.kt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/app/src/main/java/org/hackillinois/android/database/entity/Profile.kt b/app/src/main/java/org/hackillinois/android/database/entity/Profile.kt index ed4742c7c..7a16684d2 100644 --- a/app/src/main/java/org/hackillinois/android/database/entity/Profile.kt +++ b/app/src/main/java/org/hackillinois/android/database/entity/Profile.kt @@ -15,6 +15,7 @@ data class Profile( var points: Int, var userId: String, var foodWave: Int, + var coins: Int, ) { @PrimaryKey var key = 1 diff --git a/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt b/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt index 3ce9842ff..dd23e8440 100644 --- a/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt +++ b/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt @@ -43,8 +43,10 @@ class ShopAdapter(private var itemList: List) : private fun bind(item: ShopItem, itemView: View, position: Int) { itemView.apply { shopCardView.setBackgroundResource(R.drawable.point_shop_tile_bg) + shopItemTextView.text = item.name priceTextView.text = item.price.toString() + val quantity = item.quantity quantityTextView.text = resources.getString(R.string.shopquantity, quantity) // Declaring executor to parse the URL From fdf70d873c6fdb6a97cd99bc7414dde23477492e Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Sat, 13 Jan 2024 04:03:27 -0600 Subject: [PATCH 32/52] added coin total view on shop fragment --- .../main/res/drawable/point_shop_tile_bg.xml | 2 +- .../res/drawable/rounded_coin_total_bg.xml | 6 +++ .../main/res/layout/fragment_point_shop.xml | 38 +++++++++++++++++++ app/src/main/res/values/colors.xml | 3 +- 4 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 app/src/main/res/drawable/rounded_coin_total_bg.xml diff --git a/app/src/main/res/drawable/point_shop_tile_bg.xml b/app/src/main/res/drawable/point_shop_tile_bg.xml index 535498e81..7d567c433 100644 --- a/app/src/main/res/drawable/point_shop_tile_bg.xml +++ b/app/src/main/res/drawable/point_shop_tile_bg.xml @@ -1,6 +1,6 @@ - + + + + + diff --git a/app/src/main/res/layout/fragment_point_shop.xml b/app/src/main/res/layout/fragment_point_shop.xml index 6fcee36ce..fcdb2a2e6 100644 --- a/app/src/main/res/layout/fragment_point_shop.xml +++ b/app/src/main/res/layout/fragment_point_shop.xml @@ -41,6 +41,43 @@ android:text="@string/pointshop" /> + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index c5f11c886..cd405330e 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -3,7 +3,7 @@ #FFFFFF - #80FFFFFF + #66FFFFFF #A5DAD5 #d7d4b8 #212121 @@ -62,6 +62,7 @@ #FFC95B #84BCB9 #C62A6C + #2A2A2A From a017c07a8d02a11e03fe0fc531a1773260de8e86 Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Sat, 13 Jan 2024 04:36:02 -0600 Subject: [PATCH 33/52] database change from adding coins field --- .../6.json | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/app/schemas/org.hackillinois.android.database.Database/6.json b/app/schemas/org.hackillinois.android.database.Database/6.json index 3164be356..d1d5f828c 100644 --- a/app/schemas/org.hackillinois.android.database.Database/6.json +++ b/app/schemas/org.hackillinois.android.database.Database/6.json @@ -2,7 +2,7 @@ "formatVersion": 1, "database": { "version": 6, - "identityHash": "e1e02bab837cae338b4c2cc99ea2c05a", + "identityHash": "afa24420ee99f9757a10c6b1939437f2", "entities": [ { "tableName": "qr_codes", @@ -238,7 +238,7 @@ }, { "tableName": "profiles", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` TEXT NOT NULL, `displayName` TEXT NOT NULL, `discordTag` TEXT NOT NULL, `avatarUrl` TEXT NOT NULL, `points` INTEGER NOT NULL, `userId` TEXT NOT NULL, `foodWave` INTEGER NOT NULL, `key` INTEGER NOT NULL, PRIMARY KEY(`key`))", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` TEXT NOT NULL, `displayName` TEXT NOT NULL, `discordTag` TEXT NOT NULL, `avatarUrl` TEXT NOT NULL, `points` INTEGER NOT NULL, `userId` TEXT NOT NULL, `foodWave` INTEGER NOT NULL, `coins` INTEGER NOT NULL, `key` INTEGER NOT NULL, PRIMARY KEY(`key`))", "fields": [ { "fieldPath": "_id", @@ -282,6 +282,12 @@ "affinity": "INTEGER", "notNull": true }, + { + "fieldPath": "coins", + "columnName": "coins", + "affinity": "INTEGER", + "notNull": true + }, { "fieldPath": "key", "columnName": "key", @@ -384,7 +390,7 @@ "views": [], "setupQueries": [ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'e1e02bab837cae338b4c2cc99ea2c05a')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'afa24420ee99f9757a10c6b1939437f2')" ] } } \ No newline at end of file From ca7d8ddf50a08ce6f6ecdf6c2332edc4e73d5a83 Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Sat, 13 Jan 2024 04:36:27 -0600 Subject: [PATCH 34/52] display user total coins --- .../org/hackillinois/android/view/shop/ShopFragment.kt | 6 ++++++ .../hackillinois/android/viewmodel/ShopViewModel.kt | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt b/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt index 3677bf29b..9f3e9328e 100644 --- a/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt +++ b/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt @@ -4,6 +4,7 @@ import android.content.Context import android.graphics.Canvas import android.graphics.drawable.Drawable import android.os.Bundle +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -13,7 +14,9 @@ import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import kotlinx.android.synthetic.main.fragment_point_shop.coin_total_textview import kotlinx.android.synthetic.main.fragment_point_shop.view.* +import kotlinx.android.synthetic.main.fragment_point_shop.view.coin_total_textview import kotlinx.android.synthetic.main.fragment_point_shop.view.recyclerview_point_shop import org.hackillinois.android.R import org.hackillinois.android.database.entity.ShopItem @@ -46,6 +49,9 @@ class ShopFragment : Fragment() { mAdapter = ShopAdapter(shop) + coin_total_textview.text = ",%d".format(viewModel.coinTotal) + Log.i("COIN TOTAL", viewModel.coinTotal.toString()) + recyclerView = view.recyclerview_point_shop.apply { mLayoutManager = LinearLayoutManager(context) this.layoutManager = mLayoutManager diff --git a/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt b/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt index 977927f30..2a4835169 100644 --- a/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt +++ b/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt @@ -2,15 +2,25 @@ package org.hackillinois.android.viewmodel import androidx.lifecycle.LiveData import androidx.lifecycle.ViewModel +import kotlinx.android.synthetic.main.activity_main.* +import kotlinx.android.synthetic.main.fragment_point_shop.view.* +// import kotlinx.android.synthetic.main.fragment_point_shop.view.coin_total_textview +import org.hackillinois.android.database.entity.Profile import org.hackillinois.android.database.entity.ShopItem +import org.hackillinois.android.repository.ProfileRepository import org.hackillinois.android.repository.ShopRepository class ShopViewModel : ViewModel() { private val shopRepository = ShopRepository.instance + private val profileRepository = ProfileRepository.instance lateinit var shopLiveData: LiveData> + lateinit var profileLiveData: LiveData + var coinTotal: Int = 0 fun init() { shopLiveData = shopRepository.fetchShop() + profileLiveData = profileRepository.fetchProfile() + coinTotal = profileLiveData.value?.coins!! } } From a314c7da11a1a04eeaa0855aa5e6fa61127ae6f5 Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Sat, 13 Jan 2024 17:27:13 -0600 Subject: [PATCH 35/52] coin total working --- .../hackillinois/android/database/Database.kt | 2 +- .../android/view/shop/ShopAdapter.kt | 1 - .../android/view/shop/ShopFragment.kt | 18 ++++++++++++++---- .../android/viewmodel/ShopViewModel.kt | 5 ----- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/hackillinois/android/database/Database.kt b/app/src/main/java/org/hackillinois/android/database/Database.kt index 40a9f36fd..014dc4821 100644 --- a/app/src/main/java/org/hackillinois/android/database/Database.kt +++ b/app/src/main/java/org/hackillinois/android/database/Database.kt @@ -17,7 +17,7 @@ import org.hackillinois.android.database.entity.Leaderboard Leaderboard::class, ShopItem::class, ], - version = 6, + version = 7, ) abstract class Database : RoomDatabase() { diff --git a/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt b/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt index dd23e8440..1b6df385d 100644 --- a/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt +++ b/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt @@ -17,7 +17,6 @@ import java.util.concurrent.Executors class ShopAdapter(private var itemList: List) : RecyclerView.Adapter() { private lateinit var context: Context - inner class ViewHolder(parent: View) : RecyclerView.ViewHolder(parent) // onCreateViewHolder used to display scrollable list of items diff --git a/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt b/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt index 9f3e9328e..ff53d8a16 100644 --- a/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt +++ b/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt @@ -16,9 +16,9 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import kotlinx.android.synthetic.main.fragment_point_shop.coin_total_textview import kotlinx.android.synthetic.main.fragment_point_shop.view.* -import kotlinx.android.synthetic.main.fragment_point_shop.view.coin_total_textview import kotlinx.android.synthetic.main.fragment_point_shop.view.recyclerview_point_shop import org.hackillinois.android.R +import org.hackillinois.android.database.entity.Profile import org.hackillinois.android.database.entity.ShopItem import org.hackillinois.android.viewmodel.ShopViewModel @@ -49,9 +49,6 @@ class ShopFragment : Fragment() { mAdapter = ShopAdapter(shop) - coin_total_textview.text = ",%d".format(viewModel.coinTotal) - Log.i("COIN TOTAL", viewModel.coinTotal.toString()) - recyclerView = view.recyclerview_point_shop.apply { mLayoutManager = LinearLayoutManager(context) this.layoutManager = mLayoutManager @@ -65,6 +62,14 @@ class ShopFragment : Fragment() { updateShop(it) }, ) + + viewModel.profileLiveData.observe( + viewLifecycleOwner, + { + updateCoinTotalUI(it) + }, + ) + return view } @@ -102,6 +107,11 @@ class ShopFragment : Fragment() { private fun updateShop(newShop: List) { mAdapter.updateShop(newShop) } + + private fun updateCoinTotalUI(newProfile: Profile) { + coin_total_textview.text = "%d".format(newProfile.coins) + Log.i("COIN TOTAL", newProfile.coins.toString()) + } } // var itemDecoration = DividerItemDecoration(this.context, DividerItemDecoration.VERTICAL) diff --git a/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt b/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt index 2a4835169..95657b1df 100644 --- a/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt +++ b/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt @@ -2,9 +2,6 @@ package org.hackillinois.android.viewmodel import androidx.lifecycle.LiveData import androidx.lifecycle.ViewModel -import kotlinx.android.synthetic.main.activity_main.* -import kotlinx.android.synthetic.main.fragment_point_shop.view.* -// import kotlinx.android.synthetic.main.fragment_point_shop.view.coin_total_textview import org.hackillinois.android.database.entity.Profile import org.hackillinois.android.database.entity.ShopItem import org.hackillinois.android.repository.ProfileRepository @@ -17,10 +14,8 @@ class ShopViewModel : ViewModel() { lateinit var shopLiveData: LiveData> lateinit var profileLiveData: LiveData - var coinTotal: Int = 0 fun init() { shopLiveData = shopRepository.fetchShop() profileLiveData = profileRepository.fetchProfile() - coinTotal = profileLiveData.value?.coins!! } } From fcdc71190b0884454684bd9916810d64ecaccb7b Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Sat, 13 Jan 2024 17:28:18 -0600 Subject: [PATCH 36/52] new database with profile coins field --- .../7.json | 396 ++++++++++++++++++ 1 file changed, 396 insertions(+) create mode 100644 app/schemas/org.hackillinois.android.database.Database/7.json diff --git a/app/schemas/org.hackillinois.android.database.Database/7.json b/app/schemas/org.hackillinois.android.database.Database/7.json new file mode 100644 index 000000000..4394691ba --- /dev/null +++ b/app/schemas/org.hackillinois.android.database.Database/7.json @@ -0,0 +1,396 @@ +{ + "formatVersion": 1, + "database": { + "version": 7, + "identityHash": "afa24420ee99f9757a10c6b1939437f2", + "entities": [ + { + "tableName": "qr_codes", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`userId` TEXT NOT NULL, `qrInfo` TEXT NOT NULL, `key` INTEGER NOT NULL, PRIMARY KEY(`key`))", + "fields": [ + { + "fieldPath": "userId", + "columnName": "userId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "qrInfo", + "columnName": "qrInfo", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "key", + "columnName": "key", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "key" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "attendees", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `firstName` TEXT NOT NULL, `lastName` TEXT NOT NULL, `dietary` TEXT NOT NULL, `key` INTEGER NOT NULL, PRIMARY KEY(`key`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "firstName", + "columnName": "firstName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "lastName", + "columnName": "lastName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dietary", + "columnName": "dietary", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "key", + "columnName": "key", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "key" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "users", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`userId` TEXT NOT NULL, `name` TEXT NOT NULL, `email` TEXT NOT NULL, `key` INTEGER NOT NULL, PRIMARY KEY(`key`))", + "fields": [ + { + "fieldPath": "userId", + "columnName": "userId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "email", + "columnName": "email", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "key", + "columnName": "key", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "key" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "events", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`eventId` TEXT NOT NULL, `name` TEXT NOT NULL, `description` TEXT NOT NULL, `startTime` INTEGER NOT NULL, `endTime` INTEGER NOT NULL, `locations` TEXT NOT NULL, `sponsor` TEXT NOT NULL, `eventType` TEXT NOT NULL, `points` TEXT NOT NULL, `isAsync` INTEGER NOT NULL, `isPrivate` INTEGER NOT NULL, `displayOnStaffCheckIn` INTEGER NOT NULL, PRIMARY KEY(`eventId`))", + "fields": [ + { + "fieldPath": "eventId", + "columnName": "eventId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "startTime", + "columnName": "startTime", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "endTime", + "columnName": "endTime", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "locations", + "columnName": "locations", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "sponsor", + "columnName": "sponsor", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "eventType", + "columnName": "eventType", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "points", + "columnName": "points", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "isAsync", + "columnName": "isAsync", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isPrivate", + "columnName": "isPrivate", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "displayOnStaffCheckIn", + "columnName": "displayOnStaffCheckIn", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "eventId" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "roles", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `roles` TEXT NOT NULL, `key` INTEGER NOT NULL, PRIMARY KEY(`key`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "roles", + "columnName": "roles", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "key", + "columnName": "key", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "key" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "profiles", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` TEXT NOT NULL, `displayName` TEXT NOT NULL, `discordTag` TEXT NOT NULL, `avatarUrl` TEXT NOT NULL, `points` INTEGER NOT NULL, `userId` TEXT NOT NULL, `foodWave` INTEGER NOT NULL, `coins` INTEGER NOT NULL, `key` INTEGER NOT NULL, PRIMARY KEY(`key`))", + "fields": [ + { + "fieldPath": "_id", + "columnName": "_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "displayName", + "columnName": "displayName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "discordTag", + "columnName": "discordTag", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "avatarUrl", + "columnName": "avatarUrl", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "points", + "columnName": "points", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "userId", + "columnName": "userId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "foodWave", + "columnName": "foodWave", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "coins", + "columnName": "coins", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "key", + "columnName": "key", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "key" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "leaderboard", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `displayName` TEXT NOT NULL, `points` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "displayName", + "columnName": "displayName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "points", + "columnName": "points", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "shop", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`itemId` TEXT NOT NULL, `name` TEXT NOT NULL, `price` INTEGER NOT NULL, `isRaffle` INTEGER NOT NULL, `quantity` INTEGER NOT NULL, `imageURL` TEXT NOT NULL, PRIMARY KEY(`itemId`))", + "fields": [ + { + "fieldPath": "itemId", + "columnName": "itemId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "price", + "columnName": "price", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isRaffle", + "columnName": "isRaffle", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "quantity", + "columnName": "quantity", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "imageURL", + "columnName": "imageURL", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "itemId" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'afa24420ee99f9757a10c6b1939437f2')" + ] + } +} \ No newline at end of file From d04233320afaac7445a5b257aca110ac6b9f960b Mon Sep 17 00:00:00 2001 From: Leah Ludwikowski Date: Sun, 14 Jan 2024 10:30:50 -0500 Subject: [PATCH 37/52] Added roles check and timer to fetch data every 10 seconds --- .../android/view/shop/ShopFragment.kt | 60 +++++++++++++------ .../android/viewmodel/ShopViewModel.kt | 28 ++++++++- 2 files changed, 69 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt b/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt index ff53d8a16..2b87baf7f 100644 --- a/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt +++ b/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt @@ -4,10 +4,11 @@ import android.content.Context import android.graphics.Canvas import android.graphics.drawable.Drawable import android.os.Bundle -import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import androidx.lifecycle.Observer @@ -15,9 +16,9 @@ import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import kotlinx.android.synthetic.main.fragment_point_shop.coin_total_textview -import kotlinx.android.synthetic.main.fragment_point_shop.view.* import kotlinx.android.synthetic.main.fragment_point_shop.view.recyclerview_point_shop import org.hackillinois.android.R +import org.hackillinois.android.common.JWTUtilities import org.hackillinois.android.database.entity.Profile import org.hackillinois.android.database.entity.ShopItem import org.hackillinois.android.viewmodel.ShopViewModel @@ -36,15 +37,18 @@ class ShopFragment : Fragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + viewModel = ViewModelProvider(this).get(ShopViewModel::class.java) - viewModel.init() + + // pass whether the user is an attendee to the viewmodel + if (hasLoggedIn() && isAttendee()) { + viewModel.init(true) + } else { + viewModel.init(false) + } } - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle?, - ): View? { + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { val view = inflater.inflate(R.layout.fragment_point_shop, container, false) mAdapter = ShopAdapter(shop) @@ -63,12 +67,22 @@ class ShopFragment : Fragment() { }, ) - viewModel.profileLiveData.observe( - viewLifecycleOwner, - { - updateCoinTotalUI(it) - }, - ) + if (hasLoggedIn() && isAttendee()) { + // set coin views visible for attendee + val coinBg: TextView = view.findViewById(R.id.total_coin_view) + val coinText: TextView = view.findViewById(R.id.coin_total_textview) + val coinImg: ImageView = view.findViewById(R.id.coin_imageview) + coinBg.visibility = View.VISIBLE + coinText.visibility = View.VISIBLE + coinImg.visibility = View.VISIBLE + + viewModel.profileLiveData.observe( + viewLifecycleOwner, + Observer { + updateCoinTotalUI(it) + }, + ) + } return view } @@ -108,9 +122,21 @@ class ShopFragment : Fragment() { mAdapter.updateShop(newShop) } - private fun updateCoinTotalUI(newProfile: Profile) { - coin_total_textview.text = "%d".format(newProfile.coins) - Log.i("COIN TOTAL", newProfile.coins.toString()) + private fun updateCoinTotalUI(newProfile: Profile?) { + if (newProfile != null) { + coin_total_textview.text = String.format("%,d", newProfile.coins) + } + } + + private fun hasLoggedIn(): Boolean { + // Reads JWT and checks if it is equal to an empty JWT + return JWTUtilities.readJWT(requireActivity().applicationContext) != JWTUtilities.DEFAULT_JWT + } + + private fun isAttendee(): Boolean { + val context = requireActivity().applicationContext + val prefString = context.getString(R.string.authorization_pref_file_key) + return context.getSharedPreferences(prefString, Context.MODE_PRIVATE).getString("provider", "") ?: "" == "github" } } diff --git a/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt b/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt index 95657b1df..93dd98516 100644 --- a/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt +++ b/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt @@ -6,6 +6,8 @@ import org.hackillinois.android.database.entity.Profile import org.hackillinois.android.database.entity.ShopItem import org.hackillinois.android.repository.ProfileRepository import org.hackillinois.android.repository.ShopRepository +import java.util.Timer +import java.util.TimerTask class ShopViewModel : ViewModel() { private val shopRepository = ShopRepository.instance @@ -14,8 +16,30 @@ class ShopViewModel : ViewModel() { lateinit var shopLiveData: LiveData> lateinit var profileLiveData: LiveData - fun init() { + lateinit var timerObj: Timer + + fun init(isAttendee: Boolean) { + // initial fetch shopLiveData = shopRepository.fetchShop() - profileLiveData = profileRepository.fetchProfile() + if (isAttendee) { + profileLiveData = profileRepository.fetchProfile() + } + + // runs TimerTask every 10 seconds to fetch profile and shop data + timerObj = Timer() + val timerTaskObj: TimerTask = object : TimerTask() { + override fun run() { + shopLiveData = shopRepository.fetchShop() + if (isAttendee) { + profileLiveData = profileRepository.fetchProfile() + } + } + } + timerObj.scheduleAtFixedRate(timerTaskObj, 0, 10000) + } + + override fun onCleared() { + super.onCleared() + timerObj.cancel() } } From d9fdd6428bf4aa0d1f15f47cf5bc4d52148919be Mon Sep 17 00:00:00 2001 From: Leah Ludwikowski Date: Sun, 14 Jan 2024 10:31:28 -0500 Subject: [PATCH 38/52] made small changes to coin view layout --- .../main/res/drawable/point_shop_divider.xml | 1 + .../main/res/layout/fragment_point_shop.xml | 61 +++++++++++-------- app/src/main/res/values/strings.xml | 3 +- 3 files changed, 37 insertions(+), 28 deletions(-) diff --git a/app/src/main/res/drawable/point_shop_divider.xml b/app/src/main/res/drawable/point_shop_divider.xml index 32e1fdffa..6a70df16c 100644 --- a/app/src/main/res/drawable/point_shop_divider.xml +++ b/app/src/main/res/drawable/point_shop_divider.xml @@ -4,4 +4,5 @@ android:width="1dp" android:height="10dp" /> + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_point_shop.xml b/app/src/main/res/layout/fragment_point_shop.xml index fcdb2a2e6..fa9f24588 100644 --- a/app/src/main/res/layout/fragment_point_shop.xml +++ b/app/src/main/res/layout/fragment_point_shop.xml @@ -10,13 +10,15 @@ + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintVertical_bias="0.0" /> + app:layout_constraintStart_toStartOf="@id/coin_imageview" + app:layout_constraintTop_toTopOf="@id/coin_total_textview" + app:layout_constraintEnd_toEndOf="@id/coin_total_textview" + app:layout_constraintBottom_toBottomOf="@id/coin_total_textview" + android:visibility="invisible" /> + app:layout_constraintEnd_toStartOf="@id/coin_total_textview" + app:layout_constraintTop_toTopOf="@id/coin_total_textview" + app:layout_constraintBottom_toBottomOf="@id/coin_total_textview" + android:visibility="invisible" /> + android:textSize="19sp" + app:layout_constraintVertical_bias="0.75" + app:layout_constraintBottom_toBottomOf="@id/title_textview_point_shop" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="@id/title_textview_point_shop" + android:visibility="invisible" + android:text="@string/blank" /> POINT SHOP %d Left + --- PROFILE @@ -91,6 +92,4 @@ You must log in to use this feature! Go to the Profile tab to logout. - - From 6a4d786282f84c22ea9b39cf119fc36b70843210 Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Wed, 17 Jan 2024 20:50:51 -0600 Subject: [PATCH 39/52] updated point shop banner --- .../android/view/shop/ShopAdapter.kt | 1 + .../android/view/shop/ShopFragment.kt | 5 +- .../main/res/drawable/point_shop_banner.xml | 126 +++++++++--------- 3 files changed, 67 insertions(+), 65 deletions(-) diff --git a/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt b/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt index 1b6df385d..d3e90bc08 100644 --- a/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt +++ b/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt @@ -48,6 +48,7 @@ class ShopAdapter(private var itemList: List) : val quantity = item.quantity quantityTextView.text = resources.getString(R.string.shopquantity, quantity) + // Declaring executor to parse the URL val executor = Executors.newSingleThreadExecutor() // Once the executor parses the URL and receives the image, handler will load it diff --git a/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt b/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt index 2b87baf7f..7f4742758 100644 --- a/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt +++ b/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt @@ -93,7 +93,7 @@ class ShopFragment : Fragment() { val dividerLeft = parent.paddingLeft val dividerRight = parent.width - parent.paddingRight val childCount = parent.childCount // how many items recyclerview has - for (i in 0..childCount - 1) { // minus 2 to account for zero index and skip last item + for (i in 0..childCount - 1) { // minus 1 to account for zero index and not skip last item val child = parent.getChildAt(i) val params = child.layoutParams as RecyclerView.LayoutParams val dividerTop = child.bottom + params.bottomMargin @@ -101,6 +101,7 @@ class ShopFragment : Fragment() { mDivider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom) mDivider.draw(canvas) + // add divider to top of recyclerview if (i == 0) { val topDividerTop = parent.paddingTop val topDividerBottom = topDividerTop + mDivider.intrinsicHeight @@ -110,7 +111,7 @@ class ShopFragment : Fragment() { } } } - fun RecyclerView.addDividers() { + private fun RecyclerView.addDividers() { if (layoutManager !is LinearLayoutManager) { return } diff --git a/app/src/main/res/drawable/point_shop_banner.xml b/app/src/main/res/drawable/point_shop_banner.xml index 6b56649cc..53331eafd 100644 --- a/app/src/main/res/drawable/point_shop_banner.xml +++ b/app/src/main/res/drawable/point_shop_banner.xml @@ -91,6 +91,69 @@ + + + + + + + + + + + + + + + + + @@ -184,69 +247,6 @@ android:pathData="M91.16,36.7C91.16,38.03 90.62,42.73 89.95,42.73C89.29,42.73 88.75,38.03 88.75,36.7C88.75,35.37 89.29,34.3 89.95,34.3C90.62,34.3 91.16,35.37 91.16,36.7Z" android:fillColor="#FFFACC" android:fillAlpha="0.3"/> - - - - - - - - - - - - - - - - - Date: Wed, 17 Jan 2024 21:06:53 -0600 Subject: [PATCH 40/52] imageView Glide --- .../android/view/shop/ShopAdapter.kt | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt b/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt index d3e90bc08..f639928c1 100644 --- a/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt +++ b/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt @@ -1,18 +1,15 @@ package org.hackillinois.android.view.shop import android.content.Context -import android.graphics.Bitmap -import android.graphics.BitmapFactory -import android.os.Handler -import android.os.Looper import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.ImageView import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide import kotlinx.android.synthetic.main.shop_tile.view.* import org.hackillinois.android.R import org.hackillinois.android.database.entity.ShopItem -import java.util.concurrent.Executors class ShopAdapter(private var itemList: List) : RecyclerView.Adapter() { @@ -49,29 +46,32 @@ class ShopAdapter(private var itemList: List) : val quantity = item.quantity quantityTextView.text = resources.getString(R.string.shopquantity, quantity) + val imageURL = item.imageURL + val shopItemImageView: ImageView = itemView.findViewById(R.id.shopItemImageView) + Glide.with(context).load(imageURL).into(shopItemImageView) + // Declaring executor to parse the URL - val executor = Executors.newSingleThreadExecutor() + // val executor = Executors.newSingleThreadExecutor() // Once the executor parses the URL and receives the image, handler will load it // in the ImageView - val handler = Handler(Looper.getMainLooper()) + // val handler = Handler(Looper.getMainLooper()) // Initializing the image - var image: Bitmap? = null - val imageURL = item.imageURL - executor.execute() { - try { - val `in` = java.net.URL(imageURL).openStream() - image = BitmapFactory.decodeStream(`in`) +// var image: Bitmap? = null +// val imageURL = item.imageURL +// executor.execute() { +// try { +// val `in` = java.net.URL(imageURL).openStream() +// image = BitmapFactory.decodeStream(`in`) - // Only for making changes in UI - handler.post { - shopItemImageView.setImageBitmap(image) - } - } - // If the URL doesnot point to image or any other kind of failure - catch (e: Exception) { - e.printStackTrace() - } - } + // Only for making changes in UI +// handler.post { +// shopItemImageView.setImageBitmap(image) +// } +// } + // If the URL doesnot point to image or any other kind of failure +// catch (e: Exception) { +// e.printStackTrace() +// } } } From cd8ae8c66b8db8474157933096f742f955dc8374 Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Thu, 18 Jan 2024 01:35:03 -0600 Subject: [PATCH 41/52] started merch/raffle tabs --- .../main/res/layout/fragment_point_shop.xml | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/layout/fragment_point_shop.xml b/app/src/main/res/layout/fragment_point_shop.xml index fa9f24588..7396ddfa0 100644 --- a/app/src/main/res/layout/fragment_point_shop.xml +++ b/app/src/main/res/layout/fragment_point_shop.xml @@ -106,12 +106,40 @@ android:layout_marginBottom="50dp" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toBottomOf="@id/title_textview_point_shop" + app:layout_constraintTop_toBottomOf="@id/textView3" app:layout_constraintBottom_toBottomOf="parent" android:paddingEnd="31dp" android:paddingStart="31dp" android:paddingBottom="30dp" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" /> + + + + \ No newline at end of file From 849f8d38440175183e1857b648aad44a852d1120 Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Sun, 21 Jan 2024 13:45:56 -0600 Subject: [PATCH 42/52] fixed cost and quantity margins, fixed shoptile margins --- .../android/viewmodel/ShopViewModel.kt | 2 ++ .../main/res/drawable/shop_selected_tab.xml | 10 ++++++++++ .../main/res/layout/fragment_point_shop.xml | 9 +++++---- app/src/main/res/layout/shop_tile.xml | 19 +++++++++++-------- app/src/main/res/values/colors.xml | 1 + 5 files changed, 29 insertions(+), 12 deletions(-) create mode 100644 app/src/main/res/drawable/shop_selected_tab.xml diff --git a/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt b/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt index 93dd98516..364bbebc8 100644 --- a/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt +++ b/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt @@ -18,6 +18,8 @@ class ShopViewModel : ViewModel() { lateinit var timerObj: Timer + // var shopTabClicked by Delegates.notNull() + fun init(isAttendee: Boolean) { // initial fetch shopLiveData = shopRepository.fetchShop() diff --git a/app/src/main/res/drawable/shop_selected_tab.xml b/app/src/main/res/drawable/shop_selected_tab.xml new file mode 100644 index 000000000..e70eecc77 --- /dev/null +++ b/app/src/main/res/drawable/shop_selected_tab.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_point_shop.xml b/app/src/main/res/layout/fragment_point_shop.xml index 7396ddfa0..5bbfb64b9 100644 --- a/app/src/main/res/layout/fragment_point_shop.xml +++ b/app/src/main/res/layout/fragment_point_shop.xml @@ -102,11 +102,11 @@ android:id="@+id/recyclerview_point_shop" android:layout_height="match_parent" android:layout_width="match_parent" - android:layout_marginTop="250dp" + android:layout_marginTop="258dp" android:layout_marginBottom="50dp" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toBottomOf="@id/textView3" + app:layout_constraintTop_toBottomOf="@id/merchButton" app:layout_constraintBottom_toBottomOf="parent" android:paddingEnd="31dp" android:paddingStart="31dp" @@ -114,13 +114,14 @@ app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" /> + app:layout_constraintEnd_toEndOf="@id/costandQuantityView" + app:layout_constraintHorizontal_bias="0.5" + app:layout_constraintStart_toEndOf="@+id/separatorTextView" + app:layout_constraintTop_toTopOf="@id/costandQuantityView" /> diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index cd405330e..9bb7cb7e3 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -63,6 +63,7 @@ #84BCB9 #C62A6C #2A2A2A + #D84177 From 9746cb6c7c22f7e752865c7060dcb49029272f7d Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Sun, 21 Jan 2024 14:01:05 -0600 Subject: [PATCH 43/52] long shop item name stays on screen --- app/src/main/res/layout/shop_tile.xml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/src/main/res/layout/shop_tile.xml b/app/src/main/res/layout/shop_tile.xml index 51badf7aa..e7cfc735e 100644 --- a/app/src/main/res/layout/shop_tile.xml +++ b/app/src/main/res/layout/shop_tile.xml @@ -34,21 +34,22 @@ From b4ef4a4c07b83f925191e78ba128d5895b585159 Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Wed, 24 Jan 2024 21:23:02 -0600 Subject: [PATCH 44/52] merch/raffle margins fixed --- app/src/main/res/layout/fragment_point_shop.xml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/layout/fragment_point_shop.xml b/app/src/main/res/layout/fragment_point_shop.xml index 5bbfb64b9..7eb6f1f86 100644 --- a/app/src/main/res/layout/fragment_point_shop.xml +++ b/app/src/main/res/layout/fragment_point_shop.xml @@ -119,7 +119,8 @@ android:layout_height="45dp" android:layout_marginTop="11dp" app:layout_constraintTop_toBottomOf="@id/imageview_point_shop_banner" - app:layout_constraintStart_toStartOf="@id/imageview_point_shop_banner" + app:layout_constraintStart_toStartOf="parent" + android:layout_marginStart="36dp" android:gravity="center" android:background="@drawable/shop_selected_tab" android:text="MERCH" @@ -134,7 +135,8 @@ android:layout_height="45dp" android:layout_marginTop="11dp" app:layout_constraintTop_toBottomOf="@id/imageview_point_shop_banner" - app:layout_constraintEnd_toEndOf="@id/imageview_point_shop_banner" + app:layout_constraintEnd_toEndOf="parent" + android:layout_marginEnd="36dp" android:gravity="center" android:fontFamily="@font/montserrat_bold" android:textColor="@color/palePeach" From 77a8415b3e6e9677f295b913ba2b08a7a5773c36 Mon Sep 17 00:00:00 2001 From: Leah Ludwikowski Date: Mon, 29 Jan 2024 15:27:57 -0600 Subject: [PATCH 45/52] Modified some of the constraints with shop_tile --- .../8.json | 396 ++++++++++++++++++ .../hackillinois/android/database/Database.kt | 2 +- .../hackillinois/android/view/MainActivity.kt | 13 +- app/src/main/res/layout/activity_main.xml | 10 +- app/src/main/res/layout/shop_tile.xml | 117 +++--- 5 files changed, 464 insertions(+), 74 deletions(-) create mode 100644 app/schemas/org.hackillinois.android.database.Database/8.json diff --git a/app/schemas/org.hackillinois.android.database.Database/8.json b/app/schemas/org.hackillinois.android.database.Database/8.json new file mode 100644 index 000000000..35554e57a --- /dev/null +++ b/app/schemas/org.hackillinois.android.database.Database/8.json @@ -0,0 +1,396 @@ +{ + "formatVersion": 1, + "database": { + "version": 8, + "identityHash": "afa24420ee99f9757a10c6b1939437f2", + "entities": [ + { + "tableName": "qr_codes", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`userId` TEXT NOT NULL, `qrInfo` TEXT NOT NULL, `key` INTEGER NOT NULL, PRIMARY KEY(`key`))", + "fields": [ + { + "fieldPath": "userId", + "columnName": "userId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "qrInfo", + "columnName": "qrInfo", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "key", + "columnName": "key", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "key" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "attendees", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `firstName` TEXT NOT NULL, `lastName` TEXT NOT NULL, `dietary` TEXT NOT NULL, `key` INTEGER NOT NULL, PRIMARY KEY(`key`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "firstName", + "columnName": "firstName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "lastName", + "columnName": "lastName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dietary", + "columnName": "dietary", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "key", + "columnName": "key", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "key" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "users", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`userId` TEXT NOT NULL, `name` TEXT NOT NULL, `email` TEXT NOT NULL, `key` INTEGER NOT NULL, PRIMARY KEY(`key`))", + "fields": [ + { + "fieldPath": "userId", + "columnName": "userId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "email", + "columnName": "email", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "key", + "columnName": "key", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "key" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "events", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`eventId` TEXT NOT NULL, `name` TEXT NOT NULL, `description` TEXT NOT NULL, `startTime` INTEGER NOT NULL, `endTime` INTEGER NOT NULL, `locations` TEXT NOT NULL, `sponsor` TEXT NOT NULL, `eventType` TEXT NOT NULL, `points` TEXT NOT NULL, `isAsync` INTEGER NOT NULL, `isPrivate` INTEGER NOT NULL, `displayOnStaffCheckIn` INTEGER NOT NULL, PRIMARY KEY(`eventId`))", + "fields": [ + { + "fieldPath": "eventId", + "columnName": "eventId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "startTime", + "columnName": "startTime", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "endTime", + "columnName": "endTime", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "locations", + "columnName": "locations", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "sponsor", + "columnName": "sponsor", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "eventType", + "columnName": "eventType", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "points", + "columnName": "points", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "isAsync", + "columnName": "isAsync", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isPrivate", + "columnName": "isPrivate", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "displayOnStaffCheckIn", + "columnName": "displayOnStaffCheckIn", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "eventId" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "roles", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `roles` TEXT NOT NULL, `key` INTEGER NOT NULL, PRIMARY KEY(`key`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "roles", + "columnName": "roles", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "key", + "columnName": "key", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "key" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "profiles", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` TEXT NOT NULL, `displayName` TEXT NOT NULL, `discordTag` TEXT NOT NULL, `avatarUrl` TEXT NOT NULL, `points` INTEGER NOT NULL, `userId` TEXT NOT NULL, `foodWave` INTEGER NOT NULL, `coins` INTEGER NOT NULL, `key` INTEGER NOT NULL, PRIMARY KEY(`key`))", + "fields": [ + { + "fieldPath": "_id", + "columnName": "_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "displayName", + "columnName": "displayName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "discordTag", + "columnName": "discordTag", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "avatarUrl", + "columnName": "avatarUrl", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "points", + "columnName": "points", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "userId", + "columnName": "userId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "foodWave", + "columnName": "foodWave", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "coins", + "columnName": "coins", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "key", + "columnName": "key", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "key" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "leaderboard", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `displayName` TEXT NOT NULL, `points` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "displayName", + "columnName": "displayName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "points", + "columnName": "points", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "shop", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`itemId` TEXT NOT NULL, `name` TEXT NOT NULL, `price` INTEGER NOT NULL, `isRaffle` INTEGER NOT NULL, `quantity` INTEGER NOT NULL, `imageURL` TEXT NOT NULL, PRIMARY KEY(`itemId`))", + "fields": [ + { + "fieldPath": "itemId", + "columnName": "itemId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "price", + "columnName": "price", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isRaffle", + "columnName": "isRaffle", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "quantity", + "columnName": "quantity", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "imageURL", + "columnName": "imageURL", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "itemId" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'afa24420ee99f9757a10c6b1939437f2')" + ] + } +} \ No newline at end of file diff --git a/app/src/main/java/org/hackillinois/android/database/Database.kt b/app/src/main/java/org/hackillinois/android/database/Database.kt index 014dc4821..579f438dd 100644 --- a/app/src/main/java/org/hackillinois/android/database/Database.kt +++ b/app/src/main/java/org/hackillinois/android/database/Database.kt @@ -17,7 +17,7 @@ import org.hackillinois.android.database.entity.Leaderboard Leaderboard::class, ShopItem::class, ], - version = 7, + version = 8, ) abstract class Database : RoomDatabase() { diff --git a/app/src/main/java/org/hackillinois/android/view/MainActivity.kt b/app/src/main/java/org/hackillinois/android/view/MainActivity.kt index cdfd196d9..1d18a3def 100644 --- a/app/src/main/java/org/hackillinois/android/view/MainActivity.kt +++ b/app/src/main/java/org/hackillinois/android/view/MainActivity.kt @@ -66,8 +66,8 @@ class MainActivity : AppCompatActivity() { val bottomBarButtons = listOf( bottomAppBar.homeButton, bottomAppBar.scheduleButton, - bottomAppBar.shop, - bottomAppBar.profile, + bottomAppBar.shopButton, + bottomAppBar.profileButton, ) // make all buttons unselectedColor and then set selected button to selectedColor @@ -87,9 +87,8 @@ class MainActivity : AppCompatActivity() { when (view) { bottomAppBar.homeButton -> switchFragment(HomeFragment(), false) bottomAppBar.scheduleButton -> switchFragment(ScheduleFragment(), false) - bottomAppBar.leaderboard -> switchFragment(ShopFragment(), false) - bottomAppBar.shop -> switchFragment(LeaderboardFragment(), false) - bottomAppBar.profile -> switchFragment(ProfileFragment(), false) + bottomAppBar.shopButton -> switchFragment(ShopFragment(), false) + bottomAppBar.profileButton -> switchFragment(ProfileFragment(), false) else -> return@setOnClickListener } } @@ -111,8 +110,8 @@ class MainActivity : AppCompatActivity() { val bottomBarButtons = listOf( bottomAppBar.homeButton, bottomAppBar.scheduleButton, - bottomAppBar.shop, - bottomAppBar.profile, + bottomAppBar.shopButton, + bottomAppBar.profileButton, ) val unselectedIconColor = ContextCompat.getColor(this, R.color.unselectedAppBarIcon) bottomBarButtons.forEach { (it as ImageButton).setColorFilter(unselectedIconColor) } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 584fa33bf..5d2edf006 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -49,28 +49,28 @@ android:layout_height="0dp" android:visibility="invisible" app:layout_constraintBottom_toBottomOf="@id/homeButton" - app:layout_constraintEnd_toStartOf="@id/shop" + app:layout_constraintEnd_toStartOf="@id/shopButton" app:layout_constraintStart_toEndOf="@id/scheduleButton" app:layout_constraintTop_toTopOf="@id/homeButton" /> diff --git a/app/src/main/res/layout/shop_tile.xml b/app/src/main/res/layout/shop_tile.xml index e7cfc735e..ff679e762 100644 --- a/app/src/main/res/layout/shop_tile.xml +++ b/app/src/main/res/layout/shop_tile.xml @@ -3,135 +3,130 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" - android:layout_height="157dp" - > - + android:layout_height="wrap_content"> + android:layout_marginHorizontal="5dp"> + android:layout_height="150dp"> + + + app:layout_constraintVertical_chainStyle="packed" + tools:text="Super Long Test Shop Test Shop Name" /> + app:layout_constraintBottom_toBottomOf="@id/coinImageView" + app:layout_constraintEnd_toEndOf="@id/quantityTextView" + app:layout_constraintHorizontal_bias="1.0" + app:layout_constraintStart_toStartOf="@id/coinImageView" + app:layout_constraintTop_toTopOf="@+id/coinImageView" + app:layout_constraintVertical_bias="0.0" /> + app:layout_constraintStart_toStartOf="@+id/guidelineSeparator" + app:layout_constraintTop_toTopOf="@+id/priceTextView" + app:srcCompat="@drawable/faded_coin" /> + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toStartOf="@+id/separatorTextView" + app:layout_constraintHorizontal_bias="0.5" + app:layout_constraintStart_toEndOf="@+id/coinImageView" + app:layout_constraintTop_toBottomOf="@+id/shopItemTextView" + tools:text="1000" /> + app:layout_constraintBottom_toBottomOf="@+id/priceTextView" + app:layout_constraintEnd_toStartOf="@+id/quantityTextView" + app:layout_constraintHorizontal_bias="0.5" + app:layout_constraintStart_toEndOf="@+id/priceTextView" + app:layout_constraintTop_toTopOf="@id/priceTextView" /> + app:layout_constraintTop_toTopOf="@id/priceTextView" + tools:text="100 Left" /> - - \ No newline at end of file From 962649c167713cf077762769470b8ae22d3e8716 Mon Sep 17 00:00:00 2001 From: Leah Ludwikowski Date: Mon, 29 Jan 2024 16:18:42 -0600 Subject: [PATCH 46/52] More layout constraint modifications --- .../main/res/layout/fragment_point_shop.xml | 84 ++++++++++--------- app/src/main/res/layout/shop_tile.xml | 21 +++-- app/src/main/res/values/strings.xml | 4 + 3 files changed, 62 insertions(+), 47 deletions(-) diff --git a/app/src/main/res/layout/fragment_point_shop.xml b/app/src/main/res/layout/fragment_point_shop.xml index 7eb6f1f86..a137d7376 100644 --- a/app/src/main/res/layout/fragment_point_shop.xml +++ b/app/src/main/res/layout/fragment_point_shop.xml @@ -5,7 +5,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".view.leaderboard.LeaderboardFragment" - android:background="@color/nightBlue"> + android:background="@color/witchyPurple"> + android:text="@string/pointshop" /> + app:layout_constraintTop_toBottomOf="@+id/title_textview_point_shop" /> + android:gravity="center" + android:paddingVertical="10dp" + android:textColor="@color/white" + android:textSize="20sp" + app:layout_constraintEnd_toStartOf="@+id/guidelineSeparator" + app:layout_constraintStart_toStartOf="@+id/recyclerview_point_shop" + app:layout_constraintTop_toBottomOf="@id/imageview_point_shop_banner" + android:text="@string/merch" /> + android:gravity="center" + android:paddingVertical="10dp" + android:textColor="@color/white" + android:textSize="20sp" + app:layout_constraintEnd_toEndOf="@+id/recyclerview_point_shop" + app:layout_constraintStart_toStartOf="@+id/guidelineSeparator" + app:layout_constraintTop_toBottomOf="@id/imageview_point_shop_banner" + android:text="@string/raffle" /> + + + \ No newline at end of file diff --git a/app/src/main/res/layout/shop_tile.xml b/app/src/main/res/layout/shop_tile.xml index ff679e762..f28ded09b 100644 --- a/app/src/main/res/layout/shop_tile.xml +++ b/app/src/main/res/layout/shop_tile.xml @@ -39,7 +39,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginHorizontal="10dp" - android:layout_marginBottom="20dp" + android:layout_marginBottom="12dp" android:fontFamily="@font/montserrat_semi_bold" android:gravity="center" android:textColor="@color/darkForest" @@ -53,26 +53,26 @@ tools:text="Super Long Test Shop Test Shop Name" /> POINT SHOP %d Left --- + | + MERCH + RAFFLE PROFILE @@ -92,4 +95,5 @@ You must log in to use this feature! Go to the Profile tab to logout. + From 382e74c40245b443c95d0110589847ef56c33789 Mon Sep 17 00:00:00 2001 From: Sunny Lee Date: Sun, 4 Feb 2024 11:09:17 -0600 Subject: [PATCH 47/52] merch/raffle tabs working to show appropriate items --- .../android/view/shop/ShopAdapter.kt | 23 ----- .../android/view/shop/ShopFragment.kt | 97 ++++++++++++++++--- .../android/viewmodel/ShopViewModel.kt | 4 +- .../main/res/drawable/shop_unselected_tab.xml | 10 ++ .../main/res/layout/fragment_point_shop.xml | 1 + 5 files changed, 100 insertions(+), 35 deletions(-) create mode 100644 app/src/main/res/drawable/shop_unselected_tab.xml diff --git a/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt b/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt index f639928c1..0da8d92ed 100644 --- a/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt +++ b/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt @@ -49,29 +49,6 @@ class ShopAdapter(private var itemList: List) : val imageURL = item.imageURL val shopItemImageView: ImageView = itemView.findViewById(R.id.shopItemImageView) Glide.with(context).load(imageURL).into(shopItemImageView) - - // Declaring executor to parse the URL - // val executor = Executors.newSingleThreadExecutor() - // Once the executor parses the URL and receives the image, handler will load it - // in the ImageView - // val handler = Handler(Looper.getMainLooper()) - // Initializing the image -// var image: Bitmap? = null -// val imageURL = item.imageURL -// executor.execute() { -// try { -// val `in` = java.net.URL(imageURL).openStream() -// image = BitmapFactory.decodeStream(`in`) - - // Only for making changes in UI -// handler.post { -// shopItemImageView.setImageBitmap(image) -// } -// } - // If the URL doesnot point to image or any other kind of failure -// catch (e: Exception) { -// e.printStackTrace() -// } } } diff --git a/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt b/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt index 7f4742758..87ceeb330 100644 --- a/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt +++ b/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt @@ -29,28 +29,59 @@ class ShopFragment : Fragment() { fun newInstance() = ShopFragment() } - private lateinit var viewModel: ShopViewModel + private lateinit var shopViewModel: ShopViewModel private var shop: List = listOf() private lateinit var recyclerView: RecyclerView private lateinit var mLayoutManager: LinearLayoutManager private lateinit var mAdapter: ShopAdapter + private lateinit var merchButton: TextView + private lateinit var raffleButton: TextView + + private lateinit var merchItems: List + private lateinit var raffleItems: List + + // Merch tab is default selected + private var showingMerch: Boolean = true + private var showingRaffle: Boolean = false + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - viewModel = ViewModelProvider(this).get(ShopViewModel::class.java) + shopViewModel = ViewModelProvider(this).get(ShopViewModel::class.java) // pass whether the user is an attendee to the viewmodel if (hasLoggedIn() && isAttendee()) { - viewModel.init(true) + shopViewModel.init(true) } else { - viewModel.init(false) + shopViewModel.init(false) } + + // Observes value of showMerch and updates showingMerch value accordingly + shopViewModel.showMerch.observe( + this, + Observer { + showingMerch = it ?: false + updateShopUI() + }, + ) + + // Observes value of showMerch and updates showingRaffle value accordingly + shopViewModel.showRaffle.observe( + this, + Observer { + showingRaffle = it ?: false + updateShopUI() + }, + ) } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { val view = inflater.inflate(R.layout.fragment_point_shop, container, false) + merchButton = view.findViewById(R.id.merchButton) + raffleButton = view.findViewById(R.id.raffleButton) + mAdapter = ShopAdapter(shop) recyclerView = view.recyclerview_point_shop.apply { @@ -60,13 +91,17 @@ class ShopFragment : Fragment() { addDividers() } - viewModel.shopLiveData.observe( + shopViewModel.shopLiveData.observe( viewLifecycleOwner, Observer { + // will split shop items into Merch or Raffle category updateShop(it) }, ) + merchButton.setOnClickListener(merchClickListener) + raffleButton.setOnClickListener(raffleClickListener) + if (hasLoggedIn() && isAttendee()) { // set coin views visible for attendee val coinBg: TextView = view.findViewById(R.id.total_coin_view) @@ -76,7 +111,7 @@ class ShopFragment : Fragment() { coinText.visibility = View.VISIBLE coinImg.visibility = View.VISIBLE - viewModel.profileLiveData.observe( + shopViewModel.profileLiveData.observe( viewLifecycleOwner, Observer { updateCoinTotalUI(it) @@ -119,8 +154,52 @@ class ShopFragment : Fragment() { addItemDecoration(DividerItemDecorator(context)) } +// private fun updateShop(newShop: List) { +// mAdapter.updateShop(newShop) +// } + + // Called in onCreateView within shopLiveData.observe private fun updateShop(newShop: List) { - mAdapter.updateShop(newShop) + // Split the shop items into Merch and Raffle items + merchItems = newShop.filter { !it.isRaffle } + raffleItems = newShop.filter { it.isRaffle } + + // Update the UI based on the selected button + updateShopUI() + } + + private fun updateShopUI() { + // if showingMerch variable is True based on selected button, show merch items. else, show raffle + val itemsToShow = if (showingMerch) merchItems else raffleItems + mAdapter.updateShop(itemsToShow) + } + + // update merch ViewModel on click + private val merchClickListener = View.OnClickListener { + if (!merchButton.isSelected) { + merchButton.isSelected = true + merchButton.background = this.context?.let { it1 -> ContextCompat.getDrawable(it1, R.drawable.shop_selected_tab) } + raffleButton.isSelected = false + raffleButton.background = this.context?.let { it1 -> ContextCompat.getDrawable(it1, R.drawable.shop_unselected_tab) } + shopViewModel.showMerch.postValue(true) + shopViewModel.showRaffle.postValue(false) + showingMerch = true + showingRaffle = false + } + } + + // update raffle ViewModel on click + private val raffleClickListener = View.OnClickListener { + if (!raffleButton.isSelected) { + raffleButton.isSelected = true + raffleButton.background = this.context?.let { it1 -> ContextCompat.getDrawable(it1, R.drawable.shop_selected_tab) } + merchButton.isSelected = false + merchButton.background = this.context?.let { it1 -> ContextCompat.getDrawable(it1, R.drawable.shop_unselected_tab) } + shopViewModel.showRaffle.postValue(true) + shopViewModel.showMerch.postValue(false) + showingRaffle = true + showingMerch = false + } } private fun updateCoinTotalUI(newProfile: Profile?) { @@ -140,7 +219,3 @@ class ShopFragment : Fragment() { return context.getSharedPreferences(prefString, Context.MODE_PRIVATE).getString("provider", "") ?: "" == "github" } } - -// var itemDecoration = DividerItemDecoration(this.context, DividerItemDecoration.VERTICAL) -// itemDecoration.setDrawable(getDrawable(this.context, R.drawable.leaderboard_divider)!!) -// addItemDecoration(itemDecoration) diff --git a/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt b/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt index 364bbebc8..3afd3fd4a 100644 --- a/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt +++ b/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt @@ -1,6 +1,7 @@ package org.hackillinois.android.viewmodel import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import org.hackillinois.android.database.entity.Profile import org.hackillinois.android.database.entity.ShopItem @@ -18,7 +19,8 @@ class ShopViewModel : ViewModel() { lateinit var timerObj: Timer - // var shopTabClicked by Delegates.notNull() + var showMerch: MutableLiveData = MutableLiveData() + var showRaffle: MutableLiveData = MutableLiveData() fun init(isAttendee: Boolean) { // initial fetch diff --git a/app/src/main/res/drawable/shop_unselected_tab.xml b/app/src/main/res/drawable/shop_unselected_tab.xml new file mode 100644 index 000000000..157ce0d9b --- /dev/null +++ b/app/src/main/res/drawable/shop_unselected_tab.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_point_shop.xml b/app/src/main/res/layout/fragment_point_shop.xml index a137d7376..e87603c51 100644 --- a/app/src/main/res/layout/fragment_point_shop.xml +++ b/app/src/main/res/layout/fragment_point_shop.xml @@ -129,6 +129,7 @@ android:layout_height="wrap_content" android:layout_marginHorizontal="5dp" android:layout_marginTop="12dp" + android:background="@drawable/shop_unselected_tab" android:fontFamily="@font/montserrat_bold" android:gravity="center" android:paddingVertical="10dp" From 84e2764d12625e5eb5c0321d2c6d8e86535b6557 Mon Sep 17 00:00:00 2001 From: Leah Ludwikowski Date: Sun, 4 Feb 2024 15:45:45 -0600 Subject: [PATCH 48/52] Fixed brown dividers by adding them to the shop tile layout --- .../android/view/shop/ShopAdapter.kt | 7 +- .../android/view/shop/ShopFragment.kt | 39 --- .../main/res/drawable/point_shop_divider.xml | 3 - .../main/res/drawable/shop_selected_tab.xml | 8 +- .../main/res/drawable/shop_unselected_tab.xml | 8 +- app/src/main/res/layout/shop_tile.xml | 246 ++++++++++-------- 6 files changed, 144 insertions(+), 167 deletions(-) diff --git a/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt b/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt index 0da8d92ed..b78cb3aab 100644 --- a/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt +++ b/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt @@ -5,6 +5,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.ImageView +import android.widget.TextView import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide import kotlinx.android.synthetic.main.shop_tile.view.* @@ -38,7 +39,11 @@ class ShopAdapter(private var itemList: List) : private fun bind(item: ShopItem, itemView: View, position: Int) { itemView.apply { - shopCardView.setBackgroundResource(R.drawable.point_shop_tile_bg) + // set the top brown divider for the first item to be visible + if (position == 1) { + val topDivider: TextView = itemView.findViewById(R.id.brownDividerTop) + topDivider.visibility = View.VISIBLE + } shopItemTextView.text = item.name priceTextView.text = item.price.toString() diff --git a/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt b/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt index 87ceeb330..bede9aca8 100644 --- a/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt +++ b/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt @@ -1,8 +1,6 @@ package org.hackillinois.android.view.shop import android.content.Context -import android.graphics.Canvas -import android.graphics.drawable.Drawable import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -88,7 +86,6 @@ class ShopFragment : Fragment() { mLayoutManager = LinearLayoutManager(context) this.layoutManager = mLayoutManager this.adapter = mAdapter - addDividers() } shopViewModel.shopLiveData.observe( @@ -122,42 +119,6 @@ class ShopFragment : Fragment() { return view } - class DividerItemDecorator(context: Context) : RecyclerView.ItemDecoration() { - private val mDivider: Drawable = ContextCompat.getDrawable(context, R.drawable.point_shop_divider)!! - override fun onDrawOver(canvas: Canvas, parent: RecyclerView, state: RecyclerView.State) { - val dividerLeft = parent.paddingLeft - val dividerRight = parent.width - parent.paddingRight - val childCount = parent.childCount // how many items recyclerview has - for (i in 0..childCount - 1) { // minus 1 to account for zero index and not skip last item - val child = parent.getChildAt(i) - val params = child.layoutParams as RecyclerView.LayoutParams - val dividerTop = child.bottom + params.bottomMargin - val dividerBottom = dividerTop + mDivider.intrinsicHeight - mDivider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom) - mDivider.draw(canvas) - - // add divider to top of recyclerview - if (i == 0) { - val topDividerTop = parent.paddingTop - val topDividerBottom = topDividerTop + mDivider.intrinsicHeight - mDivider.setBounds(dividerLeft, topDividerTop, dividerRight, topDividerBottom) - mDivider.draw(canvas) - } - } - } - } - private fun RecyclerView.addDividers() { - if (layoutManager !is LinearLayoutManager) { - return - } - - addItemDecoration(DividerItemDecorator(context)) - } - -// private fun updateShop(newShop: List) { -// mAdapter.updateShop(newShop) -// } - // Called in onCreateView within shopLiveData.observe private fun updateShop(newShop: List) { // Split the shop items into Merch and Raffle items diff --git a/app/src/main/res/drawable/point_shop_divider.xml b/app/src/main/res/drawable/point_shop_divider.xml index 6a70df16c..85fa04f42 100644 --- a/app/src/main/res/drawable/point_shop_divider.xml +++ b/app/src/main/res/drawable/point_shop_divider.xml @@ -1,8 +1,5 @@ - \ No newline at end of file diff --git a/app/src/main/res/drawable/shop_selected_tab.xml b/app/src/main/res/drawable/shop_selected_tab.xml index e70eecc77..bf6a75890 100644 --- a/app/src/main/res/drawable/shop_selected_tab.xml +++ b/app/src/main/res/drawable/shop_selected_tab.xml @@ -2,9 +2,7 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable/shop_unselected_tab.xml b/app/src/main/res/drawable/shop_unselected_tab.xml index 157ce0d9b..93aaeccf2 100644 --- a/app/src/main/res/drawable/shop_unselected_tab.xml +++ b/app/src/main/res/drawable/shop_unselected_tab.xml @@ -2,9 +2,7 @@ - + \ No newline at end of file diff --git a/app/src/main/res/layout/shop_tile.xml b/app/src/main/res/layout/shop_tile.xml index f28ded09b..18681269a 100644 --- a/app/src/main/res/layout/shop_tile.xml +++ b/app/src/main/res/layout/shop_tile.xml @@ -5,131 +5,149 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> - + android:layout_height="10dp" + android:background="@drawable/point_shop_divider" + android:visibility="gone" + app:layout_constraintEnd_toStartOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> - + + + - + - + - + - + - + - + - + - + - + - \ No newline at end of file From bf4dc47de3dbe16bc4630f6369112b327097af46 Mon Sep 17 00:00:00 2001 From: Leah Ludwikowski Date: Sun, 4 Feb 2024 15:58:04 -0600 Subject: [PATCH 49/52] Simplified merch/raffle tab logic (removed unnecessary LiveData) --- .../android/view/shop/ShopFragment.kt | 35 ++++--------------- .../android/viewmodel/ShopViewModel.kt | 4 --- 2 files changed, 6 insertions(+), 33 deletions(-) diff --git a/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt b/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt index bede9aca8..6050d0b27 100644 --- a/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt +++ b/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt @@ -36,12 +36,11 @@ class ShopFragment : Fragment() { private lateinit var merchButton: TextView private lateinit var raffleButton: TextView - private lateinit var merchItems: List - private lateinit var raffleItems: List + private var merchItems: List = listOf() + private var raffleItems: List = listOf() // Merch tab is default selected private var showingMerch: Boolean = true - private var showingRaffle: Boolean = false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -54,24 +53,6 @@ class ShopFragment : Fragment() { } else { shopViewModel.init(false) } - - // Observes value of showMerch and updates showingMerch value accordingly - shopViewModel.showMerch.observe( - this, - Observer { - showingMerch = it ?: false - updateShopUI() - }, - ) - - // Observes value of showMerch and updates showingRaffle value accordingly - shopViewModel.showRaffle.observe( - this, - Observer { - showingRaffle = it ?: false - updateShopUI() - }, - ) } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { @@ -92,7 +73,7 @@ class ShopFragment : Fragment() { viewLifecycleOwner, Observer { // will split shop items into Merch or Raffle category - updateShop(it) + updateShopItems(it) }, ) @@ -120,7 +101,7 @@ class ShopFragment : Fragment() { } // Called in onCreateView within shopLiveData.observe - private fun updateShop(newShop: List) { + private fun updateShopItems(newShop: List) { // Split the shop items into Merch and Raffle items merchItems = newShop.filter { !it.isRaffle } raffleItems = newShop.filter { it.isRaffle } @@ -142,10 +123,8 @@ class ShopFragment : Fragment() { merchButton.background = this.context?.let { it1 -> ContextCompat.getDrawable(it1, R.drawable.shop_selected_tab) } raffleButton.isSelected = false raffleButton.background = this.context?.let { it1 -> ContextCompat.getDrawable(it1, R.drawable.shop_unselected_tab) } - shopViewModel.showMerch.postValue(true) - shopViewModel.showRaffle.postValue(false) showingMerch = true - showingRaffle = false + updateShopUI() } } @@ -156,10 +135,8 @@ class ShopFragment : Fragment() { raffleButton.background = this.context?.let { it1 -> ContextCompat.getDrawable(it1, R.drawable.shop_selected_tab) } merchButton.isSelected = false merchButton.background = this.context?.let { it1 -> ContextCompat.getDrawable(it1, R.drawable.shop_unselected_tab) } - shopViewModel.showRaffle.postValue(true) - shopViewModel.showMerch.postValue(false) - showingRaffle = true showingMerch = false + updateShopUI() } } diff --git a/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt b/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt index 3afd3fd4a..93dd98516 100644 --- a/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt +++ b/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt @@ -1,7 +1,6 @@ package org.hackillinois.android.viewmodel import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import org.hackillinois.android.database.entity.Profile import org.hackillinois.android.database.entity.ShopItem @@ -19,9 +18,6 @@ class ShopViewModel : ViewModel() { lateinit var timerObj: Timer - var showMerch: MutableLiveData = MutableLiveData() - var showRaffle: MutableLiveData = MutableLiveData() - fun init(isAttendee: Boolean) { // initial fetch shopLiveData = shopRepository.fetchShop() From e43d7d77e0192d2dd1f8cad82d8c743a6cffe484 Mon Sep 17 00:00:00 2001 From: Leah Ludwikowski Date: Sun, 4 Feb 2024 16:11:12 -0600 Subject: [PATCH 50/52] Small layout/padding modifications --- .../java/org/hackillinois/android/view/shop/ShopAdapter.kt | 3 +++ app/src/main/res/layout/fragment_point_shop.xml | 4 ++-- app/src/main/res/layout/shop_tile.xml | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt b/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt index b78cb3aab..8569bdca1 100644 --- a/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt +++ b/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt @@ -43,6 +43,9 @@ class ShopAdapter(private var itemList: List) : if (position == 1) { val topDivider: TextView = itemView.findViewById(R.id.brownDividerTop) topDivider.visibility = View.VISIBLE + } else { + val topDivider: TextView = itemView.findViewById(R.id.brownDividerTop) + topDivider.visibility = View.GONE } shopItemTextView.text = item.name diff --git a/app/src/main/res/layout/fragment_point_shop.xml b/app/src/main/res/layout/fragment_point_shop.xml index e87603c51..b69b9aa91 100644 --- a/app/src/main/res/layout/fragment_point_shop.xml +++ b/app/src/main/res/layout/fragment_point_shop.xml @@ -99,7 +99,7 @@ android:id="@+id/recyclerview_point_shop" android:layout_height="0dp" android:layout_width="match_parent" - android:layout_marginHorizontal="30dp" + android:layout_marginHorizontal="20dp" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@id/merchButton" @@ -152,6 +152,6 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" - app:layout_constraintGuide_percent="0.88" /> + app:layout_constraintGuide_percent="0.86" /> \ No newline at end of file diff --git a/app/src/main/res/layout/shop_tile.xml b/app/src/main/res/layout/shop_tile.xml index 18681269a..d01731ce2 100644 --- a/app/src/main/res/layout/shop_tile.xml +++ b/app/src/main/res/layout/shop_tile.xml @@ -82,7 +82,7 @@ android:layout_width="wrap_content" android:layout_height="0dp" android:layout_marginVertical="3dp" - android:paddingStart="10dp" + android:paddingStart="8dp" app:layout_constraintBottom_toBottomOf="@+id/priceTextView" app:layout_constraintEnd_toStartOf="@+id/priceTextView" app:layout_constraintHorizontal_chainStyle="packed" From 6c6b73e7cb78e968a68fbe162c7ea3440114d035 Mon Sep 17 00:00:00 2001 From: Leah Ludwikowski Date: Sun, 4 Feb 2024 16:16:49 -0600 Subject: [PATCH 51/52] added try-catch around Glide image loading --- .../org/hackillinois/android/view/shop/ShopAdapter.kt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt b/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt index 8569bdca1..cae359555 100644 --- a/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt +++ b/app/src/main/java/org/hackillinois/android/view/shop/ShopAdapter.kt @@ -1,6 +1,7 @@ package org.hackillinois.android.view.shop import android.content.Context +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -11,6 +12,7 @@ import com.bumptech.glide.Glide import kotlinx.android.synthetic.main.shop_tile.view.* import org.hackillinois.android.R import org.hackillinois.android.database.entity.ShopItem +import java.lang.Exception class ShopAdapter(private var itemList: List) : RecyclerView.Adapter() { @@ -54,9 +56,12 @@ class ShopAdapter(private var itemList: List) : val quantity = item.quantity quantityTextView.text = resources.getString(R.string.shopquantity, quantity) - val imageURL = item.imageURL val shopItemImageView: ImageView = itemView.findViewById(R.id.shopItemImageView) - Glide.with(context).load(imageURL).into(shopItemImageView) + try { + Glide.with(context).load(item.imageURL).into(shopItemImageView) + } catch (e: Exception) { + Log.d("Shop Glide Error", e.message.toString()) + } } } From ae75c9fa78204897c7258201237792d4c4b70383 Mon Sep 17 00:00:00 2001 From: Leah Ludwikowski Date: Sun, 4 Feb 2024 16:20:14 -0600 Subject: [PATCH 52/52] reverted name home_bg_2023 to home_bg --- .../res/drawable/{home_bg_2023.png => home_bg.png} | Bin app/src/main/res/layout/fragment_event_info.xml | 2 +- app/src/main/res/layout/fragment_leaderboard.xml | 2 +- app/src/main/res/layout/fragment_profile.xml | 2 +- .../res/layout/fragment_profile_not_logged_in.xml | 2 +- app/src/main/res/layout/fragment_schedule.xml | 2 +- 6 files changed, 5 insertions(+), 5 deletions(-) rename app/src/main/res/drawable/{home_bg_2023.png => home_bg.png} (100%) diff --git a/app/src/main/res/drawable/home_bg_2023.png b/app/src/main/res/drawable/home_bg.png similarity index 100% rename from app/src/main/res/drawable/home_bg_2023.png rename to app/src/main/res/drawable/home_bg.png diff --git a/app/src/main/res/layout/fragment_event_info.xml b/app/src/main/res/layout/fragment_event_info.xml index 31d7e3c18..2b884d122 100644 --- a/app/src/main/res/layout/fragment_event_info.xml +++ b/app/src/main/res/layout/fragment_event_info.xml @@ -11,7 +11,7 @@ android:layout_marginBottom="0dp" android:adjustViewBounds="true" android:scaleType="centerCrop" - android:src="@drawable/home_bg_2023" + android:src="@drawable/home_bg" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" diff --git a/app/src/main/res/layout/fragment_leaderboard.xml b/app/src/main/res/layout/fragment_leaderboard.xml index c9a0ab076..44f54f9f6 100644 --- a/app/src/main/res/layout/fragment_leaderboard.xml +++ b/app/src/main/res/layout/fragment_leaderboard.xml @@ -13,7 +13,7 @@ android:layout_marginBottom="0dp" android:adjustViewBounds="true" android:scaleType="centerCrop" - android:src="@drawable/home_bg_2023" + android:src="@drawable/home_bg" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" diff --git a/app/src/main/res/layout/fragment_profile.xml b/app/src/main/res/layout/fragment_profile.xml index aeb037bcd..2ca739cf4 100644 --- a/app/src/main/res/layout/fragment_profile.xml +++ b/app/src/main/res/layout/fragment_profile.xml @@ -14,7 +14,7 @@ android:layout_marginBottom="0dp" android:adjustViewBounds="true" android:scaleType="centerCrop" - android:src="@drawable/home_bg_2023" + android:src="@drawable/home_bg" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" diff --git a/app/src/main/res/layout/fragment_profile_not_logged_in.xml b/app/src/main/res/layout/fragment_profile_not_logged_in.xml index be44a82df..776ffe707 100644 --- a/app/src/main/res/layout/fragment_profile_not_logged_in.xml +++ b/app/src/main/res/layout/fragment_profile_not_logged_in.xml @@ -17,7 +17,7 @@ app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" - android:src="@drawable/home_bg_2023"/> + android:src="@drawable/home_bg"/> + android:src="@drawable/home_bg"/>