Skip to content

Commit 80deb58

Browse files
feat: add Event Locations
1 parent 4966b07 commit 80deb58

File tree

11 files changed

+205
-15
lines changed

11 files changed

+205
-15
lines changed

app/schemas/org.fossasia.openevent.general.OpenEventDatabase/1.json

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"formatVersion": 1,
33
"database": {
44
"version": 1,
5-
"identityHash": "0b3cd25764884626e03f56b0600d1c76",
5+
"identityHash": "bb590b41a39e6d611da5b6d45d5505be",
66
"entities": [
77
{
88
"tableName": "Event",
@@ -836,7 +836,7 @@
836836
},
837837
{
838838
"tableName": "Order",
839-
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `paymentMode` TEXT, `country` TEXT, `status` TEXT, `amount` REAL, `identifier` TEXT, `orderNotes` TEXT, `completedAt` TEXT, `city` TEXT, `address` TEXT, `createdAt` TEXT, `zipcode` TEXT, `paidVia` TEXT, `discountCodeId` TEXT, `ticketsPdfUrl` TEXT, `transactionId` TEXT, `event` INTEGER, `attendees` TEXT, PRIMARY KEY(`id`), FOREIGN KEY(`event`) REFERENCES `Event`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`attendees`) REFERENCES `Attendee`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
839+
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `paymentMode` TEXT, `country` TEXT, `status` TEXT, `amount` REAL, `identifier` TEXT, `orderNotes` TEXT, `completedAt` TEXT, `city` TEXT, `address` TEXT, `createdAt` TEXT, `zipcode` TEXT, `paidVia` TEXT, `discountCodeId` TEXT, `ticketsPdfUrl` TEXT, `transactionId` TEXT, `event` INTEGER, `attendees` TEXT NOT NULL, PRIMARY KEY(`id`), FOREIGN KEY(`event`) REFERENCES `Event`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`attendees`) REFERENCES `Attendee`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
840840
"fields": [
841841
{
842842
"fieldPath": "id",
@@ -944,7 +944,7 @@
944944
"fieldPath": "attendees",
945945
"columnName": "attendees",
946946
"affinity": "TEXT",
947-
"notNull": false
947+
"notNull": true
948948
}
949949
],
950950
"primaryKey": {
@@ -1067,11 +1067,44 @@
10671067
]
10681068
}
10691069
]
1070+
},
1071+
{
1072+
"tableName": "EventLocation",
1073+
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `name` TEXT, `slug` TEXT, PRIMARY KEY(`id`))",
1074+
"fields": [
1075+
{
1076+
"fieldPath": "id",
1077+
"columnName": "id",
1078+
"affinity": "INTEGER",
1079+
"notNull": false
1080+
},
1081+
{
1082+
"fieldPath": "name",
1083+
"columnName": "name",
1084+
"affinity": "TEXT",
1085+
"notNull": false
1086+
},
1087+
{
1088+
"fieldPath": "slug",
1089+
"columnName": "slug",
1090+
"affinity": "TEXT",
1091+
"notNull": false
1092+
}
1093+
],
1094+
"primaryKey": {
1095+
"columnNames": [
1096+
"id"
1097+
],
1098+
"autoGenerate": false
1099+
},
1100+
"indices": [],
1101+
"foreignKeys": []
10701102
}
10711103
],
1104+
"views": [],
10721105
"setupQueries": [
10731106
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
1074-
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"0b3cd25764884626e03f56b0600d1c76\")"
1107+
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"bb590b41a39e6d611da5b6d45d5505be\")"
10751108
]
10761109
}
1077-
}
1110+
}

app/src/main/java/org/fossasia/openevent/general/OpenEventDatabase.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import org.fossasia.openevent.general.auth.UserDao
1313
import org.fossasia.openevent.general.event.Event
1414
import org.fossasia.openevent.general.event.EventDao
1515
import org.fossasia.openevent.general.event.EventIdConverter
16+
import org.fossasia.openevent.general.event.location.EventLocation
17+
import org.fossasia.openevent.general.event.location.EventLocationDao
1618
import org.fossasia.openevent.general.event.topic.EventTopic
1719
import org.fossasia.openevent.general.event.topic.EventTopicIdConverter
1820
import org.fossasia.openevent.general.event.topic.EventTopicsDao
@@ -25,7 +27,7 @@ import org.fossasia.openevent.general.ticket.TicketDao
2527
import org.fossasia.openevent.general.ticket.TicketIdConverter
2628

