Skip to content

Instantly share code, notes, and snippets.

@abduakhatov
Created April 30, 2018 10:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save abduakhatov/2a9bd650e2f254623022b0c84cd86a54 to your computer and use it in GitHub Desktop.
Save abduakhatov/2a9bd650e2f254623022b0c84cd86a54 to your computer and use it in GitHub Desktop.
class App : Application(),HasActivityInjector {
@Inject
lateinit var activityInjector : DispatchingAndroidInjector<Activity>
override fun onCreate() {
super.onCreate()
DaggerAppComponent.builder().application(this).build().inject(this)
}
override fun activityInjector(): AndroidInjector<Activity> = activityInjector
}
@Singleton
@Component(modules = arrayOf(AndroidSupportInjectionModule::class, MainModule::class))
interface AppComponent{
@Component.Builder
interface Builder {
@BindsInstance
fun application(application:App): Builder
fun build(): AppComponent
}
fun inject (app:App)
}
abstract class BaseActivity : DaggerAppCompatActivity() {
@Inject
@Named(BaseActivityModule.ACTIVITY_NAVIGATOR)
lateinit var navigator: Navigator
}
@Module
abstract class BaseActivityModule {
companion object {
const val ACTIVITY_FRAGMENT_MANAGER = "BaseActivityModule.activityFragmentManager"
const val ACTIVITY_NAVIGATOR = "BaseActivityModule.navigator"
}
@Binds
@Named(ACTIVITY_NAVIGATOR)
@PerActivity
abstract fun bindNavigator (navigator: Navigator) : Navigator
}
abstract class BaseFragment : DaggerFragment() {
@Inject
@Named(BaseFragmentModule.FRAGMENT_NAVIGATOR)
lateinit var navigator: Navigator
}
@Module
abstract class BaseFragmentModule {
companion object {
const val BASE_FRAGMENT_MANAGER = "BaseFragmentModule.baseFragmentManager"
const val FRAGMENT_NAVIGATOR = "BaseFragmentModule.navigator"
}
@Binds
@Named(FRAGMENT_NAVIGATOR)
@PerFragment
abstract fun bindNavigator (navigator: Navigator) : Navigator
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion 27
defaultConfig {
applicationId "uz.wiut.lineup.lineup"
minSdkVersion 17
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile 'com.android.support:multidex:1.0.3'
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support:design:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
implementation 'com.android.support:support-v4:26.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
// kotlin jdk
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:cardview-v7:27.0.2'
//Butterkife
compile "com.jakewharton:butterknife:$butterknife_version"
kapt "com.jakewharton:butterknife-compiler:$butterknife_version"
//dagger 2.11
def daggerVersion = '2.11'
kapt "com.google.dagger:dagger-compiler:$daggerVersion"
kapt "com.google.dagger:dagger-android-processor:$daggerVersion"
implementation "com.google.dagger:dagger:$daggerVersion"
implementation "com.google.dagger:dagger-android:$daggerVersion"
implementation "com.google.dagger:dagger-android-support:$daggerVersion"
// firebase
implementation 'com.google.firebase:firebase-auth:11.0.4'
implementation 'com.google.firebase:firebase-database:11.0.4'
// gradient view
compile 'co.revely:gradient:1.0.1'
implementation project(':component')
// bottom nav bar
compile 'com.aurelhubert:ahbottomnavigation:2.1.0'
}
repositories {
mavenCentral()
}
kapt {
generateStubs = true
}
apply plugin: 'kotlin-android-extensions'
apply plugin: 'com.google.gms.google-services'
@Module(includes = AndroidSupportInjectionModule.class)
public abstract class MainModule {
// Activities
@PerActivity
@ContributesAndroidInjector(modules = TestActivityModule.class)
abstract TestActivity contributeTestActivity();
@PerActivity
@ContributesAndroidInjector(modules = BaseActivityModule.class)
abstract BaseActivity contributeBaseActivity();
@PerActivity
@ContributesAndroidInjector(modules = MainActivityModule.class)
abstract MainActivity contributeMainActivity();
@PerActivity
@ContributesAndroidInjector(modules = SplashScreenModule.class)
abstract SplashScreenActivity contributeSplashScreenActivity();
@PerActivity
@ContributesAndroidInjector(modules = SignUpInActivityModule.class)
abstract SignInUpActivity contributeSignInUpActivity();
@PerActivity
@ContributesAndroidInjector(modules = HomeActivityModule.class)
abstract HomeActivity contributeHomeActivity();
@PerActivity
@ContributesAndroidInjector(modules = OrganizationDetailsActivityModule.class)
abstract OrganizationDetailsActivity contributeDetailsActivity();
// Fragments
@PerFragment
@ContributesAndroidInjector(modules = BaseFragmentModule.class)
abstract BaseFragment contributeBaseFragment();
@PerFragment
@ContributesAndroidInjector(modules = SignInFragmentModule.class)
abstract SignInFragment contributeSignInFragment();
@PerFragment
@ContributesAndroidInjector(modules = SignUpFragmentModule.class)
abstract SignUpFragment contributeSignUpFragment();
@PerFragment
@ContributesAndroidInjector(modules = VerificationFragmentModule.class)
abstract VerificationFragment contributeVerificationFragment();
@PerFragment
@ContributesAndroidInjector(modules = SearchFragmentModule.class)
abstract SearchFragment contributeSearchFragment();
@PerFragment
@ContributesAndroidInjector(modules = MyProfileFragmentModule.class)
abstract MyProfileFragment contributeMyProfileFragment();
@PerFragment
@ContributesAndroidInjector(modules = HomeFragmentModule.class)
abstract HomeFragment contributeHomeFragment();
@PerFragment
@ContributesAndroidInjector(modules = OrganizationDetailsFragmentModule.class)
abstract OrganizationDetailsFragment contributeOrganizationDetailsFragment();
@PerFragment
@ContributesAndroidInjector(modules = BookmarkFragmentModule.class)
abstract BookmarkFragment contributeBookmarkFragment();
// Child Fragments
@PerChildFragment
@ContributesAndroidInjector(modules = CategorySearchFragmentModule.class)
abstract CategorySearchFragment contributeCategorySearchFragment();
@PerChildFragment
@ContributesAndroidInjector(modules = CitySearchFragmentModule.class)
abstract CitySearchFragment contributeCitySearchFragment();
@PerChildFragment
@ContributesAndroidInjector(modules = MapSearchFragmentModule.class)
abstract MapSearchFragment contributeMapSearchFragment();
@PerChildFragment
@ContributesAndroidInjector(modules = SavedFragmentModule.class)
abstract SavedBookmarkFragment contributeSavedFragmentFragment();
@PerChildFragment
@ContributesAndroidInjector(modules = HistoryFragmentModule.class)
abstract HistoryOfBookmarksFragment contributeHistoryFragment();
}
class MoreDetailsFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
return inflater!!.inflate(R.layout.fragment_more_details, container, false)
}
}// Required empty public constructor
//@Singleton
class Navigator {
companion object {
val FOR_RESULT = "forResult"
val LOGIN_REQUEST_CODE = 22
}
@Inject
constructor()
fun startActivity(context: Context, toCall: BaseActivity) {
val intent = Intent(context, toCall::class.java)
context.startActivity(intent)
}
fun startActivityByContext(context: Context) {
val intent = Intent(context, context::class.java)
context.startActivity(intent)
}
fun startActivityWithBundle(context: Context, toCall: BaseActivity, bundle: OrgDetails) {
val i = Intent(context, toCall::class.java)
i.putExtra(Constants.ORG_DETAIL, bundle)
context.startActivity(i)
}
fun startActivityWithTaskClear(context: Context, toCall: BaseActivity) {
val intent = Intent(context, toCall::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
context.startActivity(intent)
}
fun startForResult(context: Activity, toCall: BaseActivity) {
val intent = Intent(context, toCall::class.java)
intent.putExtra(FOR_RESULT, true)
context.startActivityForResult(intent, LOGIN_REQUEST_CODE)
}
fun setSupportActionBar(toolbar: Toolbar) {
setSupportActionBar(toolbar)
}
fun makeToask(context: Context, text: String) {
Toast.makeText(context, text, Toast.LENGTH_SHORT).show()
}
fun changeFragmentWithStack(fragmentManager: FragmentManager, fragment: Fragment, className: String) {
if (fragment != null) {
fragmentManager
.beginTransaction()
.addToBackStack(className)
.replace(R.id.flMainContent, fragment)
.commit()
}
}
fun changeFragment(fragmentManager: FragmentManager, fragment: Fragment) {
if (fragment != null) {
fragmentManager
.beginTransaction()
.replace(R.id.flMainContent, fragment)
.commit()
}
}
fun closeFragment(activity: FragmentActivity) {
if (activity != null) {
activity.supportFragmentManager.popBackStack()
}
}
}
class OrganizationDetailsActivity : BaseActivity(), OrganizationDetailsActivityView {
@Inject
lateinit var presenter : OrganizationDetailsActivityPresenterImpl
@BindView(R.id.toolbar) lateinit var toolbar: Toolbar
@BindView(R.id.tvToolboxTitle) lateinit var tvToolboxTitle: TextView
private var orgDetails = OrgDetails()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_home)
ButterKnife.bind(this)
initUI()
}
private fun initUI() {
loadDataFromBundle()
changeFragment(OrganizationDetailsFragment.newInstance(orgDetails))
rxBusRegister()
}
private fun loadDataFromBundle() {
val extras = intent.extras
if (extras != null) {
orgDetails = intent.getSerializableExtra(Constants.ORG_DETAIL) as OrgDetails
}
}
private fun changeFragment(fragment: Fragment) {
if (fragment != null) {
supportFragmentManager
.beginTransaction()
.addToBackStack(this.localClassName)
.replace(R.id.flMainContent, fragment)
.commit()
}
}
private fun rxBusRegister() {
RxBus2.subscribe(RxBus2.TOOLBAR_HIDE, this, Consumer { o ->
if (o is ChangeToolbarTitle) {
when (supportFragmentManager.findFragmentById(R.id.flMainContent)) {
is OrganizationDetailsFragment -> {
toolbar.visibility = View.GONE
Log.d(Constants.DEBUG, "Queue Details")
tvToolboxTitle.text = "Queue Details"
}
is MoreDetailsFragment -> {
toolbar.visibility = View.GONE
Log.d(Constants.DEBUG, "Details")
tvToolboxTitle.text = "Details"
}
}
} else if (o is ChangeFragment) {
changeFragment(o.fragment)
}
})
}
override fun onDestroy() {
super.onDestroy()
RxBus2.unregister(this)
}
}
@Module
abstract class OrganizationDetailsActivityModule {
@Binds
@PerActivity
abstract fun bindOrganizationDetailsActivity (activity: OrganizationDetailsActivity) : AppCompatActivity
@Binds
@PerActivity
abstract fun bindOrganizationDetailsActivityPresenterView (activity: OrganizationDetailsActivity) : OrganizationDetailsActivityView
@Binds
@PerActivity
abstract fun bindOrganizationDetailsActivityPresenter (presenterImpl: OrganizationDetailsActivityPresenterImpl) : OrganizationDetailsActivityPresenter
}
class OrganizationDetailsFragment : BaseFragment(), OrganizationDetailsFragmentView {
@Inject
lateinit var presenter : OrganizationDetailsFragmentPresenterImpl
@BindView(R.id.llGradContainerMain) lateinit var llGradContainerMain: LinearLayout
@BindView(R.id.tvOrgName) lateinit var tvOrgName: TextView
@BindView(R.id.cvTopContainer) lateinit var cvTopContainer: CardView
@BindView(R.id.llWorkingContainer) lateinit var llWorkingContainer: LinearLayout
@BindView(R.id.tvApproximateTimeTitle2) lateinit var tvApproximateTimeTitle2: TextView
@BindView(R.id.tvApproximateTime2) lateinit var tvApproximateTime2: TextView
@BindView(R.id.tvApproximateTime) lateinit var tvApproximateTime: TextView
@BindView(R.id.tvApproximateTime3) lateinit var tvApproximateTime3: TextView
@BindView(R.id.tvApproximateTimeTitle3) lateinit var tvApproximateTimeTitle3: TextView
@BindView(R.id.tvApproximateTimeTitle) lateinit var tvApproximateTimeTitle: TextView
@BindView(R.id.btnRegister) lateinit var btnRegister: Button
@BindView(R.id.tvMoreInfor) lateinit var tvMoreInfor: TextView
private lateinit var orgDetails: OrgDetails
companion object {
@JvmStatic
fun newInstance(orgDetails: OrgDetails) =
OrganizationDetailsFragment().apply {
arguments = Bundle().apply {
putSerializable(Constants.ORG_DETAIL, orgDetails)
}
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_organization_details, container, false)
ButterKnife.bind(this, view)
init()
return view
}
private fun init() {
setUpGradientBg()
getArgument()
bindData()
}
private fun bindData() {
var org = orgDetails.org!!
var regOrg = orgDetails.regedOrg!!
tvOrgName.text = org.name
tvApproximateTime3.text = regOrg.peopleWaiting.toString()
tvApproximateTime.text = (regOrg.peopleWaiting * regOrg.averageWaitingTime).toString()
tvApproximateTime2.text = calculateApproximateTime()
}
@OnClick(R.id.btnRegister)
fun btnRegisterClick(v: View){
presenter.onRegisterClicked(isNetworkAvailable(), orgDetails)
}
private fun setUpGradientBg() {
RevelyGradient.linear()
.angle(-45f)
.colors(Constants.arrOfColsBelowToolbar)
.onBackgroundOf(llGradContainerMain)
}
private fun calculateApproximateTime(): String {
val now = Calendar.getInstance()
now.add(Calendar.MINUTE, orgDetails.regedOrg!!.peopleWaiting * orgDetails.regedOrg!!.averageWaitingTime)
return SimpleDateFormat("hh:mm").format(now.time)
}
private fun getArgument() {
arguments?.let {
orgDetails = it.getSerializable(Constants.ORG_DETAIL) as OrgDetails
}
}
private fun isNetworkAvailable(): Boolean {
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val activeNetworkInfo = connectivityManager.getActiveNetworkInfo()
return activeNetworkInfo != null
}
override fun saved() {
navigator.makeToask(context, "Saved")
activity.finish()
}
}
@Module
abstract class OrganizationDetailsFragmentModule {
@Binds
@PerFragment
abstract fun bindOrganizationDetailsFragment (fragment: OrganizationDetailsFragment) : Fragment
@Binds
@PerFragment
abstract fun bindOrganizationDetailsFragmentView (fragment: OrganizationDetailsFragment) : OrganizationDetailsFragmentView
@Binds
@PerFragment
abstract fun bindOrganizationDetailsFragmentPresenter (presenterImpl: OrganizationDetailsFragmentPresenterImpl) : OrganizationDetailsFragmentPresenter
}
interface OrganizationDetailsFragmentPresenter {
fun onRegisterClicked(networkAvailable: Boolean, orgDetails: OrgDetails) {}
}
class OrganizationDetailsFragmentPresenterImpl : OrganizationDetailsFragmentPresenter {
@Inject
lateinit var view: OrganizationDetailsFragmentView
private var mAuth: FirebaseAuth?
private var dbRef: DatabaseReference
private var uid: String?
private lateinit var org: Organization
private lateinit var regedOrg: RegisteredOrganization
private var user: User? = null
@Inject
constructor() {
mAuth = FirebaseAuth.getInstance()
dbRef = FirebaseDatabase.getInstance().getReference("v1")
uid = mAuth?.currentUser?.uid
}
override fun onRegisterClicked(networkAvailable: Boolean, orgDetails: OrgDetails) {
org = orgDetails.org!!
regedOrg = orgDetails.regedOrg!!
if (!networkAvailable) sendSMS(org.locationTitle, org.categoryTitle, org.oId)
dbRef.child("usersList/clients/${uid}").addListenerForSingleValueEvent(object : ValueEventListener {//todo look at path
override fun onDataChange(p0: DataSnapshot?) {
if (p0 == null) return
user = p0.getValue<User>(User::class.java)!!
saveQueueData()
}
override fun onCancelled(p0: DatabaseError?) {
}
})
}
private fun saveQueueData() {
var queueUrl = "dailyQueues/${regedOrg.timestamp}/${regedOrg.location}/${regedOrg.category}/${regedOrg.oId}/${regedOrg.queueId}/peopleWaiting/${uid}"
var wp = WaitingPeople()
wp.name = user?.name
wp.phoneNumber = user?.phoneNumber
dbRef.child(queueUrl).setValue(wp)
saveToHistory()
}
private fun saveToHistory() {
var history = History()
history.category = regedOrg.category
history.lastVisit = regedOrg.timestamp
history.location = regedOrg.location
history.oId = regedOrg.oId
var historyUrl = "histories/${uid}"
var key = dbRef.child(historyUrl).push().key
dbRef.child(historyUrl).child(key).setValue(history)
saveToUsersList()
}
private fun saveToUsersList() {
var userUrl = "usersList/clients/${uid}/dQId/${regedOrg.queueId}"
dbRef.child(userUrl).setValue(regedOrg)
view.saved()
}
fun sendSMS(location: String?, category: String?, orgId: String?) {
var number = "0789"
var smsBody = "navbt ${location}_${category}_${orgId}_${uid}"
try {
val sms = SmsManager.getDefault() // using android SmsManager
sms.sendTextMessage(number, null, smsBody, null, null)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
interface OrganizationDetailsFragmentView {
fun saved()
}
@Scope // Required to specify the annotation as a qualifier
@Retention(AnnotationRetention.RUNTIME)
annotation class PerActivity
@Scope
@Retention(RetentionPolicy.RUNTIME)
annotation class PerChildFragment
@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class PerFragment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment