Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • Commit451/LabCoat
  • Iktwo/GitLabAndroid
  • jonduran3000/GitLabAndroid
  • steffandroid/GitLabAndroid
  • xiaoyanit/GitLabAndroid
  • scottolcott/GitLabAndroid
  • james.mu/GitLabAndroid
  • pushkarpandey27/GitLabAndroid
  • atomfrede/GitLabAndroid
  • burrito82/GitLabAndroid
  • txlong_onz/GitLabAndroid
  • ricardo.longa/GitLabAndroid
  • rubenroy/GitLabAndroid
  • remy_android/GitLabAndroid
  • mzestars/GitLabAndroid
  • theobisproject/LabCoat
  • tarek360/GitLabAndroid
  • TR4Android/LabCoat
  • lvsmart/LabCoat
  • buddybuild/LabCoat
  • tkuah/LabCoat
  • jay3126/LabCoat
  • rmad17/LabCoat
  • galvatron/LabCoat
  • lijianjian13/LabCoat
  • Cody2333/LabCoat
  • ajtfreitas/LabCoat
  • nestor.lobo/LabCoat
  • Microgamer/LabCoat
  • irvinwang/LabCoat
  • avallete/LabCoat
  • digicazter/LabCoat
  • lovexiaov/LabCoat
  • dineshkarpe/LabCoat
  • bak1an/LabCoat
  • loomis/LabCoat
  • sank20/LabCoat
  • Jawnnyfoo/LabCoat
  • scottyab/LabCoat
  • aleksandar-stefanovic/LabCoat
  • tfontana/LabCoat
  • fuzzmz/LabCoat
  • dipaksavaliya/LabCoat
  • adi.bk/LabCoat
  • andreea.voicu/LabCoat
  • H1ghT0p/LabCoat
  • indritqoku/LabCoat
  • armpogart/LabCoat
  • eyedol/LabCoat
  • khairulnizan/LabCoat
  • vadm.perspectiva/LabCoat
  • yiyoss1986/LabCoat
  • BRoy98/LabCoat
  • satyarth.23/LabCoat
  • victorpe76/LabCoat
  • canhnht/LabCoat
  • jinhu/LabCoat
  • weathery/LabCoat
  • gitlabproject_s/LabCoat
  • tfKamran/LabCoat
  • voxadam/LabCoat
  • nprail/LabCoat
  • terrakok/LabCoat
  • jungletian/LabCoat
  • goldins/LabCoat
  • insanum/LabCoat
  • lzrs/LabCoat
  • shankarg/LabCoat
  • rm3l/LabCoat
  • alamo_dev/LabCoat
  • insomniaqc/LabCoat
  • mrasif/LabCoat
  • Babasile/LabCoat
  • eeyoo/LabCoat
  • ditkin/LabCoat
  • unbubot/LabCoat
  • bschuhm/LabCoat
  • fanticker/LabCoat
  • colorwebdesigner/LabCoat
  • milouse/LabCoat
80 results
Show changes
Commits on Source (3)
Showing
with 197 additions and 500 deletions
Change Log
==========
 
Version 2.5.0
----------------------------
- Change login to reflect API changes in GitLab
Version 2.4.12
----------------------------
 
Loading
Loading
debug: true
components:
- build-tools;26.0.1
- platforms;android-26
- extras;google;m2repository
- build-tools;27.0.0
- platforms;android-27
Loading
Loading
@@ -4,7 +4,7 @@ buildscript {
}
 
dependencies {
classpath 'io.fabric.tools:gradle:1.24.1'
classpath 'io.fabric.tools:gradle:1.24.5'
}
}
 
Loading
Loading
@@ -17,30 +17,24 @@ apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'io.fabric'
 