2729
@Database(entities = [Event::class, User::class, SocialLink::class, Ticket::class, Attendee::class,
28-
EventTopic::class, Order::class, CustomForm::class], version = 1)
30+
EventTopic::class, Order::class, CustomForm::class, EventLocation::class], version = 1)
2931
@TypeConverters(EventIdConverter::class, EventTopicIdConverter::class, TicketIdConverter::class,
3032
AttendeeIdConverter::class, ListAttendeeIdConverter::class)
3133
abstract class OpenEventDatabase : RoomDatabase() {
@@ -42,5 +44,7 @@ abstract class OpenEventDatabase : RoomDatabase() {
4244

4345
abstract fun eventTopicsDao(): EventTopicsDao
4446

47+
abstract fun eventLocationsDao(): EventLocationDao
48+
4549
abstract fun orderDao(): OrderDao
4650
}

app/src/main/java/org/fossasia/openevent/general/di/Modules.kt

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ import org.fossasia.openevent.general.event.EventService
3939
import org.fossasia.openevent.general.common.EventsDiffCallback
4040
import org.fossasia.openevent.general.event.EventsListAdapter
4141
import org.fossasia.openevent.general.event.EventsViewModel
42+
import org.fossasia.openevent.general.event.location.EventLocation
43+
import org.fossasia.openevent.general.event.location.EventLocationApi
4244
import org.fossasia.openevent.general.event.topic.EventTopic
4345
import org.fossasia.openevent.general.event.topic.EventTopicApi
4446
import org.fossasia.openevent.general.event.topic.SimilarEventsViewModel
@@ -118,11 +120,15 @@ val apiModule = module {
118120
val retrofit: Retrofit = get()
119121
retrofit.create(PaypalApi::class.java)
120122
}
123+
single {
124+
val retrofit: Retrofit = get()
125+
retrofit.create(EventLocationApi::class.java)
126+
}
121127

122128
factory { AuthHolder(get()) }
123129
factory { AuthService(get(), get(), get()) }
124130

125-
factory { EventService(get(), get(), get(), get()) }
131+
factory { EventService(get(), get(), get(), get(), get(), get()) }
126132
factory { TicketService(get(), get()) }
127133
factory { SocialLinksService(get(), get()) }
128134
factory { AttendeeService(get(), get(), get()) }
@@ -137,7 +143,7 @@ val viewModelModule = module {
137143
viewModel { EventDetailsViewModel(get()) }
138144
viewModel { SearchViewModel(get(), get(), get()) }
139145
viewModel { AttendeeViewModel(get(), get(), get(), get(), get(), get()) }
140-
viewModel { SearchLocationViewModel(get()) }
146+
viewModel { SearchLocationViewModel(get(), get()) }
141147
viewModel { TicketsViewModel(get(), get(), get()) }
142148
viewModel { AboutEventViewModel(get()) }
143149
viewModel { SocialLinksViewModel(get()) }
@@ -188,7 +194,7 @@ val networkModule = module {
188194
SignUp::class.java, Ticket::class.java, SocialLink::class.java, EventId::class.java,
189195
EventTopic::class.java, Attendee::class.java, TicketId::class.java, Order::class.java,
190196
AttendeeId::class.java, Charge::class.java, Paypal::class.java, ConfirmOrder::class.java,
191-
CustomForm::class.java))
197+
CustomForm::class.java, EventLocation::class.java))
192198
.addConverterFactory(JacksonConverterFactory.create(objectMapper))
193199
.baseUrl(baseUrl)
194200
.build()
@@ -238,6 +244,11 @@ val databaseModule = module {
238244
val database: OpenEventDatabase = get()
239245
database.orderDao()
240246
}
247+
248+
factory {
249+
val database: OpenEventDatabase = get()
250+
database.eventLocationsDao()
251+
}
241252
}
242253

