From b5c92f0cd27fe4823eba6a261b17cd324d4fa524 Mon Sep 17 00:00:00 2001 From: DawnImpulse Date: Thu, 4 Oct 2018 16:52:43 +0530 Subject: [PATCH] New : User profile + logout (trello.com/c/9eFy2Z4p) --- app/build.gradle | 1 + app/src/main/AndroidManifest.xml | 8 +- .../wallup/activities/UserActivity.kt | 90 +++++++++++++++++++ .../wallup/models/UnsplashModel.kt | 17 ++++ .../wallup/repositories/UnsplashRepository.kt | 22 +++++ .../wallup/sheets/ModalSheetNav.kt | 21 ++++- .../wallup/source/RetroUnsplashSource.kt | 10 ++- .../kotlin/com/dawnimpulse/wallup/utils/C.kt | 4 + .../com/dawnimpulse/wallup/utils/Dialog.kt | 52 +++++++++++ app/src/main/res/drawable/vd_account.xml | 6 ++ app/src/main/res/drawable/vd_logout.xml | 6 ++ app/src/main/res/layout/activity_user.xml | 81 +++++++++++++++++ .../res/layout/bottom_sheet_navigation.xml | 39 +++++--- app/src/main/res/values/colors.xml | 2 + 14 files changed, 340 insertions(+), 19 deletions(-) create mode 100644 app/src/main/kotlin/com/dawnimpulse/wallup/activities/UserActivity.kt create mode 100644 app/src/main/kotlin/com/dawnimpulse/wallup/utils/Dialog.kt create mode 100644 app/src/main/res/drawable/vd_account.xml create mode 100644 app/src/main/res/drawable/vd_logout.xml create mode 100644 app/src/main/res/layout/activity_user.xml diff --git a/app/build.gradle b/app/build.gradle index ca1eddb..c7c30e2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -71,6 +71,7 @@ dependencies { implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.24.0' //kotlin co-routines implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + implementation 'androidx.appcompat:appcompat:1.0.0-alpha1' } apply plugin: 'com.google.gms.google-services' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c8addf9..ba14e99 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -131,7 +131,7 @@ + android:theme="@style/AppTheme.Fullscreen" /> + + + + \ No newline at end of file diff --git a/app/src/main/kotlin/com/dawnimpulse/wallup/activities/UserActivity.kt b/app/src/main/kotlin/com/dawnimpulse/wallup/activities/UserActivity.kt new file mode 100644 index 0000000..84dcb26 --- /dev/null +++ b/app/src/main/kotlin/com/dawnimpulse/wallup/activities/UserActivity.kt @@ -0,0 +1,90 @@ +/* +ISC License + +Copyright 2018, Saksham (DawnImpulse) + +Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, +provided that the above copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE +OR PERFORMANCE OF THIS SOFTWARE.*/ +package com.dawnimpulse.wallup.activities + +import android.content.DialogInterface +import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +import androidx.core.widget.toast +import com.dawnimpulse.wallup.R +import com.dawnimpulse.wallup.handlers.ImageHandler +import com.dawnimpulse.wallup.models.UnsplashModel +import com.dawnimpulse.wallup.pojo.UserPojo +import com.dawnimpulse.wallup.utils.C +import com.dawnimpulse.wallup.utils.Config +import com.dawnimpulse.wallup.utils.Dialog +import com.dawnimpulse.wallup.utils.L +import com.google.gson.Gson +import com.pixplicity.easyprefs.library.Prefs +import kotlinx.android.synthetic.main.activity_user.* + +/** + * @author Saksham + * + * @note Last Branch Update - master + * @note Created on 2018-10-04 by Saksham + * + * @note Updates : + */ +class UserActivity : AppCompatActivity() { + private val NAME = "UserActivity" + private lateinit var model: UnsplashModel + + // on create + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_user) + + // fetching details from prefs + if (Prefs.contains(C.USER)) + setDetails(Gson().fromJson(Prefs.getString(C.USER, ""), UserPojo::class.java)) + + // fetching details from unsplash + model = UnsplashModel(lifecycle) + model.selfProfile() { e, r -> + e?.let { + L.d(NAME, e) + toast("error fetching profile") + } + r?.let { + Prefs.putString(C.USER, Gson().toJson(it)) + setDetails(it as UserPojo) + } + + } + + // logout user + logoutL.setOnClickListener { + Dialog.simpleOk(this, + "User Profile Logout", + "Wish to logout from your profile ?", + DialogInterface.OnClickListener { dialog, _ -> + Prefs.remove(C.USER_TOKEN) + Prefs.remove(C.USER) + Config.USER_API_KEY = "" + dialog.dismiss() + toast("Successfully logout from your profile") + finish() + }) + } + } + + //set user details + private fun setDetails(user: UserPojo) { + userFullName.text = user.name + userName.text = "@${user.username}" + ImageHandler.setImageInView(lifecycle, userImage, user.profile_image.large) + ImageHandler.setImageInView(lifecycle, userBg, "${C.UNSPLASH_SOURCE}/user/${user.username}/720x1280") + } +} diff --git a/app/src/main/kotlin/com/dawnimpulse/wallup/models/UnsplashModel.kt b/app/src/main/kotlin/com/dawnimpulse/wallup/models/UnsplashModel.kt index 075419b..a1530f8 100644 --- a/app/src/main/kotlin/com/dawnimpulse/wallup/models/UnsplashModel.kt +++ b/app/src/main/kotlin/com/dawnimpulse/wallup/models/UnsplashModel.kt @@ -32,6 +32,7 @@ import com.dawnimpulse.wallup.repositories.UnsplashRepository * 2018 09 08 - master - Saksham - featured curatedCollections * 2018 09 22 - master - Saksham - random images tag * 2018 10 01 - master - Saksham - generate bearer token + * 2018 10 04 - master - Saksham - self profile */ class UnsplashModel() { private lateinit var lifecycle: Lifecycle @@ -306,4 +307,20 @@ class UnsplashModel() { }) } } + + // self profile + fun selfProfile(callback: (Any?, Any?) -> Unit){ + UnsplashRepository.selfProfile() { e, r -> + lifecycle.addObserver(object : LifecycleObserver { + var once = true + @OnLifecycleEvent(Lifecycle.Event.ON_START) + fun onStart() { + if (once) { + callback(e, r) + once = false + } + } + }) + } + } } \ No newline at end of file diff --git a/app/src/main/kotlin/com/dawnimpulse/wallup/repositories/UnsplashRepository.kt b/app/src/main/kotlin/com/dawnimpulse/wallup/repositories/UnsplashRepository.kt index 37ea840..72bce5a 100644 --- a/app/src/main/kotlin/com/dawnimpulse/wallup/repositories/UnsplashRepository.kt +++ b/app/src/main/kotlin/com/dawnimpulse/wallup/repositories/UnsplashRepository.kt @@ -41,6 +41,7 @@ import retrofit2.Response * 2018 09 14 - master - Saksham - user's collections * 2018 09 22 - master - Saksham - random images tag * 2018 10 01 - master - Saksham - generate bearer token + * 2018 10 04 - master - Saksham - user profile */ object UnsplashRepository { private val NAME = "UnsplashRepository" @@ -481,5 +482,26 @@ object UnsplashRepository { }) } + // user profile + fun selfProfile(callback: (Any?, Any?) -> Unit){ + val apiClient = RetroApiClient.getClient()!!.create(RetroUnsplashSource::class.java) + val call = apiClient.selfProfile( + Config.apiKey() + ) + + call.enqueue(object : Callback { + + override fun onResponse(call: Call?, response: Response) { + if (response.isSuccessful) + callback(null, response.body()) + else + callback(ErrorUtils.parseError(response), null) + } + + override fun onFailure(call: Call?, t: Throwable?) { + t?.toString()?.let { L.d(NAME, it) } + } + }) + } } diff --git a/app/src/main/kotlin/com/dawnimpulse/wallup/sheets/ModalSheetNav.kt b/app/src/main/kotlin/com/dawnimpulse/wallup/sheets/ModalSheetNav.kt index b7309fc..0df7536 100644 --- a/app/src/main/kotlin/com/dawnimpulse/wallup/sheets/ModalSheetNav.kt +++ b/app/src/main/kotlin/com/dawnimpulse/wallup/sheets/ModalSheetNav.kt @@ -18,14 +18,17 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.appcompat.app.AppCompatActivity import com.dawnimpulse.wallup.BuildConfig import com.dawnimpulse.wallup.R import com.dawnimpulse.wallup.activities.AboutActivity import com.dawnimpulse.wallup.activities.CollectionLayoutActivity import com.dawnimpulse.wallup.activities.GeneralImagesActivity +import com.dawnimpulse.wallup.activities.UserActivity import com.dawnimpulse.wallup.utils.C import com.dawnimpulse.wallup.utils.F import com.dawnimpulse.wallup.utils.RemoteConfig +import com.pixplicity.easyprefs.library.Prefs import kotlinx.android.synthetic.main.bottom_sheet_navigation.* @@ -37,8 +40,10 @@ import kotlinx.android.synthetic.main.bottom_sheet_navigation.* * * @note Updates : * Saksham - 2018 09 15 - master - update handling + * Saksham - 2018 10 04 - master - user */ class ModalSheetNav : RoundedBottomSheetDialogFragment(), View.OnClickListener { + private lateinit var sheet: ModalSheetUnsplash // on create override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { @@ -49,10 +54,13 @@ class ModalSheetNav : RoundedBottomSheetDialogFragment(), View.OnClickListener { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + sheet = ModalSheetUnsplash() + sheetNavRandom.setOnClickListener(this) sheetNavFeedback.setOnClickListener(this) sheetNavCollection.setOnClickListener(this) sheetNavAbout.setOnClickListener(this) + sheetNavUser.setOnClickListener(this) RemoteConfig.getProductionUpdateValues()?.let { if (it.next_version_code > BuildConfig.VERSION_CODE) { @@ -74,19 +82,24 @@ class ModalSheetNav : RoundedBottomSheetDialogFragment(), View.OnClickListener { startActivity(intent) dismiss() } - sheetNavFeedback.id -> F.sendMail(activity!!) sheetNavCollection.id -> { startActivity(Intent(activity, CollectionLayoutActivity::class.java)) dismiss() } - sheetNavAbout.id -> { startActivity(Intent(activity, AboutActivity::class.java)) dismiss() } + sheetNavFeedback.id -> F.sendMail(activity!!) + sheetNavUpdateL.id -> F.startWeb(context!!, C.WALLUP_PLAY) + sheetNavUser.id -> { + if (!Prefs.contains(C.USER_TOKEN)) + sheet.show((context as AppCompatActivity).supportFragmentManager, sheet.tag) + else + startActivity(Intent(context, UserActivity::class.java)) - sheetNavUpdateL.id -> - F.startWeb(context!!, C.WALLUP_PLAY) + dismiss() + } } } } \ No newline at end of file diff --git a/app/src/main/kotlin/com/dawnimpulse/wallup/source/RetroUnsplashSource.kt b/app/src/main/kotlin/com/dawnimpulse/wallup/source/RetroUnsplashSource.kt index fed65aa..e6a7ab7 100644 --- a/app/src/main/kotlin/com/dawnimpulse/wallup/source/RetroUnsplashSource.kt +++ b/app/src/main/kotlin/com/dawnimpulse/wallup/source/RetroUnsplashSource.kt @@ -112,7 +112,7 @@ interface RetroUnsplashSource { @POST("/photos/{id}/like") fun likeImage( @Header(C.AUTHORIZATION) authorization: String, - @Path(C.ID) id:String + @Path(C.ID) id: String ): Call // ------------------------------ @@ -121,10 +121,9 @@ interface RetroUnsplashSource { @DELETE("/photos/{id}/like") fun unlikeImage( @Header(C.AUTHORIZATION) authorization: String, - @Path(C.ID) id:String + @Path(C.ID) id: String ): Call - //________________________________ // USER //________________________________ @@ -161,6 +160,11 @@ interface RetroUnsplashSource { @Query(C.USERNAME) username: String ): Call> + @GET("/me") + fun selfProfile( + @Header(C.AUTHORIZATION) authorization: String + ): Call + //________________________________ // Collection diff --git a/app/src/main/kotlin/com/dawnimpulse/wallup/utils/C.kt b/app/src/main/kotlin/com/dawnimpulse/wallup/utils/C.kt index 750ddbd..55da18c 100644 --- a/app/src/main/kotlin/com/dawnimpulse/wallup/utils/C.kt +++ b/app/src/main/kotlin/com/dawnimpulse/wallup/utils/C.kt @@ -61,6 +61,9 @@ object C { const val FEATURE = "feature" const val BUG = "bug" const val USER_TOKEN = "userToken" + const val USER = "user" + + const val UTM = "?utm_source=wallup&utm_medium=referral" const val UNSPLASH = "https://unsplash.com$UTM" @@ -76,6 +79,7 @@ object C { const val REDIRECT = "wallup://sourcei.org" const val UNSPLASH_OAUTH = "https://unsplash.com/oauth/authorize" const val UNSPLASH_TOKEN = "https://unsplash.com/oauth/token" + const val UNSPLASH_SOURCE = "https://source.unsplash.com" const val ERROR_CODE_1 = 601 const val ERROR_CODE_2 = 602 diff --git a/app/src/main/kotlin/com/dawnimpulse/wallup/utils/Dialog.kt b/app/src/main/kotlin/com/dawnimpulse/wallup/utils/Dialog.kt new file mode 100644 index 0000000..fe1881c --- /dev/null +++ b/app/src/main/kotlin/com/dawnimpulse/wallup/utils/Dialog.kt @@ -0,0 +1,52 @@ +/* +ISC License + +Copyright 2018, Saksham (DawnImpulse) + +Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, +provided that the above copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE +OR PERFORMANCE OF THIS SOFTWARE.*/package com.dawnimpulse.wallup.utils + +import android.content.Context +import android.content.DialogInterface +import androidx.appcompat.app.AlertDialog + + +/** + * @author Saksham + * + * @note Last Branch Update - + * @note Created on 2018-10-04 by Saksham + * + * @note Updates : + */ +object Dialog { + private lateinit var alertDialog: AlertDialog + + // simple ok dialog + fun simpleOk(context: Context, title: String,message: String, positive: DialogInterface.OnClickListener) { + var builder = AlertDialog.Builder(context) + builder + .setTitle(title) + .setMessage(message) + .setPositiveButton("OK", positive) + .setNegativeButton("CANCEL") { dialog, _ -> + dialog.dismiss() + } + .setCancelable(false) + + alertDialog = builder.create() + alertDialog.show() + + } + + // dismiss + fun dismiss(){ + alertDialog.dismiss() + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/vd_account.xml b/app/src/main/res/drawable/vd_account.xml new file mode 100644 index 0000000..a212882 --- /dev/null +++ b/app/src/main/res/drawable/vd_account.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/vd_logout.xml b/app/src/main/res/drawable/vd_logout.xml new file mode 100644 index 0000000..8fd1e55 --- /dev/null +++ b/app/src/main/res/drawable/vd_logout.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_user.xml b/app/src/main/res/layout/activity_user.xml new file mode 100644 index 0000000..23a26fb --- /dev/null +++ b/app/src/main/res/layout/activity_user.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/bottom_sheet_navigation.xml b/app/src/main/res/layout/bottom_sheet_navigation.xml index 01617b3..c98243c 100644 --- a/app/src/main/res/layout/bottom_sheet_navigation.xml +++ b/app/src/main/res/layout/bottom_sheet_navigation.xml @@ -179,15 +179,14 @@ OR PERFORMANCE OF THIS SOFTWARE. - + + android:background="?android:attr/selectableItemBackgroundBorderless"> + app:srcCompat="@drawable/vd_account" /> - + + android:layout_weight="1" + android:background="?android:attr/selectableItemBackgroundBorderless" + android:visibility="invisible"> + + + + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index cacba35..542bc71 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -25,6 +25,8 @@ OR PERFORMANCE OF THIS SOFTWARE. #BDBDBD #9E9E9E + #0091EA + #E8F5E9 #2E7D32 #ffee33