Skip to content

Commit

Permalink
Merge branch 'release/1.2' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
mouredev committed Sep 6, 2021
2 parents 6a3f438 + 2b0422a commit 3e95e7b
Show file tree
Hide file tree
Showing 47 changed files with 1,070 additions and 206 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ Twitimer es una App gratuita para **[Android](https://play.google.com/store/apps

* Por razones de seguridad debes añadir tu propio fichero de configuración de Firebase `google-services.json` con Realtime Database activo y las claves de acceso al API de Twitch en Remote Config con los valores `TwitchClientID` y `TwitchClientSecret`.
* Es suficiente con abrir y ejecutar el proyecto desde Android Studio.
* [Puedes ver todo el proceso en este tutorial en YouTube](https://youtu.be/_FLHGY_ATWA)

<a href="https://youtu.be/_FLHGY_ATWA"><img src="http://i3.ytimg.com/vi/_FLHGY_ATWA/maxresdefault.jpg" style="height: 50%; width:50%;"/></a>

### ¿De qué forma utilizamos Twitimer para aprender programación?
* Puedes acceder a su código fuente libremente.
Expand Down
9 changes: 5 additions & 4 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ android {
applicationId "com.mouredev.twitimer"
minSdkVersion 23
targetSdkVersion 30
versionCode 9
versionName "1.1.4"
versionCode 12
versionName "1.2"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
Expand All @@ -37,10 +37,11 @@ android {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
implementation 'androidx.preference:preference-ktx:1.1.1'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.picasso:picasso:2.71828'
Expand Down
22 changes: 11 additions & 11 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.mouredev.twitimer">

<!-- Permissions -->
<uses-permission android:name="android.permission.INTERNET" />
<permission android:name="android.permission.QUERY_ALL_PACKAGES" />

<permission android:name="android.permission.QUERY_ALL_PACKAGES" /> <!-- Queries -->
<queries>
<intent>
<action android:name="android.intent.action.MAIN" />
</intent>
</queries>

<application
android:allowBackup="true"
Expand Down Expand Up @@ -40,7 +45,10 @@
android:name=".usecases.user.UserActivity"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity" />

<activity
android:name=".usecases.settings.SettingsActivity"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity" />

<!-- Push notifications -->
<service
Expand All @@ -57,14 +65,6 @@
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/primary" />

</application>

<!-- Queries -->
<queries>
<intent>
<action android:name="android.intent.action.MAIN" />
</intent>
</queries>

</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ data class DatabaseUser(
val offlineImageUrl: String? = null,
val streamer: Int? = null,
val schedule: List<DatabaseUserSchedule>? = null,
val followedUsers: MutableList<String>? = null
val followedUsers: MutableList<String>? = null,
var settings: DatabaseUserSettings? = null
) {

fun toUser(): User {
Expand All @@ -31,6 +32,7 @@ data class DatabaseUser(
user.streamer = streamer == 1
user.schedule = schedule?.toMutableList()
user.followedUsers = followedUsers ?: arrayListOf()
user.settings = settings?.toUserSettings()

return user
}
Expand All @@ -49,7 +51,20 @@ data class DatabaseUserSchedule(
val weekDayType = WeekdayType.valueFrom(weekDay ?: 0)
val date = date?.toDate()
return UserSchedule(enable == 1, weekDayType, weekDayType, date ?: Date(), duration ?: 1, title ?: "")
}

}

data class DatabaseUserSettings(
val discord: String? = null,
val youtube: String? = null,
val twitter: String? = null,
val instagram: String? = null,
val tiktok: String? = null
) {

fun toUserSettings(): UserSettings {
return UserSettings(discord, youtube, twitter, instagram, tiktok)
}

}
28 changes: 27 additions & 1 deletion app/src/main/java/com/mouredev/twitimer/model/domain/User.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.mouredev.twitimer.model.domain

import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.annotations.SerializedName
import com.mouredev.twitimer.R
Expand Down Expand Up @@ -46,6 +45,7 @@ data class User(
var streamer: Boolean? = null
var schedule: MutableList<UserSchedule>? = null
var followedUsers: MutableList<String>? = null
var settings: UserSettings? = null

fun toJSON(): Map<String, Any> {

Expand All @@ -62,6 +62,7 @@ data class User(
)

JSON[DatabaseField.SCHEDULE.key] = scheduleToJSON()
JSON[DatabaseField.SETTINGS.key] = settingsToJSON()

return JSON
}
Expand All @@ -75,6 +76,10 @@ data class User(
return scheduleJSON
}

fun settingsToJSON(): MutableMap<String, String> {
return settings?.toJSON() ?: mutableMapOf()
}

// Actualiza datos mutables del usuario. Esto ocurre cuando recuperamos de nuevo el usuario de Twitch para actualizarlo en Twitimer.
fun override(user: User): Boolean {

Expand Down Expand Up @@ -272,4 +277,25 @@ enum class WeekdayType(val index: Int) {
}
}

}

data class UserSettings(
var discord: String? = null,
var youtube: String? = null,
var twitter: String? = null,
var instagram: String? = null,
var tiktok: String? = null
) {

fun toJSON(): MutableMap<String, String> {

return mutableMapOf(
DatabaseField.DISCORD.key to (discord ?: ""),
DatabaseField.YOUTUBE.key to (youtube ?: ""),
DatabaseField.TWITTER.key to (twitter ?: ""),
DatabaseField.INSTAGRAM.key to (instagram ?: ""),
DatabaseField.TIKTOK.key to (tiktok ?: "")
)
}

}
22 changes: 22 additions & 0 deletions app/src/main/java/com/mouredev/twitimer/model/session/Session.kt
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,19 @@ class Session {
}
}

fun save(context: Context, settings: UserSettings) {

val savedSettings = savedSettings(context)

if (savedSettings != settings) {
user?.settings = settings
user?.let { user ->
save(context, user)
FirebaseRDBService.saveSettings(user)
}
}
}

fun saveFollow(context: Context, followedUser: User) {

val login = followedUser.login ?: ""
Expand Down Expand Up @@ -380,6 +393,14 @@ class Session {
return null
}

fun savedSettings(context: Context): UserSettings? {

PreferencesProvider.string(context, PreferencesKey.AUTH_USER)?.let {
return User.fromJson(it).settings
}
return null
}

// Private

private fun save(context: Context, user: User) {
Expand Down Expand Up @@ -411,6 +432,7 @@ class Session {
private fun mergeUsers(context: Context, user: User, oldFollowers: Set<String>, success: () -> Unit) {

this.user?.schedule = user.schedule
this.user?.settings = user.settings

// Merge followers
val mergedFollowers = oldFollowers.union(HashSet(user.followedUsers ?: arrayListOf())).toMutableList()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ enum class DatabaseField(val key: String) {
// Schedule
SCHEDULE("schedule"), ENABLE("enable"), WEEKDAY("weekDay"), DATE("date"), DURATION("duration"), TITLE("title"),

FOLLOWED_USERS("followedUsers")
FOLLOWED_USERS("followedUsers"),

// Settings
SETTINGS("settings"), DISCORD("discord"), YOUTUBE("youtube"), TWITTER("twitter"), INSTAGRAM("instagram"), TIKTOK("tiktok")

}


Expand Down Expand Up @@ -58,6 +62,13 @@ object FirebaseRDBService {
}
}

fun saveSettings(user: User) {

user.login?.let { login ->
streamersRef.child(login).child(DatabaseField.SETTINGS.key).setValue(user.settingsToJSON())
}
}

fun search(query: String, success: (users: List<User>?) -> Unit, failure: () -> Unit) {

val validQuery = query.removeFirebaseInvalidCharacters().lowercase()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,14 @@ import android.view.View
import android.view.ViewGroup
import com.mouredev.twitimer.R
import com.mouredev.twitimer.databinding.AccountFragmentBinding
import com.mouredev.twitimer.usecases.account.user.UserFragmentListener
import com.mouredev.twitimer.usecases.account.user.UserRouter
import com.mouredev.twitimer.usecases.common.views.info.InfoFragmentListener
import com.mouredev.twitimer.usecases.common.views.info.InfoRouter
import com.mouredev.twitimer.usecases.common.views.info.InfoViewType
import com.mouredev.twitimer.usecases.common.views.webview.WebViewFragmentListener
import com.mouredev.twitimer.usecases.common.views.webview.WebViewRouter

class AccountFragment : Fragment(), InfoFragmentListener, WebViewFragmentListener, UserFragmentListener {
class AccountFragment : Fragment(), InfoFragmentListener, WebViewFragmentListener {

companion object {
fun fragment() = AccountFragment()
Expand Down Expand Up @@ -56,6 +55,11 @@ class AccountFragment : Fragment(), InfoFragmentListener, WebViewFragmentListene

}

override fun onResume() {
super.onResume()
viewModel.checkSession()
}

// Public

fun setListener(listener: AccountFragmentListener) {
Expand All @@ -75,7 +79,7 @@ class AccountFragment : Fragment(), InfoFragmentListener, WebViewFragmentListene
viewModel.authenticated.observe(activity) { authenticated ->

if (authenticated) {
UserRouter().replace(activity.supportFragmentManager, R.id.accountContainer, null, this)
UserRouter().replace(activity.supportFragmentManager, R.id.accountContainer, null)
}
}

Expand All @@ -94,6 +98,12 @@ class AccountFragment : Fragment(), InfoFragmentListener, WebViewFragmentListene
}
}

private fun searching(show: Boolean) = if (show) {
binding.fragmentProgressBar.visibility = View.VISIBLE
} else {
binding.fragmentProgressBar.visibility = View.GONE
}

// InfoFragmentListener

override fun action() {
Expand All @@ -109,16 +119,4 @@ class AccountFragment : Fragment(), InfoFragmentListener, WebViewFragmentListene
}
}

// UserFragmentListener

override fun onClose() {
viewModel.load()
}

private fun searching(show: Boolean) = if (show) {
binding.fragmentProgressBar.visibility = View.VISIBLE
} else {
binding.fragmentProgressBar.visibility = View.GONE
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ class AccountViewModel : ViewModel() {
info.postValue(false)
}

fun checkSession() {
if (Session.instance.user?.login == null) {
load()
}
}

// Private

private fun authenticate(context: Context, authorizationCode: String, listener: AccountFragmentListener?) {
Expand Down
Loading

0 comments on commit 3e95e7b

Please sign in to comment.