def versionMajor = 2
def versionMinor = 4
def versionPatch = 12
def versionBuild = 0 // bump for dogfood builds, public betas, etc.
android {
compileSdkVersion 26
buildToolsVersion "26.0.1"
compileSdkVersion 27
buildToolsVersion "27.0.0"
 
project.ext {
LABCOAT_FABRIC_KEY = project.hasProperty("LABCOAT_FABRIC_KEY") ? project.LABCOAT_FABRIC_KEY : ""
KEYSTORE_PATH = project.hasProperty("KEYSTORE_PATH") ? project.KEYSTORE_PATH : " "
KEYSTORE_PASSWORD = project.hasProperty("KEYSTORE_PASSWORD") ? project.KEYSTORE_PASSWORD : " "
KEYSTORE_ALIAS = project.hasProperty("KEYSTORE_ALIAS") ? project.KEYSTORE_ALIAS : " "
KEY_PASSWORD = project.hasProperty("KEY_PASSWORD") ? project.KEY_PASSWORD : " "
}
 
defaultConfig {
applicationId "com.commit451.gitlab"
minSdkVersion 16
targetSdkVersion 26
targetSdkVersion 27
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
versionCode versionMajor * 1000000 + versionMinor * 10000 + versionPatch * 100 + versionBuild
versionName "${versionMajor}.${versionMinor}.${versionPatch}"
versionCode 2050000
versionName "2.5.0"
manifestPlaceholders = [fabric_key: project.ext.LABCOAT_FABRIC_KEY]
vectorDrawables.useSupportLibrary = true
 
Loading
Loading
@@ -64,7 +58,7 @@ android {
release {
storeFile file(project.ext.KEYSTORE_PATH)
storePassword project.ext.KEYSTORE_PASSWORD
keyAlias project.ext.KEYSTORE_ALIAS
keyAlias "commit451"
keyPassword project.ext.KEY_PASSWORD
}
}
Loading
Loading
@@ -99,17 +93,16 @@ android {
}
 
ext {
supportLibVersion = '26.1.0'
supportLibVersion = '27.0.1'
retrofitVersion = '2.3.0'
okHttpVersion = '3.9.0'
okHttpVersion = '3.9.1'
butterknifeVersion = '8.8.1'
parcelerVersion = '1.1.9'
reptarVersion = '2.5.1'
adapterLayout = '1.1.1'
materialDialogsVersion = '0.9.4.7'
adapterLayout = '1.1.2'
materialDialogsVersion = '0.9.5.0'
leakCanaryVersion = '1.5.3'
addendumVersion = '1.4.0'
alakazamVersion = '1.0.1'
addendumVersion = '1.6.0'
moshiVersion = '1.5.0'
}
 
Loading
Loading
@@ -147,15 +140,15 @@ dependencies {
implementation 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.1.0'
implementation "com.jakewharton:butterknife:$butterknifeVersion"
kapt "com.jakewharton:butterknife-compiler:$butterknifeVersion"
implementation 'com.jakewharton.timber:timber:4.5.1'
implementation 'com.jakewharton.timber:timber:4.6.0'
implementation 'com.jakewharton.threetenabp:threetenabp:1.0.5'
 
implementation 'org.greenrobot:eventbus:3.0.0'
implementation 'org.greenrobot:eventbus:3.1.1'
 
implementation 'io.reactivex.rxjava2:rxjava:2.1.3'
implementation 'io.reactivex.rxjava2:rxjava:2.1.6'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
 
implementation 'com.trello.rxlifecycle2:rxlifecycle-components:2.2.0'
implementation 'com.trello.rxlifecycle2:rxlifecycle-components:2.2.1'
 
implementation "org.parceler:parceler-api:$parcelerVersion"
kapt "org.parceler:parceler:$parcelerVersion"
Loading
Loading
@@ -172,21 +165,22 @@ dependencies {
implementation("com.wefika:flowlayout:0.4.1") {
exclude group: 'com.intellij', module: 'annotations'
}
implementation 'com.github.Commit451.Easel:easel:2.1.1'
implementation 'com.github.Commit451:Easel:3.0.0'
implementation 'com.github.Commit451:Gimbal:2.0.2'
implementation 'com.github.Commit451:Teleprinter:1.0.2'
implementation 'com.github.Commit451:Jounce:1.0.2'
implementation 'com.github.Commit451:ForegroundViews:2.4.0'
implementation 'com.github.Commit451:MorphTransitions:2.0.0'
implementation "com.github.Commit451.Alakazam:alakazam:$alakazamVersion"
implementation "com.github.Commit451.Alakazam:alakazam-kotlin:$alakazamVersion"
implementation 'com.github.Commit451:Lift:1.2.0'
implementation 'com.github.Commit451:okyo:2.0.0'
implementation "com.github.Commit451:Alakazam:2.0.0"
implementation 'com.github.Commit451:Lift:2.0.1'
implementation 'com.github.Commit451:okyo:3.0.1'
implementation 'com.github.Commit451:OkioProGuardRules:1.11.0.0'
implementation 'com.github.Commit451:RetrofitProguardRules:2.2.0.0'
implementation 'com.github.Commit451:LoganSquareProGuardRules:1.3.7.0'
implementation 'com.github.Commit451:EventBusProGuardRules:3.0.0.0'
implementation "com.github.Commit451.Addendum:addendum:$addendumVersion"
implementation "com.github.Commit451.Addendum:addendum-recyclerview:$addendumVersion"
implementation "com.github.Commit451.Addendum:addendum-design:$addendumVersion"
implementation "com.github.Commit451.Addendum:addendum-parceler:$addendumVersion"
 
implementation 'com.github.chrisbanes:PhotoView:2.1.3'
Loading
Loading
@@ -197,28 +191,28 @@ dependencies {
 
implementation 'com.alexgwyn.recyclerviewsquire:recyclerviewsquire:0.0.6'
 
implementation 'com.github.ivbaranov:materiallettericon:0.2.2'
implementation 'com.github.ivbaranov:materiallettericon:0.2.3'
 
implementation 'com.github.alorma:diff-textview:1.3.0'
 
implementation 'com.wdullaer:materialdatetimepicker:3.3.0'
implementation 'com.wdullaer:materialdatetimepicker:3.4.0'
 
implementation 'com.github.novoda:simple-chrome-custom-tabs:0.1.5'
 
implementation "com.afollestad.material-dialogs:core:$materialDialogsVersion"
implementation "com.afollestad.material-dialogs:commons:$materialDialogsVersion"
 
implementation 'de.hdodenhof:circleimageview:2.1.0'
implementation 'de.hdodenhof:circleimageview:2.2.0'
 
implementation('com.vdurmont:emoji-java:3.3.0') {
implementation('com.vdurmont:emoji-java:4.0.0') {
exclude group: 'org.json', module: 'json'
}
 
implementation 'com.github.jkwiecien:EasyImage:2.0.3'
implementation 'com.github.jkwiecien:EasyImage:2.0.4'
 
implementation 'com.atlassian.commonmark:commonmark:0.10.0'
 
normalImplementation('com.crashlytics.sdk.android:crashlytics:2.6.8@aar') {
normalImplementation('com.crashlytics.sdk.android:crashlytics:2.7.1@aar') {
transitive = true
}
 
Loading
Loading
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.commit451.gitlab">
package="com.commit451.gitlab">
 
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 
<application
android:name=".App"
Loading
Loading
@@ -13,66 +13,93 @@
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name=".activity.LaunchActivity"
android:theme="@style/Activity.Launch">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<action android:name="android.intent.action.MAIN" />
 
<category android:name="android.intent.category.LAUNCHER"/>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".activity.ProjectsActivity"
android:launchMode="singleTask"
android:theme="@style/Activity.Projects"/>
android:theme="@style/Activity.Projects" />
<activity
android:name=".activity.GroupsActivity"
android:launchMode="singleTask"
android:theme="@style/Activity.Groups"/>
android:theme="@style/Activity.Groups" />
<activity
android:name=".activity.ActivityActivity"
android:launchMode="singleTask"
android:theme="@style/Activity.Activity"/>
android:theme="@style/Activity.Activity" />
<activity
android:name=".activity.TodosActivity"
android:launchMode="singleTask"
android:theme="@style/Activity.Todos"/>
<activity android:name=".activity.ProjectActivity"/>
android:theme="@style/Activity.Todos" />
<activity android:name=".activity.ProjectActivity" />
<activity
android:name=".activity.LoginActivity"
android:theme="@style/Activity.Login"/>
<activity android:name=".activity.FileActivity"/>
<activity android:name=".activity.IssueActivity"/>
<activity android:name=".activity.DiffActivity"/>
<activity android:name=".activity.AboutActivity"/>
<activity android:name=".activity.AddUserActivity"/>
android:theme="@style/Activity.Login" />
<activity android:name=".activity.FileActivity" />
<activity android:name=".activity.IssueActivity" />
<activity android:name=".activity.DiffActivity" />
<activity android:name=".activity.AboutActivity" />
<activity android:name=".activity.AddUserActivity" />
<activity
android:name=".activity.UserActivity"
android:theme="@style/Activity.User"/>
<activity android:name=".activity.SearchActivity"/>
android:theme="@style/Activity.User" />
<activity android:name=".activity.SearchActivity" />
<activity
android:name=".activity.GroupActivity"
android:theme="@style/Activity.Group"/>
<activity android:name=".activity.MergeRequestActivity"/>
<activity android:name=".activity.AddIssueActivity"/>
<activity android:name=".activity.MilestoneActivity"/>
<activity android:name=".activity.AddMilestoneActivity"/>
<activity android:name=".activity.BuildActivity"/>
<activity android:name=".activity.PipelineActivity"/>
android:theme="@style/Activity.Group" />
<activity android:name=".activity.MergeRequestActivity" />
<activity android:name=".activity.AddIssueActivity" />
<activity android:name=".activity.MilestoneActivity" />
<activity android:name=".activity.AddMilestoneActivity" />
<activity android:name=".activity.BuildActivity" />
<activity android:name=".activity.PipelineActivity" />
<activity
android:name=".activity.LoadSomeInfoActivity"
android:theme="@style/Activity.Translucent"/>
<activity android:name=".activity.SettingsActivity"/>
<activity android:name=".activity.AddLabelActivity"/>
<activity android:name=".activity.AddNewLabelActivity"/>
android:theme="@style/Activity.Translucent" />
<activity android:name=".activity.SettingsActivity" />
<activity android:name=".activity.AddLabelActivity" />
<activity android:name=".activity.AddNewLabelActivity" />
<activity
android:name=".activity.PickBranchOrTagActivity"
android:theme="@style/Activity.Translucent"/>
<activity android:name=".activity.WebLoginActivity"/>
android:theme="@style/Activity.Translucent" />
<activity
android:name=".activity.AttachActivity"
android:theme="@style/Activity.Translucent"/>
android:theme="@style/Activity.Translucent" />
<activity
android:name=".activity.RoutingActivity"
android:launchMode="singleTask"
Loading
Loading
@@ -81,57 +108,61 @@
 
<!-- Standard Url -->
<intent-filter android:label="@string/deeplink_text">
<action android:name="android.intent.action.VIEW"/>
<action android:name="android.intent.action.VIEW" />
 
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
 
<data android:scheme="@string/deeplink_scheme"/>
<data android:scheme="@string/deeplink_scheme" />
</intent-filter>
</activity>
<activity android:name=".widget.UserFeedWidgetConfigureActivity">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>
<activity android:name=".widget.ProjectFeedWidgetConfigureActivity">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>
<activity android:name=".widget.ProjectFeedWidgetConfigureProjectActivity"/>
 
<activity android:name=".activity.FullscreenImageActivity"/>
<activity android:name=".widget.ProjectFeedWidgetConfigureProjectActivity" />
 
<activity android:name=".activity.DebugActivity"/>
<activity android:name=".activity.FullscreenImageActivity" />
<activity android:name=".activity.DebugActivity" />
 
<receiver
android:name=".widget.UserFeedWidgetProvider"
android:label="User Feed">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
 
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_user_feed"/>
android:resource="@xml/widget_user_feed" />
</receiver>
<receiver
android:name=".widget.ProjectFeedWidgetProvider"
android:label="Project Feed">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
 
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_project_feed"/>
android:resource="@xml/widget_project_feed" />
</receiver>
 
<service
android:name=".widget.ProjectFeedWidgetService"
android:name=".widget.FeedWidgetService"
android:exported="false"
android:permission="android.permission.BIND_REMOTEVIEWS"/>
android:permission="android.permission.BIND_REMOTEVIEWS" />
 
</application>
 
Loading
Loading
Loading
Loading
@@ -15,6 +15,7 @@ import butterknife.ButterKnife
import butterknife.OnClick
import com.commit451.addendum.parceler.getParcelerParcelableExtra
import com.commit451.addendum.parceler.putParcelerParcelableExtra
import com.commit451.addendum.themeAttrColor
import com.commit451.easel.Easel
import com.commit451.gitlab.App
import com.commit451.gitlab.R
Loading
Loading
@@ -83,7 +84,7 @@ class AddMilestoneActivity : MorphActivity() {
now.get(Calendar.MONTH),
now.get(Calendar.DAY_OF_MONTH)
)
dpd.accentColor = Easel.getThemeAttrColor(this, R.attr.colorAccent)
dpd.accentColor = this.themeAttrColor(R.attr.colorAccent)
dpd.show(fragmentManager, "date_picker")
}
 
Loading
Loading
Loading
Loading
@@ -15,7 +15,7 @@ import android.widget.EditText
import butterknife.*
import com.commit451.addendum.parceler.getParcelerParcelableExtra
import com.commit451.addendum.parceler.putParcelerParcelableExtra
import com.commit451.alakazam.HideRunnable
import com.commit451.alakazam.fadeOut
import com.commit451.gitlab.App
import com.commit451.gitlab.R
import com.commit451.gitlab.adapter.UserAdapter
Loading
Loading
@@ -96,9 +96,7 @@ class AddUserActivity : MorphActivity() {
@OnTextChanged(R.id.search)
fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
if (s.isNullOrEmpty()) {
buttonClear.animate()
.alpha(0.0f)
.withEndAction(HideRunnable(buttonClear))
buttonClear.fadeOut()
} else {
buttonClear.visibility = View.VISIBLE
buttonClear.animate().alpha(1.0f)
Loading
Loading
Loading
Loading
@@ -15,7 +15,7 @@ import butterknife.ButterKnife
import butterknife.OnClick
import com.commit451.addendum.parceler.getParcelerParcelableExtra
import com.commit451.addendum.parceler.putParcelerParcelableExtra
import com.commit451.alakazam.kotlin.fadeIn
import com.commit451.alakazam.fadeIn
import com.commit451.gitlab.App
import com.commit451.gitlab.R
import com.commit451.gitlab.extension.setup
Loading
Loading
Loading
Loading
@@ -19,7 +19,9 @@ import butterknife.BindView
import butterknife.ButterKnife
import com.commit451.addendum.parceler.getParcelerParcelableExtra
import com.commit451.addendum.parceler.putParcelerParcelableExtra
import com.commit451.alakazam.Alakazam
import com.commit451.addendum.themeAttrColor
import com.commit451.alakazam.navigationBarColorAnimator
import com.commit451.easel.Easel
import com.commit451.gitlab.App
import com.commit451.gitlab.R
Loading
Loading
@@ -121,22 +123,22 @@ class GroupActivity : BaseActivity() {
 
fun bindPalette(palette: Palette) {
val animationTime = 1000
val vibrantColor = palette.getVibrantColor(Easel.getThemeAttrColor(this, R.attr.colorAccent))
val darkerColor = Easel.getDarkerColor(vibrantColor)
val vibrantColor = palette.getVibrantColor(this.themeAttrColor(R.attr.colorAccent))
val darkerColor = Easel.darkerColor(vibrantColor)
 
if (Build.VERSION.SDK_INT >= 21) {
Alakazam.navigationBarColorAnimator(window, darkerColor)
window.navigationBarColorAnimator(darkerColor)
.setDuration(animationTime.toLong())
.start()
}
 
ObjectAnimator.ofObject(collapsingToolbarLayout, "contentScrimColor", ArgbEvaluator(),
Easel.getThemeAttrColor(this, R.attr.colorPrimary), vibrantColor)
this.themeAttrColor(R.attr.colorPrimary), vibrantColor)
.setDuration(animationTime.toLong())
.start()
 
ObjectAnimator.ofObject(collapsingToolbarLayout, "statusBarScrimColor", ArgbEvaluator(),
Easel.getThemeAttrColor(this, R.attr.colorPrimaryDark), darkerColor)
this.themeAttrColor(R.attr.colorPrimaryDark), darkerColor)
.setDuration(animationTime.toLong())
.start()
 
Loading
Loading
Loading
Loading
@@ -22,10 +22,6 @@ import com.commit451.gitlab.ssl.CustomKeyManager
class LaunchActivity : BaseActivity() {
 
companion object {
//Figure out how this works, then reenable
private val PRIVATE_KEY_ENABLED = false
private val REQUEST_DEVICE_AUTH = 123
}
 
Loading
Loading
@@ -57,11 +53,7 @@ class LaunchActivity : BaseActivity() {
} else if (Prefs.isRequiredDeviceAuth) {
showKeyguard()
} else {
if (PRIVATE_KEY_ENABLED) {
loadPrivateKey(accounts, 0)
} else {
moveAlong()
}
moveAlong()
}
}
 
Loading
Loading
@@ -80,26 +72,4 @@ class LaunchActivity : BaseActivity() {
Navigator.navigateToStartingActivity(this)
finish()
}
private fun loadPrivateKey(accounts: List<Account>, i: Int) {
if (i >= accounts.size) {
runOnUiThread { }
return
}
val alias = accounts[i].privateKeyAlias
if (alias != null && !CustomKeyManager.isCached(alias)) {
CustomKeyManager.cache(this, alias, object : CustomKeyManager.KeyCallback {
override fun onSuccess(entry: CustomKeyManager.KeyEntry) {
loadPrivateKey(accounts, i + 1)
}
override fun onError(e: Exception) {
loadPrivateKey(accounts, i + 1)
}
})
} else {
loadPrivateKey(accounts, i + 1)
}
}
}
package com.commit451.gitlab.activity
 
import android.app.Activity
import android.app.AlertDialog
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.security.KeyChain
import android.support.design.widget.Snackbar
import android.support.design.widget.TextInputLayout
import android.support.v7.widget.Toolbar
import android.text.method.LinkMovementMethod
import android.util.Patterns
import android.view.View
import android.widget.EditText
import android.widget.TextView
import butterknife.BindView
import butterknife.ButterKnife
import butterknife.OnClick
import butterknife.OnEditorAction
import com.afollestad.materialdialogs.MaterialDialog
import com.commit451.gitlab.App
import com.commit451.gitlab.BuildConfig
import com.commit451.gitlab.R
Loading
Loading
@@ -26,7 +22,6 @@ import com.commit451.gitlab.api.GitLab
import com.commit451.gitlab.api.GitLabFactory
import com.commit451.gitlab.api.MoshiProvider
import com.commit451.gitlab.api.OkHttpClientFactory
import com.commit451.gitlab.api.request.SessionRequest
import com.commit451.gitlab.data.Prefs
import com.commit451.gitlab.dialog.HttpLoginDialog
import com.commit451.gitlab.event.LoginEvent
Loading
Loading
@@ -40,9 +35,9 @@ import com.commit451.gitlab.model.api.User
import com.commit451.gitlab.navigation.Navigator
import com.commit451.gitlab.rx.CustomResponseSingleObserver
import com.commit451.gitlab.ssl.CustomHostnameVerifier
import com.commit451.gitlab.ssl.CustomKeyManager
import com.commit451.gitlab.ssl.X509CertificateException
import com.commit451.gitlab.ssl.X509Util
import com.commit451.gitlab.util.IntentUtil
import com.commit451.teleprinter.Teleprinter
import okhttp3.Credentials
import okhttp3.HttpUrl
Loading
Loading
@@ -65,8 +60,6 @@ class LoginActivity : BaseActivity() {
 
private val EXTRA_SHOW_CLOSE = "show_close"
 
private val REQUEST_PRIVATE_TOKEN = 123
fun newIntent(context: Context, showClose: Boolean = false): Intent {
val intent = Intent(context, LoginActivity::class.java)
intent.putExtra(EXTRA_SHOW_CLOSE, showClose)
Loading
Loading
@@ -77,32 +70,38 @@ class LoginActivity : BaseActivity() {
@BindView(R.id.root) lateinit var root: View
@BindView(R.id.toolbar) lateinit var toolbar: Toolbar
@BindView(R.id.text_input_layout_server) lateinit var textInputLayoutUrl: TextInputLayout
@BindView(R.id.user_input_hint) lateinit var textInputLayoutUser: TextInputLayout
@BindView(R.id.user_input) lateinit var textUser: EditText
@BindView(R.id.password_hint) lateinit var textInputLayoutPassword: TextInputLayout
@BindView(R.id.password_input) lateinit var textPassword: TextView
@BindView(R.id.token_hint) lateinit var textInputLayoutToken: TextInputLayout
@BindView(R.id.token_input) lateinit var textToken: TextView
@BindView(R.id.normal_login) lateinit var rootNormalLogin: View
@BindView(R.id.token_login) lateinit var rootTokenLogin: View
@BindView(R.id.progress) lateinit var progress: View
 
lateinit var teleprinter: Teleprinter
 
var isNormalLogin = true
val emailPattern: Pattern by lazy {
Patterns.EMAIL_ADDRESS
}
val tokenPattern: Pattern by lazy {
Pattern.compile("^[A-Za-z0-9-_]*$")
}
var account: Account = Account()
var gitLab: GitLab? = null
 
@OnEditorAction(R.id.password_input, R.id.token_input)
fun onPasswordEditorAction(): Boolean {
onLoginClick()
return true
@OnClick(R.id.button_info)
fun onInfoClicked() {
MaterialDialog.Builder(this)
.title(R.string.access_token_info_title)
.content(R.string.access_token_info_message)
.positiveText(R.string.create_personal_access_token)
.onPositive { _, _ ->
val validUrl = verifyUrl()
if (validUrl) {
val url = textInputLayoutUrl.text()
val accessTokenUrl = "$url/profile/personal_access_tokens"
IntentUtil.openPage(this, accessTokenUrl)
} else {
Snackbar.make(root, R.string.not_a_valid_url, Snackbar.LENGTH_SHORT)
.show()
}
}
.negativeText(R.string.cancel)
.show()
}
 
@OnClick(R.id.login_button)
Loading
Loading
@@ -118,24 +117,18 @@ class LoginActivity : BaseActivity() {
}
val uri = textInputLayoutUrl.text()
 
if (isNormalLogin) {
val valid = textInputLayoutUser.checkValid() and textInputLayoutPassword.checkValid()
if (!valid) {
return
}
if (!textInputLayoutToken.checkValid()) {
return
}
if (!tokenPattern.matcher(textToken.text).matches()) {
textInputLayoutToken.error = getString(R.string.not_a_valid_private_token)
return
} else {
if (!textInputLayoutToken.checkValid()) {
return
}
if (!tokenPattern.matcher(textToken.text).matches()) {
textInputLayoutToken.error = getString(R.string.not_a_valid_private_token)
return
} else {
textInputLayoutToken.error = null
}
textInputLayoutToken.error = null
}
 
if (isAlreadySignedIn(uri.toString(), if (isNormalLogin) textUser.text.toString() else textToken.text.toString())) {
if (isAlreadySignedIn(uri, textToken.text.toString())) {
Snackbar.make(root, getString(R.string.already_logged_in), Snackbar.LENGTH_LONG)
.show()
return
Loading
Loading
@@ -147,22 +140,6 @@ class LoginActivity : BaseActivity() {
login()
}
 
@OnClick(R.id.button_open_login_page)
fun onOpenLoginPageClicked() {
if (verifyUrl()) {
val url = textInputLayoutUrl.editText!!.text.toString()
Navigator.navigateToWebSignin(this, url, true, REQUEST_PRIVATE_TOKEN)
}
}
@OnClick(R.id.button_open_login_page_for_personal_access)
fun onOpenLoginPageForPersonalAccessTokenClicked() {
if (verifyUrl()) {
val url = textInputLayoutUrl.editText!!.text.toString()
Navigator.navigateToWebSignin(this, url, false, REQUEST_PRIVATE_TOKEN)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
Loading
Loading
@@ -171,27 +148,6 @@ class LoginActivity : BaseActivity() {
teleprinter = Teleprinter(this)
val showClose = intent.getBooleanExtra(EXTRA_SHOW_CLOSE, false)
 
toolbar.inflateMenu(R.menu.advanced_login)
toolbar.setOnMenuItemClickListener(Toolbar.OnMenuItemClickListener { item ->
when (item.itemId) {
R.id.action_advanced_login -> {
val isNormalLogin = rootNormalLogin.visibility == View.VISIBLE
if (isNormalLogin) {
rootNormalLogin.visibility = View.GONE
rootTokenLogin.visibility = View.VISIBLE
item.setTitle(R.string.normal_link)
this@LoginActivity.isNormalLogin = false
} else {
rootNormalLogin.visibility = View.VISIBLE
rootTokenLogin.visibility = View.GONE
item.setTitle(R.string.advanced_login)
this@LoginActivity.isNormalLogin = true
}
return@OnMenuItemClickListener true
}
}
false
})
if (showClose) {
toolbar.setNavigationIcon(R.drawable.ic_close_24dp)
toolbar.setNavigationOnClickListener { onBackPressed() }
Loading
Loading
@@ -200,69 +156,15 @@ class LoginActivity : BaseActivity() {
textInputLayoutUrl.editText?.setText(R.string.url_gitlab)
}
 
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
REQUEST_PRIVATE_TOKEN -> if (resultCode == Activity.RESULT_OK) {
val token = data?.getStringExtra(WebLoginActivity.EXTRA_TOKEN)
textInputLayoutToken.editText!!.setText(token)
}
}
override fun hasBrowsableLinks(): Boolean {
return true
}
 
fun connect(byAuth: Boolean) {
fun connect() {
progress.visibility = View.VISIBLE
progress.alpha = 0.0f
progress.animate().alpha(1.0f)
 
if (byAuth) {
connectByAuth()
} else {
connectByToken()
}
}
fun connectByAuth() {
val request = SessionRequest()
request.password = textInputLayoutPassword.text()
val usernameOrEmail = textInputLayoutUser.text()
if (emailPattern.matcher(usernameOrEmail).matches()) {
request.email = usernameOrEmail
} else {
request.login = usernameOrEmail
}
attemptLogin(request)
}
fun attemptLogin(request: SessionRequest) {
val clientBuilder = OkHttpClientFactory.create(account)
if (BuildConfig.DEBUG) {
clientBuilder.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
}
gitLab = GitLabFactory.createGitLab(account, clientBuilder)
gitLab!!.login(request)
.setup(bindToLifecycle())
.subscribe(object : CustomResponseSingleObserver<User>() {
override fun error(e: Throwable) {
Timber.e(e)
if (e is HttpException) {
handleConnectionResponse(response())
} else {
handleConnectionError(e)
}
}
override fun responseNonNullSuccess(userLogin: User) {
account.privateToken = userLogin.privateToken
loadUser(clientBuilder)
}
})
}
fun connectByToken() {
account.privateToken = textToken.text.toString()
val gitlabClientBuilder = OkHttpClientFactory.create(account, false)
if (BuildConfig.DEBUG) {
Loading
Loading
@@ -274,30 +176,6 @@ class LoginActivity : BaseActivity() {
loadUser(gitlabClientBuilder)
}
 
fun loginWithPrivateToken() {
val serverUri = Uri.parse(account.serverUrl)
KeyChain.choosePrivateKeyAlias(this, { alias ->
account.privateKeyAlias = alias
if (alias != null) {
if (!CustomKeyManager.isCached(alias)) {
CustomKeyManager.cache(this@LoginActivity, alias, object : CustomKeyManager.KeyCallback {
override fun onSuccess(entry: CustomKeyManager.KeyEntry) {
runOnUiThread { login() }
}
override fun onError(e: Exception) {
account.privateKeyAlias = null
Timber.e(e, "Failed to load private key")
}
})
} else {
runOnUiThread { login() }
}
}
}, null, null, serverUri.host, serverUri.port, null)
}
fun verifyUrl(): Boolean {
val url = textInputLayoutUrl.text()
var uri: Uri? = null
Loading
Loading
@@ -316,8 +194,7 @@ class LoginActivity : BaseActivity() {
textInputLayoutUrl.error = null
}
if (!url.endsWith("/")) {
textInputLayoutUrl.error = getString(R.string.please_end_your_url_with_a_slash)
return false
textInputLayoutUrl.editText?.setText(url + "/")
} else {
textInputLayoutUrl.error = null
}
Loading
Loading
@@ -327,20 +204,14 @@ class LoginActivity : BaseActivity() {
fun login() {
// This seems useless - But believe me, it makes everything work! Don't remove it.
// (OkHttpClientFactory caches the clients and needs a new account to recreate them)
val newAccount = Account()
newAccount.serverUrl = account.serverUrl
newAccount.trustedCertificate = account.trustedCertificate
newAccount.trustedHostname = account.trustedHostname
newAccount.privateKeyAlias = account.privateKeyAlias
newAccount.authorizationHeader = account.authorizationHeader
account = newAccount
 
if (isNormalLogin) {
connect(true)
} else {
connect(false)
}
connect()
}
 
fun loadUser(gitlabClientBuilder: OkHttpClient.Builder) {
Loading
Loading
@@ -364,8 +235,9 @@ class LoginActivity : BaseActivity() {
 
override fun responseNonNullSuccess(userFull: User) {
progress.visibility = View.GONE
account.user = userFull
account.lastUsed = Date()
account.email = userFull.email
account.username = userFull.username
Prefs.addAccount(account)
App.get().setAccount(account)
App.bus().post(LoginEvent(account))
Loading
Loading
@@ -492,9 +364,7 @@ class LoginActivity : BaseActivity() {
fun isAlreadySignedIn(url: String, usernameOrEmailOrPrivateToken: String): Boolean {
val accounts = Prefs.getAccounts()
return accounts.any {
it.serverUrl == url && (usernameOrEmailOrPrivateToken == it.user?.username
|| usernameOrEmailOrPrivateToken.equals(it.user?.email, ignoreCase = true)
|| usernameOrEmailOrPrivateToken.equals(it.privateToken, ignoreCase = true))
it.serverUrl == url && usernameOrEmailOrPrivateToken == it.privateToken
}
}
}
Loading
Loading
@@ -20,7 +20,7 @@ import com.commit451.addendum.parceler.getParcelerParcelable
import com.commit451.addendum.parceler.getParcelerParcelableExtra
import com.commit451.addendum.parceler.putParcelerParcelable
import com.commit451.addendum.parceler.putParcelerParcelableExtra
import com.commit451.alakazam.HideRunnable
import com.commit451.alakazam.fadeOut
import com.commit451.gitlab.App
import com.commit451.gitlab.R
import com.commit451.gitlab.adapter.ProjectPagerAdapter
Loading
Loading
@@ -196,17 +196,13 @@ class ProjectActivity : BaseActivity() {
 
override fun error(t: Throwable) {
Timber.e(t)
progress.animate()
.alpha(0.0f)
.withEndAction(HideRunnable(progress))
progress.fadeOut()
Snackbar.make(root, getString(R.string.connection_error), Snackbar.LENGTH_SHORT)
.show()
}
 
override fun success(project: Project) {
progress.animate()
.alpha(0.0f)
.withEndAction(HideRunnable(progress))
progress.fadeOut()
bindProject(project)
}
})
Loading
Loading
Loading
Loading
@@ -15,8 +15,9 @@ import butterknife.BindView
import butterknife.ButterKnife
import com.commit451.addendum.parceler.getParcelerParcelableExtra
import com.commit451.addendum.parceler.putParcelerParcelableExtra
import com.commit451.alakazam.Alakazam
import com.commit451.easel.Easel
import com.commit451.addendum.themeAttrColor
import com.commit451.alakazam.navigationBarColorAnimator
import com.commit451.gitlab.App
import com.commit451.gitlab.R
import com.commit451.gitlab.extension.feedUrl
Loading
Loading
@@ -91,23 +92,23 @@ class UserActivity : BaseActivity() {
 
fun bindPalette(palette: Palette) {
val animationTime = 1000
val vibrantColor = palette.getVibrantColor(Easel.getThemeAttrColor(this, R.attr.colorPrimary))
val darkerColor = Easel.getDarkerColor(vibrantColor)
val vibrantColor = palette.getVibrantColor(this.themeAttrColor(R.attr.colorPrimary))
val darkerColor = this.themeAttrColor(vibrantColor)
 
if (Build.VERSION.SDK_INT >= 21) {
Alakazam.navigationBarColorAnimator(window, darkerColor)
window.navigationBarColorAnimator(darkerColor)
.setDuration(animationTime.toLong())
.start()
window.statusBarColor = darkerColor
}
 
ObjectAnimator.ofObject(collapsingToolbarLayout, "contentScrimColor", ArgbEvaluator(),
Easel.getThemeAttrColor(this, R.attr.colorPrimary), vibrantColor)
this.themeAttrColor(R.attr.colorPrimary), vibrantColor)
.setDuration(animationTime.toLong())
.start()
 
ObjectAnimator.ofObject(collapsingToolbarLayout, "statusBarScrimColor", ArgbEvaluator(),
Easel.getThemeAttrColor(this, R.attr.colorPrimaryDark), darkerColor)
this.themeAttrColor(R.attr.colorPrimaryDark), darkerColor)
.setDuration(animationTime.toLong())
.start()
 
Loading
Loading
package com.commit451.gitlab.activity
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.support.annotation.Keep
import android.support.v7.widget.Toolbar
import android.view.View
import android.webkit.*
import butterknife.BindView
import butterknife.ButterKnife
import com.commit451.gitlab.R
import me.zhanghai.android.materialprogressbar.MaterialProgressBar
/**
* Shows user a WebView for login and intercepts the headers to get the private token. Hmmmm
*/
class WebLoginActivity : BaseActivity() {
companion object {
val EXTRA_TOKEN = "token"
private val JAVASCRIPT_INTERFACE_EXTRACTOR = "TokenExtractor"
/**
* This is pretty fragile and has changed in the past, so if this screen ever stops working,
* it's probably due to this id changing. Go inspect the source of the page to verify
*/
private val PRIVATE_TOKEN_HTML_ID = "private-token"
private val KEY_URL = "url"
private val KEY_EXTRACTING_PRIVATE_TOKEN = "extracting_private_token"
fun newIntent(context: Context, url: String, extractingPrivateToken: Boolean): Intent {
val intent = Intent(context, WebLoginActivity::class.java)
intent.putExtra(KEY_URL, url)
intent.putExtra(KEY_EXTRACTING_PRIVATE_TOKEN, extractingPrivateToken)
return intent
}
}
@BindView(R.id.toolbar) lateinit var toolbar: Toolbar
@BindView(R.id.progress) lateinit var progress: MaterialProgressBar
@BindView(R.id.webview) lateinit var webView: WebView
lateinit var url: String
val isExtracting: Boolean by lazy {
intent.getBooleanExtra(KEY_EXTRACTING_PRIVATE_TOKEN, false)
}
val webChromeClient = object : WebChromeClient() {
override fun onProgressChanged(view: WebView, newProgress: Int) {
super.onProgressChanged(view, newProgress)
if (progress.visibility != View.VISIBLE) {
progress.visibility = View.VISIBLE
}
progress.progress = newProgress
if (newProgress == 100) {
progress.visibility = View.GONE
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_webview_login)
ButterKnife.bind(this)
url = intent.getStringExtra(KEY_URL)
if (url.endsWith("/")) {
url = url.substring(0, url.length - 1)
}
toolbar.setNavigationIcon(R.drawable.ic_back_24dp)
toolbar.setNavigationOnClickListener { onBackPressed() }
val settings = webView.settings
settings.javaScriptEnabled = true
webView.addJavascriptInterface(HtmlExtractorJavaScriptInterface(), JAVASCRIPT_INTERFACE_EXTRACTOR)
webView.setWebViewClient(ExtractionWebClient())
webView.setWebChromeClient(webChromeClient)
webView.clearCache(true)
webView.clearFormData()
webView.clearHistory()
clearCookies()
webView.loadUrl(url + "/users/sign_in")
}
@Suppress("DEPRECATION")
fun clearCookies() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
CookieManager.getInstance().removeAllCookies(null)
CookieManager.getInstance().flush()
} else {
val cookieSyncManager = CookieSyncManager.createInstance(this)
cookieSyncManager.startSync()
val cookieManager = CookieManager.getInstance()
cookieManager.removeAllCookie()
cookieManager.removeSessionCookie()
cookieSyncManager.stopSync()
cookieSyncManager.sync()
}
}
inner class ExtractionWebClient : WebViewClient() {
override fun onPageFinished(view: WebView, url: String) {
var modifiedUrl = url
if (modifiedUrl.endsWith("/")) {
modifiedUrl = url.substring(0, url.length - 1)
}
if (modifiedUrl == this@WebLoginActivity.url) {
if (isExtracting) {
webView.loadUrl(this@WebLoginActivity.url + "/profile/account")
} else {
webView.loadUrl(this@WebLoginActivity.url + "/profile/personal_access_tokens")
}
return
}
if (modifiedUrl == this@WebLoginActivity.url + "/profile/account") {
webView.loadUrl("javascript:" + JAVASCRIPT_INTERFACE_EXTRACTOR + ".extract" +
"(document.getElementById('" + PRIVATE_TOKEN_HTML_ID + "').value);")
return
}
super.onPageFinished(view, url)
}
}
inner class HtmlExtractorJavaScriptInterface {
@JavascriptInterface
@Keep
fun extract(token: String) {
val data = Intent()
data.putExtra(EXTRA_TOKEN, token)
setResult(Activity.RESULT_OK, data)
finish()
}
}
}
Loading
Loading
@@ -4,6 +4,7 @@ import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.ViewGroup
import android.widget.PopupMenu
import com.commit451.addendum.themeAttrColor
import com.commit451.easel.Easel
import com.commit451.gitlab.App
import com.commit451.gitlab.R
Loading
Loading
@@ -24,7 +25,7 @@ class AccountAdapter(context: Context, private val listener: AccountAdapter.List
}
 
private val accounts = mutableListOf<Account>()
private val colorControlHighlight: Int = Easel.getThemeAttrColor(context, R.attr.colorControlHighlight)
private val colorControlHighlight: Int = context.themeAttrColor(R.attr.colorControlHighlight)
 
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
when (viewType) {
Loading
Loading
Loading
Loading
@@ -12,9 +12,8 @@ import java.io.IOException
class AuthenticationRequestInterceptor(private val account: Account) : Interceptor {
 
companion object {
val AUTHORIZATION_HEADER_FIELD = "Authorization"
val PRIVATE_TOKEN_HEADER_FIELD = "PRIVATE-TOKEN"
val PRIVATE_TOKEN_GET_PARAMETER = "private_token"
const val PRIVATE_TOKEN_HEADER_FIELD = "Private-Token"
private const val PRIVATE_TOKEN_GET_PARAMETER = "private_token"
}
 
@Throws(IOException::class)
Loading
Loading
@@ -30,13 +29,6 @@ class AuthenticationRequestInterceptor(private val account: Account) : Intercept
cleanServerUrl = cleanServerUrl.substring(cleanServerUrl.indexOf(':'))
 
if (cleanUrl.startsWith(cleanServerUrl)) {
val authorizationHeader = account.authorizationHeader
if (authorizationHeader != null) {
request = request.newBuilder()
.header(AUTHORIZATION_HEADER_FIELD, authorizationHeader)
.build()
}
val privateToken = account.privateToken
if (privateToken == null) {
Timber.e("The private token was null")
Loading
Loading
package com.commit451.gitlab.api
 
import com.commit451.gitlab.api.request.SessionRequest
import com.commit451.gitlab.api.response.FileUploadResponse
import com.commit451.gitlab.model.api.*
import io.reactivex.Completable
Loading
Loading
@@ -21,11 +20,6 @@ interface GitLabService {
const val MAX_TREE_PER_PAGE = "100"
}
 
/* --- LOGIN --- */
@POST(API_VERSION + "/session")
fun login(@Body request: SessionRequest): Single<Response<User>>
/* --- USERS --- */
 
/**
Loading
Loading
Loading
Loading
@@ -22,9 +22,12 @@ object OkHttpClientFactory {
fun create(account: Account, includeSignInAuthenticator: Boolean = true): OkHttpClient.Builder {
// A custom trust manager, otherwise SSL won't work properly with some configurations
val customTrustManager = CustomTrustManager()
customTrustManager.setTrustedCertificate(account.trustedCertificate)
customTrustManager.setTrustedHostname(account.trustedHostname)
customTrustManager.setPrivateKeyAlias(account.privateKeyAlias)
account.trustedCertificate?.let {
customTrustManager.setTrustedCertificate(it)
}
account.trustedHostname?.let {
customTrustManager.setTrustedHostname(it)
}
 
val builder = OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
Loading
Loading
package com.commit451.gitlab.api.request
import com.squareup.moshi.Json
/**
* Start a session
*/
class SessionRequest {
@field:Json(name = "email")
var email: String? = null
@field:Json(name = "login")
var login: String? = null
@field:Json(name = "password")
var password: String? = null
}
Loading
Loading
@@ -21,9 +21,9 @@ import timber.log.Timber
*/
object Prefs {
 
val KEY_ACCOUNTS = "accounts"
val KEY_STARTING_VIEW = "starting_view"
val KEY_REQUIRE_DEVICE_AUTH = "require_device_auth"
private const val KEY_ACCOUNTS = "accounts"
private const val KEY_STARTING_VIEW = "starting_view"
private const val KEY_REQUIRE_DEVICE_AUTH = "require_device_auth"
 
const val STARTING_VIEW_PROJECTS = 0
const val STARTING_VIEW_GROUPS = 1
Loading
Loading
Loading
Loading
@@ -5,6 +5,7 @@ import android.os.Bundle
import android.view.View
 
import com.commit451.gitlab.App
import com.commit451.gitlab.activity.BaseActivity
import com.commit451.gitlab.event.ReloadDataEvent
import com.trello.rxlifecycle2.components.support.RxFragment
 
Loading
Loading
@@ -13,9 +14,12 @@ import org.greenrobot.eventbus.Subscribe
 
open class BaseFragment : RxFragment() {
 
var baseEventReceiver: EventReceiver? = null
private var baseEventReceiver: EventReceiver? = null
val baseActivty by lazy {
activity as BaseActivity
}
 
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
 
baseEventReceiver = EventReceiver()
Loading
Loading