...
 
Commits (251)
......@@ -8,8 +8,7 @@ local.properties
# Idea
.idea/
!.idea/codeStyles
**/*.iml
# Mac OS
.DS_Store
\ No newline at end of file
.DS_Store
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<AndroidXmlCodeStyleSettings>
<option name="USE_CUSTOM_SETTINGS" value="true" />
</AndroidXmlCodeStyleSettings>
<JetCodeStyleSettings>
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings>
<Objective-C-extensions>
<file>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
</file>
<class>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
</class>
<extensions>
<pair source="cpp" header="h" fileNamingConvention="NONE" />
<pair source="c" header="h" fileNamingConvention="NONE" />
</extensions>
</Objective-C-extensions>
<XML>
<option name="XML_KEEP_LINE_BREAKS" value="false" />
<option name="XML_ALIGN_ATTRIBUTES" value="false" />
<option name="XML_SPACE_INSIDE_EMPTY_TAG" value="true" />
</XML>
<codeStyleSettings language="XML">
<option name="FORCE_REARRANGE_MODE" value="1" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
<codeStyleSettings language="kotlin">
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
</codeStyleSettings>
</code_scheme>
</component>
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>
\ No newline at end of file
plugins {
id("com.android.application")
id("io.fabric")
id("org.jetbrains.kotlin.android.extensions")
kotlin("android")
kotlin("kapt")
id("org.jetbrains.kotlin.android.extensions")
}
val buildUid = System.getenv("BUILD_COMMIT_SHA") ?: "local"
......@@ -16,8 +16,8 @@ android {
minSdkVersion(19)
targetSdkVersion(28)
versionName = "1.3.2"
versionCode = 11
versionName = "1.5.5"
versionCode = 20
buildToolsVersion = "28.0.3"
......@@ -49,14 +49,6 @@ android {
buildConfigField("String", "OAUTH_CALLBACK", "\"app://gitlab.client/\"")
multiDexEnabled = true
javaCompileOptions {
annotationProcessorOptions {
arguments = mapOf(
"toothpick_registry_package_name" to "ru.terrakok.gitlabclient"
)
}
}
}
signingConfigs {
......@@ -71,13 +63,13 @@ android {
buildTypes {
create("debugPG") {
isDebuggable = true
initWith(getByName("debug"))
isMinifyEnabled = true
versionNameSuffix = " debugPG"
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
file("config/proguard/proguard-rules.txt")
file("proguard-rules.pro")
)
}
getByName("release") {
......@@ -86,7 +78,7 @@ android {
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
file("config/proguard/proguard-rules.txt")
file("proguard-rules.pro")
)
}
}
......@@ -94,27 +86,27 @@ android {
}
dependencies {
val supportLibraryVersion = "28.0.0"
val moxyVersion = "1.4.6"
val toothpickVersion = "1.0.6"
val moxyVersion = "1.7.0"
val toothpickVersion = "2.1.0"
val retrofitVersion = "2.2.0"
val markwonVersion = "1.1.1"
val markwonVersion = "2.0.0"
val glideVersion = "4.8.0"
//Support
implementation("com.android.support:appcompat-v7:$supportLibraryVersion")
implementation("com.android.support:design:$supportLibraryVersion")
implementation("com.android.support:cardview-v7:$supportLibraryVersion")
implementation("com.android.support.constraint:constraint-layout:1.1.3")
implementation("androidx.appcompat:appcompat:1.0.2")
implementation("com.google.android.material:material:1.1.0-alpha07")
implementation("androidx.cardview:cardview:1.0.0")
implementation("androidx.constraintlayout:constraintlayout:1.1.3")
//Kotlin
implementation("org.jetbrains.kotlin:kotlin-stdlib:${extra["kotlinVersion"] as String}")
//Log
implementation("com.jakewharton.timber:timber:4.7.0")
//MVP Moxy
kapt("com.arello-mobile:moxy-compiler:$moxyVersion")
implementation("com.arello-mobile:moxy-app-compat:$moxyVersion")
kapt("tech.schoolhelper:moxy-x-compiler:$moxyVersion")
implementation("tech.schoolhelper:moxy-x:$moxyVersion")
implementation("tech.schoolhelper:moxy-x-androidx:$moxyVersion")
//Cicerone Navigation
implementation("ru.terrakok.cicerone:cicerone:4.0.2")
implementation("ru.terrakok.cicerone:cicerone:5.0.0")
//DI
implementation("com.github.stephanenicolas.toothpick:toothpick-runtime:$toothpickVersion")
kapt("com.github.stephanenicolas.toothpick:toothpick-compiler:$toothpickVersion")
......@@ -126,39 +118,37 @@ dependencies {
implementation("com.squareup.okhttp3:logging-interceptor:3.11.0")
implementation("com.squareup.retrofit2:adapter-rxjava2:$retrofitVersion")
//RxJava
implementation("io.reactivex.rxjava2:rxandroid:2.1.0")
implementation("io.reactivex.rxjava2:rxjava:2.2.3")
implementation("io.reactivex.rxjava2:rxandroid:2.1.1")
implementation("io.reactivex.rxjava2:rxjava:2.2.6")
implementation("com.jakewharton.rxrelay2:rxrelay:2.1.0")
//Adapter simplify
implementation("com.hannesdorfmann:adapterdelegates3:3.1.0")
implementation("com.hannesdorfmann:adapterdelegates4:4.0.0")
//Image load and cache
implementation("com.github.bumptech.glide:glide:$glideVersion")
kapt("com.github.bumptech.glide:compiler:$glideVersion")
implementation("com.github.bumptech.glide:okhttp3-integration:4.6.1") {
exclude(group = "glide-parent")
}
implementation("com.github.bumptech.glide:okhttp3-integration:$glideVersion")
//Markdown to HTML converter
implementation("ru.noties:markwon:$markwonVersion")
implementation("ru.noties:markwon-image-loader:$markwonVersion")
//Bottom navigation bar
implementation("com.aurelhubert:ahbottomnavigation:2.1.0")
implementation("com.aurelhubert:ahbottomnavigation:2.3.4")
//Lottie
implementation("com.airbnb.android:lottie:2.5.1")
//Date
implementation("com.jakewharton.threetenabp:threetenabp:1.0.5")
implementation("com.jakewharton.threetenabp:threetenabp:1.2.1")
//FlexBox Layout
implementation("com.google.android:flexbox:1.0.0")
//Firebase
implementation("com.google.firebase:firebase-core:16.0.5")
implementation("com.google.firebase:firebase-core:16.0.9")
//Crashlytics
implementation("com.crashlytics.sdk.android:crashlytics:2.9.6")
implementation("com.crashlytics.sdk.android:crashlytics:2.10.1")
//JUnit
testImplementation("junit:junit:4.12")
//Mockito
testImplementation("org.mockito:mockito-core:2.8.9")
testImplementation("org.mockito:mockito-core:2.27.0")
//Mockito Kotlin
testImplementation("com.nhaarman:mockito-kotlin-kt1.1:1.5.0")
testImplementation("com.nhaarman.mockitokotlin2:mockito-kotlin:2.1.0")
}
configurations.all {
......
{
"project_info": {
"project_number": "0",
"firebase_url": "debug",
"project_id": "gitfox-gitlab-client",
"storage_bucket": "debug"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:0:android:0",
"android_client_info": {
"package_name": "com.gitlab.terrakok.gitfox"
}
},
"oauth_client": [
{
"client_id": "debug",
"client_type": 3
}
],
"api_key": [
{
"current_key": "debug"
},
{
"current_key": "debug"
}
],
"services": {
"analytics_service": {
"status": 1
},
"appinvite_service": {
"status": 1,
"other_platform_oauth_client": []
},
"ads_service": {
"status": 2
}
}
}
],
"configuration_version": "1"
}
\ No newline at end of file
......@@ -16,6 +16,7 @@
<activity
android:name=".ui.AppActivity"
android:launchMode="singleInstance"
android:theme="@style/AppTheme.Splash"
android:windowSoftInputMode="adjustResize">
<intent-filter>
......
Copyright (c) 2006, Ivan Sagalaev
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of highlight.js nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This diff is collapsed.
!function(e){"use strict";function t(){"complete"===document.readyState?n():e.addEventListener("DOMContentLoaded",n)}function n(){try{var e=document.querySelectorAll("code.hljs");for(var t in e)e.hasOwnProperty(t)&&r(e[t])}catch(n){console.error("LineNumbers error: ",n)}}function r(e){if("object"==typeof e){var t=e.parentNode,n=o(t.textContent);if(n>1){for(var r="",c=0;n>c;c++)r+=c+1+"\n";var l=document.createElement("code");l.className="hljs hljs-line-numbers",l.style["float"]="left",l.textContent=r,t.insertBefore(l,e)}}}function o(e){if(0===e.length)return 0;var t=/\r\n|\r|\n/g,n=e.match(t);return n=n?n.length:0,e[e.length-1].match(t)||(n+=1),n}"undefined"==typeof e.hljs?console.error("highlight.js not detected!"):(e.hljs.initLineNumbersOnLoad=t,e.hljs.lineNumbersBlock=r)}(window);
\ No newline at end of file
/*
Darcula color scheme from the JetBrains family of IDEs
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #2b2b2b;
}
.hljs {
color: #bababa;
}
.hljs-strong,
.hljs-emphasis {
color: #a8a8a2;
}
.hljs-bullet,
.hljs-quote,
.hljs-link,
.hljs-number,
.hljs-regexp,
.hljs-literal {
color: #6896ba;
}
.hljs-code,
.hljs-selector-class {
color: #a6e22e;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-section,
.hljs-attribute,
.hljs-name,
.hljs-variable {
color: #cb7832;
}
.hljs-params {
color: #b9b9b9;
}
.hljs-string {
color: #6a8759;
}
.hljs-subst,
.hljs-type,
.hljs-built_in,
.hljs-builtin-name,
.hljs-symbol,
.hljs-selector-id,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-template-tag,
.hljs-template-variable,
.hljs-addition {
color: #e0c46c;
}
.hljs-comment,
.hljs-deletion,
.hljs-meta {
color: #7f7f7f;
}
/*
Original highlight.js style (c) Ivan Sagalaev <maniac@softwaremaniacs.org>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #F0F0F0;
}
/* Base color: saturation 0; */
.hljs,
.hljs-subst {
color: #444;
}
.hljs-comment {
color: #888888;
}
.hljs-keyword,
.hljs-attribute,
.hljs-selector-tag,
.hljs-meta-keyword,
.hljs-doctag,
.hljs-name {
font-weight: bold;
}
/* User color: hue: 0 */
.hljs-type,
.hljs-string,
.hljs-number,
.hljs-selector-id,
.hljs-selector-class,
.hljs-quote,
.hljs-template-tag,
.hljs-deletion {
color: #880000;
}
.hljs-title,
.hljs-section {
color: #880000;
font-weight: bold;
}
.hljs-regexp,
.hljs-symbol,
.hljs-variable,
.hljs-template-variable,
.hljs-link,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #BC6060;
}
/* Language color: hue: 90; */
.hljs-literal {
color: #78A960;
}
.hljs-built_in,
.hljs-bullet,
.hljs-code,
.hljs-addition {
color: #397300;
}
/* Meta color: hue: 200 */
.hljs-meta {
color: #1f7199;
}
.hljs-meta-string {
color: #4d99bf;
}
/* Misc effects */
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}
package ru.terrakok.gitlabclient
import android.app.Application
import android.content.Context
import android.graphics.Color
import android.os.Build
import androidx.multidex.MultiDex
import com.crashlytics.android.Crashlytics
import com.jakewharton.threetenabp.AndroidThreeTen
import io.fabric.sdk.android.Fabric
import ru.noties.markwon.SpannableConfiguration
import ru.noties.markwon.spans.SpannableTheme
import ru.terrakok.gitlabclient.model.data.auth.AuthHolder
import ru.terrakok.gitlabclient.toothpick.DI
import ru.terrakok.gitlabclient.toothpick.module.AppModule
import ru.terrakok.gitlabclient.toothpick.module.ServerModule
import ru.terrakok.gitlabclient.di.DI
import ru.terrakok.gitlabclient.di.module.AppModule
import timber.log.Timber
import toothpick.Toothpick
import toothpick.configuration.Configuration
import toothpick.registries.FactoryRegistryLocator
import toothpick.registries.MemberInjectorRegistryLocator
import java.util.*
/**
* @author Konstantin Tskhovrebov (aka terrakok) on 26.03.17.
*/
class App : Application() {
override fun attachBaseContext(base: Context?) {
super.attachBaseContext(base)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
MultiDex.install(this)
}
}
override fun onCreate() {
super.onCreate()
appCode = UUID.randomUUID().toString()
initLogger()
initFabric()
......@@ -55,20 +60,13 @@ class App : Application() {
if (BuildConfig.DEBUG) {
Toothpick.setConfiguration(Configuration.forDevelopment().preventMultipleRootScopes())
} else {
Toothpick.setConfiguration(Configuration.forProduction().disableReflection())
FactoryRegistryLocator.setRootRegistry(ru.terrakok.gitlabclient.FactoryRegistry())
MemberInjectorRegistryLocator.setRootRegistry(ru.terrakok.gitlabclient.MemberInjectorRegistry())
Toothpick.setConfiguration(Configuration.forProduction())
}
}
private fun initAppScope() {
val appScope = Toothpick.openScope(DI.APP_SCOPE)
appScope.installModules(AppModule(this))
//By default we need init ServerScope for launch app
val authHolder = appScope.getInstance(AuthHolder::class.java)
val serverScope = Toothpick.openScopes(DI.APP_SCOPE, DI.SERVER_SCOPE)
serverScope.installModules(ServerModule(authHolder.serverPath))
Toothpick.openScope(DI.APP_SCOPE)
.installModules(AppModule(this))
}
private fun initMarkwon() {
......@@ -84,9 +82,4 @@ class App : Application() {
private fun initThreetenABP() {
AndroidThreeTen.init(this)
}
companion object {
lateinit var appCode: String
private set
}
}
\ No newline at end of file
package ru.terrakok.gitlabclient.toothpick
package ru.terrakok.gitlabclient.di
/**
* @author Konstantin Tskhovrebov (aka terrakok) on 09.07.17.
......@@ -7,12 +7,4 @@ object DI {
//single scopes
const val APP_SCOPE = "app scope"
const val SERVER_SCOPE = "server scope"
const val DRAWER_FLOW_SCOPE = "drawer flow scope"
const val AUTH_FLOW_SCOPE = "auth flow scope"
//multi scopes
const val USER_FLOW_SCOPE = "user flow scope: "
const val PROJECT_FLOW_SCOPE = "project flow scope: "
const val MERGE_REQUEST_FLOW_SCOPE = "merge request flow scope: "
const val ISSUE_FLOW_SCOPE = "issue flow scope: "
}
\ No newline at end of file
package ru.terrakok.gitlabclient.toothpick
package ru.terrakok.gitlabclient.di
/**
* @author Konstantin Tskhovrebov (aka terrakok) on 09.07.17.
......
package ru.terrakok.gitlabclient.toothpick.module
package ru.terrakok.gitlabclient.di.module
import android.content.Context
import android.content.res.AssetManager
import com.google.gson.Gson
import ru.terrakok.cicerone.Cicerone
import ru.terrakok.cicerone.NavigatorHolder
import ru.terrakok.cicerone.Router
import ru.terrakok.gitlabclient.BuildConfig
import ru.terrakok.gitlabclient.R
import ru.terrakok.gitlabclient.di.*
import ru.terrakok.gitlabclient.di.provider.GsonProvider
import ru.terrakok.gitlabclient.entity.app.develop.AppInfo
import ru.terrakok.gitlabclient.model.data.auth.AuthHolder
import ru.terrakok.gitlabclient.model.data.storage.Prefs
import ru.terrakok.gitlabclient.model.data.storage.RawAppData
import ru.terrakok.gitlabclient.model.interactor.app.AppInfoInteractor
import ru.terrakok.gitlabclient.model.repository.app.AppInfoRepository
import ru.terrakok.gitlabclient.model.repository.session.SessionRepository
import ru.terrakok.gitlabclient.model.repository.tools.Base64Tools
import ru.terrakok.gitlabclient.model.system.AppSchedulers
import ru.terrakok.gitlabclient.model.system.ResourceManager
import ru.terrakok.gitlabclient.model.system.SchedulersProvider
import ru.terrakok.gitlabclient.model.system.message.SystemMessageNotifier
import ru.terrakok.gitlabclient.toothpick.PrimitiveWrapper
import ru.terrakok.gitlabclient.toothpick.qualifier.*
import toothpick.config.Module
/**
......@@ -37,16 +33,16 @@ class AppModule(context: Context) : Module() {
bind(ResourceManager::class.java).singletonInScope()
bind(Base64Tools::class.java).toInstance(Base64Tools())
bind(AssetManager::class.java).toInstance(context.assets)
bind(RawAppData::class.java)
bind(SystemMessageNotifier::class.java).toInstance(SystemMessageNotifier())
bind(Gson::class.java).toProvider(GsonProvider::class.java).providesSingletonInScope()
//Navigation
val cicerone = Cicerone.create()
bind(Router::class.java).toInstance(cicerone.router)
bind(NavigatorHolder::class.java).toInstance(cicerone.navigatorHolder)
//Auth
bind(AuthHolder::class.java).to(Prefs::class.java).singletonInScope()
//Session
bind(SessionRepository::class.java).singletonInScope()
//AppInfo
bind(AppInfo::class.java).toInstance(
......@@ -59,7 +55,5 @@ class AppModule(context: Context) : Module() {
BuildConfig.FEEDBACK_URL
)
)
bind(AppInfoRepository::class.java)
bind(AppInfoInteractor::class.java)
}
}
\ No newline at end of file
package ru.terrakok.gitlabclient.toothpick.module
package ru.terrakok.gitlabclient.di.module
import ru.terrakok.cicerone.Cicerone
import ru.terrakok.cicerone.NavigatorHolder
......
package ru.terrakok.gitlabclient.toothpick.module
package ru.terrakok.gitlabclient.di.module
import ru.terrakok.gitlabclient.presentation.global.GlobalMenuController
import toothpick.config.Module
......
package ru.terrakok.gitlabclient.di.module
import okhttp3.OkHttpClient
import ru.terrakok.gitlabclient.BuildConfig
import ru.terrakok.gitlabclient.di.ServerPath
import ru.terrakok.gitlabclient.di.WithErrorHandler
import ru.terrakok.gitlabclient.di.provider.ApiProvider
import ru.terrakok.gitlabclient.di.provider.MarkDownConverterProvider
import ru.terrakok.gitlabclient.di.provider.OkHttpClientProvider
import ru.terrakok.gitlabclient.di.provider.OkHttpClientWithErrorHandlerProvider
import ru.terrakok.gitlabclient.entity.app.session.AuthHolder
import ru.terrakok.gitlabclient.entity.app.session.OAuthParams
import ru.terrakok.gitlabclient.entity.app.session.UserAccount
import ru.terrakok.gitlabclient.model.data.cache.ProjectCache
import ru.terrakok.gitlabclient.model.data.server.GitlabApi
import ru.terrakok.gitlabclient.model.data.state.AccountMainBadgesStateModel
import ru.terrakok.gitlabclient.presentation.global.ErrorHandler
import ru.terrakok.gitlabclient.presentation.global.MarkDownConverter
import toothpick.config.Module
/**
* @author Konstantin Tskhovrebov (aka terrakok) on 20.06.17.
*/
class ServerModule(userAccount: UserAccount?) : Module() {
init {
if (userAccount != null) {
bind(AuthHolder::class.java).toInstance(AuthHolder(userAccount.token, userAccount.isOAuth))
bind(String::class.java).withName(ServerPath::class.java).toInstance(userAccount.serverPath)
} else {
//for authorization screen
bind(AuthHolder::class.java).toInstance(AuthHolder(null, true))
bind(String::class.java).withName(ServerPath::class.java).toInstance(BuildConfig.ORIGIN_GITLAB_ENDPOINT)
}
//Network
bind(OkHttpClient::class.java).toProvider(OkHttpClientProvider::class.java).providesSingletonInScope()
bind(OkHttpClient::class.java).withName(WithErrorHandler::class.java)
.toProvider(OkHttpClientWithErrorHandlerProvider::class.java)
.providesSingletonInScope()
bind(ProjectCache::class.java).singletonInScope()
bind(GitlabApi::class.java).toProvider(ApiProvider::class.java).providesSingletonInScope()
bind(MarkDownConverter::class.java).toProvider(MarkDownConverterProvider::class.java).providesSingletonInScope()
//Auth
bind(OAuthParams::class.java).toInstance(
OAuthParams(
BuildConfig.OAUTH_APP_ID,
BuildConfig.OAUTH_SECRET,
BuildConfig.OAUTH_CALLBACK
)
)
//Error handler with logout logic
bind(ErrorHandler::class.java).singletonInScope()
//Account badges
bind(AccountMainBadgesStateModel::class.java).toInstance(AccountMainBadgesStateModel())
}
}
\ No newline at end of file
package ru.terrakok.gitlabclient.toothpick.provider
package ru.terrakok.gitlabclient.di.provider
import com.google.gson.Gson
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import ru.terrakok.gitlabclient.di.ServerPath
import ru.terrakok.gitlabclient.di.WithErrorHandler
import ru.terrakok.gitlabclient.model.data.cache.ProjectCache
import ru.terrakok.gitlabclient.model.data.server.ApiWithCache
import ru.terrakok.gitlabclient.model.data.server.GitlabApi
import ru.terrakok.gitlabclient.toothpick.qualifier.ServerPath
import ru.terrakok.gitlabclient.toothpick.qualifier.WithErrorHandler
import javax.inject.Inject
import javax.inject.Provider
......
package ru.terrakok.gitlabclient.toothpick.provider
package ru.terrakok.gitlabclient.di.provider
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import org.threeten.bp.LocalDateTime
import org.threeten.bp.LocalDate
import org.threeten.bp.ZonedDateTime
import ru.terrakok.gitlabclient.entity.Color
import ru.terrakok.gitlabclient.entity.todo.Todo
import ru.terrakok.gitlabclient.model.data.server.deserializer.DateDeserializer
import ru.terrakok.gitlabclient.model.data.server.deserializer.ColorDeserializer
import ru.terrakok.gitlabclient.model.data.server.deserializer.LocalDateDeserializer
import ru.terrakok.gitlabclient.model.data.server.deserializer.TodoDeserializer
import ru.terrakok.gitlabclient.model.data.server.deserializer.ZonedDateTimeDeserializer
import javax.inject.Inject
import javax.inject.Provider
......@@ -16,7 +20,9 @@ class GsonProvider @Inject constructor() : Provider<Gson> {
override fun get(): Gson =
GsonBuilder()
.registerTypeAdapter(LocalDateTime::class.java, DateDeserializer())
.registerTypeAdapter(Todo::class.java, TodoDeserializer())
.registerTypeAdapter(Color::class.java, ColorDeserializer())
.registerTypeAdapter(LocalDate::class.java, LocalDateDeserializer())
.registerTypeAdapter(ZonedDateTime::class.java, ZonedDateTimeDeserializer())
.create()
}
\ No newline at end of file
package ru.terrakok.gitlabclient.toothpick.provider
package ru.terrakok.gitlabclient.di.provider
import android.content.Context
import android.graphics.Rect
import okhttp3.OkHttpClient
import ru.noties.markwon.SpannableConfiguration
import ru.noties.markwon.UrlProcessorRelativeToAbsolute
import ru.noties.markwon.il.AsyncDrawableLoader
import ru.noties.markwon.renderer.ImageSize
import ru.noties.markwon.renderer.ImageSizeResolver
import ru.noties.markwon.spans.SpannableTheme
import ru.terrakok.gitlabclient.R
import ru.terrakok.gitlabclient.di.DefaultServerPath
import ru.terrakok.gitlabclient.extension.color
import ru.terrakok.gitlabclient.model.system.SchedulersProvider
import ru.terrakok.gitlabclient.presentation.global.MarkDownConverter
import ru.terrakok.gitlabclient.toothpick.qualifier.DefaultServerPath
import java.util.concurrent.Executors
import javax.inject.Inject
import javax.inject.Provider
......@@ -43,39 +40,11 @@ class MarkDownConverterProvider @Inject constructor(
private val urlProcessor = UrlProcessorRelativeToAbsolute(defaultServerPath)
private val imageSizeResolver = object : ImageSizeResolver() {
override fun resolveImageSize(
imageSize: ImageSize?,
imageBounds: Rect,
canvasWidth: Int,
textSize: Float
): Rect {
// This implementation was taken from SNAPSHOT @2.0,0.
// Post process bounds to fit canvasWidth (previously was inside AsyncDrawable)
// must be applied only if imageSize is null.
val rect: Rect
val w = imageBounds.width()
rect = if (w > canvasWidth) {
val reduceRatio = w.toFloat() / canvasWidth
Rect(
0,
0,
canvasWidth,
(imageBounds.height() / reduceRatio + .5f).toInt()
)
} else {
imageBounds
}
return rect
}
}
private val spannableConfig
get() = SpannableConfiguration.builder(context)
.asyncDrawableLoader(asyncDrawableLoader)
.urlProcessor(urlProcessor)
.theme(spannableTheme)
.imageSizeResolver(imageSizeResolver)
.build()
override fun get() = MarkDownConverter(
......
package ru.terrakok.gitlabclient.toothpick.provider
package ru.terrakok.gitlabclient.di.provider
import android.content.Context
import okhttp3.Cache
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import ru.terrakok.gitlabclient.BuildConfig
import ru.terrakok.gitlabclient.model.data.auth.AuthHolder
import ru.terrakok.gitlabclient.entity.app.session.AuthHolder
import ru.terrakok.gitlabclient.model.data.server.Tls12SocketFactory.Companion.enableTls12
import ru.terrakok.gitlabclient.model.data.server.interceptor.AuthHeaderInterceptor
import ru.terrakok.gitlabclient.model.data.server.interceptor.CurlLoggingInterceptor
import ru.terrakok.gitlabclient.model.data.server.interceptor.ErrorResponseInterceptor
import java.util.concurrent.TimeUnit
import javax.inject.Inject
import javax.inject.Provider
......@@ -22,6 +22,7 @@ class OkHttpClientProvider @Inject constructor(
) : Provider<OkHttpClient> {
override fun get() = with(OkHttpClient.Builder()) {
enableTls12()
cache(Cache(context.cacheDir, CACHE_SIZE_BYTES))
connectTimeout(TIMEOUT, TimeUnit.SECONDS)
readTimeout(TIMEOUT, TimeUnit.SECONDS)
......
package ru.terrakok.gitlabclient.toothpick.provider
package ru.terrakok.gitlabclient.di.provider
import okhttp3.OkHttpClient
import ru.terrakok.gitlabclient.model.data.server.interceptor.ErrorResponseInterceptor
......
package ru.terrakok.gitlabclient.toothpick.qualifier
package ru.terrakok.gitlabclient.di
import javax.inject.Qualifier
......@@ -40,4 +40,10 @@ annotation class UserId
annotation class CacheLifetime
@Qualifier
annotation class WithErrorHandler
\ No newline at end of file
annotation class WithErrorHandler
@Qualifier
annotation class FilePath
@Qualifier
annotation class FileReference
\ No newline at end of file
package ru.terrakok.gitlabclient.entity
import com.google.gson.annotations.SerializedName
data class Branch(
@SerializedName("name") val name: String,
@SerializedName("merged") val merged: Boolean,
@SerializedName("protected") val protected: Boolean,
@SerializedName("default") val default: Boolean,
@SerializedName("developers_can_push") val developersCanPush: Boolean,
@SerializedName("developers_can_merge") val developersCanMerge: Boolean,
@SerializedName("can_push") val canPush: Boolean
)
\ No newline at end of file
package ru.terrakok.gitlabclient.entity
/**
* Created by Eugene Shapovalov (@CraggyHaggy) on 04.01.19.
*/
data class Color(
val name: String,
val value: Int
)
\ No newline at end of file
package ru.terrakok.gitlabclient.entity
import com.google.gson.annotations.SerializedName
import org.threeten.bp.LocalDateTime
import org.threeten.bp.ZonedDateTime
/**
* Created by Eugene Shapovalov (@CraggyHaggy) on 20.10.18.
......@@ -12,11 +12,11 @@ data class Commit(
@SerializedName("title") val title: String,
@SerializedName("author_name") val authorName: String,
@SerializedName("author_email") val authorEmail: String?,
@SerializedName("authored_date") val authoredDate: LocalDateTime,
@SerializedName("authored_date") val authoredDate: ZonedDateTime,
@SerializedName("commiter_name") val commiterName: String?,
@SerializedName("commiter_email") val commiterEmail: String?,
@SerializedName("commited_date") val commitedDate: LocalDateTime?,
@SerializedName("created_at") val createdAt: LocalDateTime,
@SerializedName("commited_date") val commitedDate: ZonedDateTime?,
@SerializedName("created_at") val createdAt: ZonedDateTime,
@SerializedName("message") val message: String,
@SerializedName("parent_ids") val parentIds: List<String>
)
\ No newline at end of file
package ru.terrakok.gitlabclient.entity
import com.google.gson.annotations.SerializedName
/**
* @author Maxim Myalkin (MaxMyalkin) on 29.10.2018.
*/
data class Label(
@SerializedName("id") val id: Long,
@SerializedName("name") val name: String,
@SerializedName("color") val color: Color,
@SerializedName("description") val description: String?,
@SerializedName("open_issues_count") val openIssuesCount: Int,
@SerializedName("closed_issues_count") val closedIssuesCount: Int,
@SerializedName("open_merge_requests_count") val openMergeRequestsCount: Int,
@SerializedName("subscribed") val subscribed: Boolean,
@SerializedName("priority") val priority: Int?
)
\ No newline at end of file
......@@ -2,11 +2,13 @@ package ru.terrakok.gitlabclient.entity
import com.google.gson.annotations.SerializedName
data class Author(
data class Member(
@SerializedName("id") val id: Long,
@SerializedName("state") val state: String?,
@SerializedName("web_url") val webUrl: String?,
@SerializedName("username") val username: String,
@SerializedName("name") val name: String,
@SerializedName("state") val state: String?,
@SerializedName("avatar_url") val avatarUrl: String?,
@SerializedName("username") val username: String
)
@SerializedName("web_url") val webUrl: String?,
@SerializedName("expires_at") val expiresDate: String?,
@SerializedName("access_level") val accessLevel: Long
)
\ No newline at end of file
package ru.terrakok.gitlabclient.entity
import com.google.gson.annotations.SerializedName
import org.threeten.bp.LocalDateTime
import org.threeten.bp.ZonedDateTime
import ru.terrakok.gitlabclient.entity.event.EventTargetType
data class Note(
@SerializedName("id") val id: Long,
@SerializedName("body") val body: String,
@SerializedName("author") val author: Author,
@SerializedName("created_at") val createdAt: LocalDateTime,
@SerializedName("updated_at") val updatedAt: LocalDateTime?,
@SerializedName("author") val author: ShortUser,
@SerializedName("created_at") val createdAt: ZonedDateTime,
@SerializedName("updated_at") val updatedAt: ZonedDateTime?,
@SerializedName("system") val isSystem: Boolean,
@SerializedName("noteable_id") val noteableId: Long,
@SerializedName("noteable_type") val noteableType: EventTargetType?,
......
package ru.terrakok.gitlabclient.entity
import com.google.gson.annotations.SerializedName
import org.threeten.bp.LocalDateTime
import org.threeten.bp.ZonedDateTime
data class Owner(
@SerializedName("id") val id: Long,
@SerializedName("name") val name: String,
@SerializedName("username") val username: String,
@SerializedName("created_at") val createdAt: LocalDateTime?
@SerializedName("created_at") val createdAt: ZonedDateTime?
)