243254
val fragmentsModule = module {

app/src/main/java/org/fossasia/openevent/general/event/EventService.kt

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ package org.fossasia.openevent.general.event
33
import io.reactivex.Completable
44
import io.reactivex.Flowable
55
import io.reactivex.Single
6+
import org.fossasia.openevent.general.event.location.EventLocation
7+
import org.fossasia.openevent.general.event.location.EventLocationApi
8+
import org.fossasia.openevent.general.event.location.EventLocationDao
69
import org.fossasia.openevent.general.event.topic.EventTopic
710
import org.fossasia.openevent.general.event.topic.EventTopicApi
811
import org.fossasia.openevent.general.event.topic.EventTopicsDao
@@ -12,7 +15,9 @@ class EventService(
1215
private val eventApi: EventApi,
1316
private val eventDao: EventDao,
1417
private val eventTopicApi: EventTopicApi,
15-
private val eventTopicsDao: EventTopicsDao
18+
private val eventTopicsDao: EventTopicsDao,
19+
private val eventLocationApi: EventLocationApi,
20+
private val eventLocationDao: EventLocationDao
1621
) {
1722

1823
fun getEvents(): Flowable<List<Event>> {
@@ -33,6 +38,23 @@ class EventService(
3338
}
3439
}
3540

41+
fun getEventLocations(): Flowable<List<EventLocation>> {
42+
val eventsLocationFlowable = eventLocationDao.getAllEventLocation()
43+
return eventsLocationFlowable.switchMap {
44+
if (it.isNotEmpty())
45+
eventsLocationFlowable
46+
else
47+
eventLocationApi.getEventLocation()
48+
.map {
49+
eventLocationDao.insertEventLocations(it)
50+
}
51+
.toFlowable()
52+
.flatMap {
53+
eventsLocationFlowable
54+
}
55+
}
56+
}
57+
3658
private fun getEventTopicList(eventsList: List<Event>): List<EventTopic?> {
3759
return eventsList
3860
.filter { it.eventTopic != null }
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.fossasia.openevent.general.event.location
2+
3+
import androidx.room.Entity
4+
import androidx.room.PrimaryKey
5+
import com.github.jasminb.jsonapi.LongIdHandler
6+
import com.github.jasminb.jsonapi.annotations.Id
7+
import com.github.jasminb.jsonapi.annotations.Type
8+
9+
@Type("event-location")
10+
@Entity
11+
data class EventLocation(
12+
@Id(LongIdHandler::class)
13+
@PrimaryKey
14+
val id: Long?,
15+
val name: String?,
16+
val slug: String?
17+
)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package org.fossasia.openevent.general.event.location
2+
3+
import io.reactivex.Single
4+
import retrofit2.http.GET
5+
6+
interface EventLocationApi {
7+
8+
@GET("event-locations?sort=name")
9+
fun getEventLocation(): Single<List<EventLocation>>
10+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.fossasia.openevent.general.event.location
2+
3+
import androidx.room.Dao
4+
import androidx.room.Insert
5+
import androidx.room.OnConflictStrategy
6+
import androidx.room.Query
7+
import io.reactivex.Flowable
8+
9+
@Dao
10+
interface EventLocationDao {
11+
12+
@Insert(onConflict = OnConflictStrategy.REPLACE)
13+
fun insertEventLocations(eventLocation: List<EventLocation?>)
14+
15+
@Query("SELECT * from EventLocation")
16+
fun getAllEventLocation(): Flowable<List<EventLocation>>
17+
18+
@Query("DELETE FROM EventLocation")
19+
fun deleteAll()
20+
}

app/src/main/java/org/fossasia/openevent/general/search/SearchLocationFragment.kt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import android.os.Bundle
66
import android.view.LayoutInflater
77
import android.view.View
88
import android.view.ViewGroup
9+
import android.widget.ArrayAdapter
910
import androidx.appcompat.app.AppCompatActivity
1011
import androidx.core.content.ContextCompat
1112
import androidx.fragment.app.Fragment
@@ -19,8 +20,10 @@ import com.mapbox.mapboxsdk.plugins.places.autocomplete.ui.PlaceAutocompleteFrag
1920
import com.mapbox.mapboxsdk.plugins.places.autocomplete.ui.PlaceSelectionListener
2021
import kotlinx.android.synthetic.main.fragment_search_location.view.currentLocationLinearLayout
2122
import kotlinx.android.synthetic.main.fragment_search_location.view.locationProgressBar
23+
import kotlinx.android.synthetic.main.fragment_search_location.view.eventLocationLv
2224
import org.fossasia.openevent.general.BuildConfig
2325
import org.fossasia.openevent.general.R
26+
import org.fossasia.openevent.general.utils.extensions.nonNull
2427
import org.koin.androidx.viewmodel.ext.android.viewModel
2528

2629
const val LOCATION_PERMISSION_REQUEST = 1000
@@ -31,6 +34,7 @@ class SearchLocationFragment : Fragment() {
3134
private val searchLocationViewModel by viewModel<SearchLocationViewModel>()
3235
private val geoLocationViewModel by viewModel<GeoLocationViewModel>()
3336
private val safeArgs: SearchLocationFragmentArgs by navArgs()
37+
private val eventLocationList : MutableList<String> = ArrayList()
3438

3539
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
3640
rootView = inflater.inflate(R.layout.fragment_search_location, container, false)
@@ -40,6 +44,22 @@ class SearchLocationFragment : Fragment() {
4044
thisActivity.supportActionBar?.hide()
4145
}
4246
setHasOptionsMenu(true)
47+
searchLocationViewModel.loadEventsLocation()
48+
val adapter = ArrayAdapter(context, android.R.layout.simple_list_item_1, eventLocationList)
49+
rootView.eventLocationLv.adapter = adapter
50+
51+
searchLocationViewModel.eventLocations
52+
.nonNull()
53+
.observe(this, Observer { list ->
54+
list.forEach {
55+
eventLocationList.add(it.name ?: "")
56+
}
57+
adapter.notifyDataSetChanged()
58+
})
59+
rootView.eventLocationLv.setOnItemClickListener { parent, view, position, id ->
60+
searchLocationViewModel.saveSearch(eventLocationList[position])
61+
redirectToMain()
62+
}
4363

4464
geoLocationViewModel.currentLocationVisibility.observe(viewLifecycleOwner, Observer {
4565
rootView.currentLocationLinearLayout.visibility = View.GONE
Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,40 @@
11
package org.fossasia.openevent.general.search
22

3+
import androidx.lifecycle.LiveData
4+
import androidx.lifecycle.MutableLiveData
35
import androidx.lifecycle.ViewModel
6+
import io.reactivex.android.schedulers.AndroidSchedulers
7+
import io.reactivex.disposables.CompositeDisposable
8+
import io.reactivex.schedulers.Schedulers
49
import org.fossasia.openevent.general.data.Preference
10+
import org.fossasia.openevent.general.event.EventService
11+
import org.fossasia.openevent.general.event.location.EventLocation
12+
import timber.log.Timber
513

614
const val SAVED_LOCATION = "LOCATION"
715

8-
class SearchLocationViewModel(private val preference: Preference) : ViewModel() {
16+
class SearchLocationViewModel(
17+
private val eventService: EventService,
18+
private val preference: Preference
19+
) : ViewModel() {
20+
21+
private val compositeDisposable = CompositeDisposable()
22+
private val mutableEventLocations = MutableLiveData<List<EventLocation>>()
23+
val eventLocations: LiveData<List<EventLocation>> = mutableEventLocations
924

1025
fun saveSearch(query: String) {
1126
preference.putString(SAVED_LOCATION, query)
1227
}
28+
29+
fun loadEventsLocation() {
30+
compositeDisposable.add(eventService.getEventLocations()
31+
.subscribeOn(Schedulers.io())
32+
.observeOn(AndroidSchedulers.mainThread())
33+
.subscribe({
34+
mutableEventLocations.value = it
35+
}, {
36+
Timber.e(it, "Error fetching events")
37+
})
38+
)
39+
}
1340
}

0 commit comments

Comments
 (0)