mirror of
https://github.com/gedoor/legado.git
synced 2024-09-01 09:34:25 +08:00
commit
e9c0aac7af
@ -3,7 +3,6 @@ apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-parcelize'
|
||||
apply plugin: 'kotlin-kapt'
|
||||
apply plugin: 'de.timfreiheit.resourceplaceholders'
|
||||
apply plugin: 'com.google.firebase.crashlytics'
|
||||
|
||||
static def releaseTime() {
|
||||
return new Date().format("yy.MMddHH", TimeZone.getTimeZone("GMT+8"))
|
||||
@ -121,10 +120,6 @@ dependencies {
|
||||
//kotlin
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||
|
||||
//fireBase
|
||||
implementation 'com.google.firebase:firebase-analytics-ktx:18.0.0'
|
||||
implementation 'com.google.firebase:firebase-crashlytics-ktx:17.3.0'
|
||||
|
||||
//androidX
|
||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||
implementation 'androidx.core:core-ktx:1.3.2'
|
||||
@ -212,6 +207,4 @@ dependencies {
|
||||
//转换繁体
|
||||
implementation 'com.github.liuyueyi.quick-chinese-transfer:quick-transfer-core:0.1.3'
|
||||
|
||||
}
|
||||
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
}
|
@ -3,6 +3,14 @@
|
||||
* 关注合作公众号 **[小说拾遗]** 获取好看的小说。
|
||||
* 旧版数据导入教程:先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】。
|
||||
|
||||
**2021/04/16**
|
||||
* 去掉google统计,解决华为手机使用崩溃的bug
|
||||
* 添加规则订阅时判断重复提醒
|
||||
|
||||
**2021/04/13**
|
||||
* 修复导入布局bug
|
||||
* 修复订阅切换布局bug
|
||||
|
||||
**2021/04/08**
|
||||
* 缓存时重新检查并缓存图片
|
||||
* 订阅源调试添加源码查看
|
||||
|
@ -152,7 +152,7 @@ function rule2json() {
|
||||
RuleJSON.lastUpdateTime = new Date().getTime();
|
||||
RuleJSON.customOrder = RuleJSON.customOrder == '' ? 0 : parseInt(RuleJSON.customOrder);
|
||||
RuleJSON.weight = RuleJSON.weight == '' ? 0 : parseInt(RuleJSON.weight);
|
||||
RuleJSON.bookSourceType == RuleJSON.bookSourceType == '' ? 0 : parseInt(RuleJSON.weight);
|
||||
RuleJSON.bookSourceType == RuleJSON.bookSourceType == '' ? 0 : parseInt(RuleJSON.bookSourceType);
|
||||
RuleJSON.enabled = RuleJSON.enabled == '' || String(RuleJSON.enabled).toLocaleLowerCase().replace(/^\s*|\s*$/g, '') == 'true';
|
||||
RuleJSON.enabledExplore = RuleJSON.enabledExplore == '' || String(RuleJSON.enabledExplore).toLocaleLowerCase().replace(/^\s*|\s*$/g, '') == 'true';
|
||||
return RuleJSON;
|
||||
|
@ -22,8 +22,8 @@ val appDb by lazy {
|
||||
ReplaceRule::class, SearchBook::class, SearchKeyword::class, Cookie::class,
|
||||
RssSource::class, Bookmark::class, RssArticle::class, RssReadRecord::class,
|
||||
RssStar::class, TxtTocRule::class, ReadRecord::class, HttpTTS::class, Cache::class,
|
||||
RuleSub::class, EpubChapter::class],
|
||||
version = 31,
|
||||
RuleSub::class],
|
||||
version = 32,
|
||||
exportSchema = true
|
||||
)
|
||||
abstract class AppDatabase : RoomDatabase() {
|
||||
@ -45,7 +45,6 @@ abstract class AppDatabase : RoomDatabase() {
|
||||
abstract val httpTTSDao: HttpTTSDao
|
||||
abstract val cacheDao: CacheDao
|
||||
abstract val ruleSubDao: RuleSubDao
|
||||
abstract val epubChapterDao: EpubChapterDao
|
||||
|
||||
companion object {
|
||||
|
||||
@ -59,7 +58,8 @@ abstract class AppDatabase : RoomDatabase() {
|
||||
migration_14_15, migration_15_17, migration_17_18, migration_18_19,
|
||||
migration_19_20, migration_20_21, migration_21_22, migration_22_23,
|
||||
migration_23_24, migration_24_25, migration_25_26, migration_26_27,
|
||||
migration_27_28, migration_28_29, migration_29_30, migration_30_31
|
||||
migration_27_28, migration_28_29, migration_29_30, migration_30_31,
|
||||
migration_31_32
|
||||
)
|
||||
.allowMainThreadQueries()
|
||||
.addCallback(dbCallback)
|
||||
@ -290,6 +290,12 @@ abstract class AppDatabase : RoomDatabase() {
|
||||
database.execSQL("insert into readRecord (deviceId, bookName, readTime) select androidId, bookName, readTime from readRecord1")
|
||||
}
|
||||
}
|
||||
|
||||
private val migration_31_32 = object : Migration(31, 32) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("DROP TABLE `epubChapters`")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package io.legado.app.data.dao
|
||||
|
||||
import androidx.room.*
|
||||
import io.legado.app.data.entities.EpubChapter
|
||||
|
||||
@Dao
|
||||
interface EpubChapterDao {
|
||||
@get:Query("select * from epubChapters")
|
||||
val all: List<EpubChapter>
|
||||
|
||||
@Query("select count(*) from epubChapters Where bookUrl = :bookUrl")
|
||||
fun getCnt(bookUrl: String): Int
|
||||
|
||||
@Query("select * from epubChapters Where bookUrl = :bookUrl and parentHref = :parentHref ")
|
||||
fun get(bookUrl: String, parentHref: String): List<EpubChapter>
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insert(vararg chapter: EpubChapter)
|
||||
|
||||
@Query("delete from epubChapters")
|
||||
fun clear()
|
||||
|
||||
@Query("delete from epubChapters Where bookUrl = :bookUrl")
|
||||
fun deleteByName(bookUrl: String)
|
||||
|
||||
@Delete
|
||||
fun delete(vararg chapter: EpubChapter)
|
||||
|
||||
@Update
|
||||
fun update(vararg chapter: EpubChapter)
|
||||
|
||||
}
|
@ -16,6 +16,9 @@ interface RuleSubDao {
|
||||
@get:Query("select customOrder from ruleSubs order by customOrder limit 0,1")
|
||||
val maxOrder: Int
|
||||
|
||||
@Query("select * from ruleSubs where url = :url")
|
||||
fun findByUrl(url: String): RuleSub?
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insert(vararg ruleSub: RuleSub)
|
||||
|
||||
|
@ -1,23 +0,0 @@
|
||||
package io.legado.app.data.entities
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.Index
|
||||
|
||||
@Entity(
|
||||
tableName = "epubChapters",
|
||||
primaryKeys = ["bookUrl", "href"],
|
||||
indices = [(Index(value = ["bookUrl"], unique = false)),
|
||||
(Index(value = ["bookUrl", "href"], unique = true))],
|
||||
foreignKeys = [(ForeignKey(
|
||||
entity = Book::class,
|
||||
parentColumns = ["bookUrl"],
|
||||
childColumns = ["bookUrl"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
))]
|
||||
)
|
||||
data class EpubChapter(
|
||||
var bookUrl: String = "",
|
||||
var href: String = "",
|
||||
var parentHref: String? = null,
|
||||
)
|
@ -14,7 +14,7 @@
|
||||
* book\download 下载界面
|
||||
* book\explore 发现界面
|
||||
* book\local 书籍导入界面
|
||||
* fileChooser 文件选择界面
|
||||
* document 文件选择界面
|
||||
* config 配置界面
|
||||
* main 主界面
|
||||
* qrCode 二维码扫描界面
|
||||
|
@ -148,11 +148,9 @@ class BgTextConfigDialog : BaseDialogFragment() {
|
||||
cancelButton()
|
||||
}.show()
|
||||
}
|
||||
binding.swDarkStatusIcon.setOnCheckedChangeListener { buttonView, isChecked ->
|
||||
if (buttonView?.isPressed == true) {
|
||||
setCurStatusIconDark(isChecked)
|
||||
(activity as? ReadBookActivity)?.upSystemUiVisibility()
|
||||
}
|
||||
binding.swDarkStatusIcon.setOnCheckedChangeListener { _, isChecked ->
|
||||
setCurStatusIconDark(isChecked)
|
||||
(activity as? ReadBookActivity)?.upSystemUiVisibility()
|
||||
}
|
||||
binding.tvTextColor.setOnClickListener {
|
||||
ColorPickerDialog.newBuilder()
|
||||
|
@ -121,17 +121,13 @@ class PaddingConfigDialog : BaseDialogFragment() {
|
||||
footerPaddingRight = it
|
||||
postEvent(EventBus.UP_CONFIG, true)
|
||||
}
|
||||
binding.cbShowTopLine.onCheckedChangeListener = { cb, isChecked ->
|
||||
if (cb.isPressed) {
|
||||
showHeaderLine = isChecked
|
||||
postEvent(EventBus.UP_CONFIG, true)
|
||||
}
|
||||
binding.cbShowTopLine.onCheckedChangeListener = { _, isChecked ->
|
||||
showHeaderLine = isChecked
|
||||
postEvent(EventBus.UP_CONFIG, true)
|
||||
}
|
||||
binding.cbShowBottomLine.onCheckedChangeListener = { cb, isChecked ->
|
||||
if (cb.isPressed) {
|
||||
showFooterLine = isChecked
|
||||
postEvent(EventBus.UP_CONFIG, true)
|
||||
}
|
||||
binding.cbShowBottomLine.onCheckedChangeListener = { _, isChecked ->
|
||||
showFooterLine = isChecked
|
||||
postEvent(EventBus.UP_CONFIG, true)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,6 @@ class ReadAloudDialog : BaseDialogFragment() {
|
||||
tvSetting.setTextColor(textColor)
|
||||
cbTtsFollowSys.setTextColor(textColor)
|
||||
}
|
||||
initOnChange()
|
||||
initData()
|
||||
initEvent()
|
||||
}
|
||||
@ -95,32 +94,6 @@ class ReadAloudDialog : BaseDialogFragment() {
|
||||
seekTtsSpeechRate.progress = AppConfig.ttsSpeechRate
|
||||
}
|
||||
|
||||
private fun initOnChange() = with(binding) {
|
||||
cbTtsFollowSys.setOnCheckedChangeListener { buttonView, isChecked ->
|
||||
if (buttonView.isPressed) {
|
||||
requireContext().putPrefBoolean("ttsFollowSys", isChecked)
|
||||
seekTtsSpeechRate.isEnabled = !isChecked
|
||||
upTtsSpeechRate()
|
||||
}
|
||||
}
|
||||
seekTtsSpeechRate.setOnSeekBarChangeListener(object : SeekBarChangeListener {
|
||||
|
||||
override fun onStopTrackingTouch(seekBar: SeekBar) {
|
||||
AppConfig.ttsSpeechRate = seekBar.progress
|
||||
upTtsSpeechRate()
|
||||
}
|
||||
})
|
||||
seekTimer.setOnSeekBarChangeListener(object : SeekBarChangeListener {
|
||||
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
|
||||
upTimerText(progress)
|
||||
}
|
||||
|
||||
override fun onStopTrackingTouch(seekBar: SeekBar) {
|
||||
ReadAloud.setTimer(requireContext(), seekTimer.progress)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun initEvent() = with(binding) {
|
||||
llMainMenu.setOnClickListener {
|
||||
callBack?.showMenuBar()
|
||||
@ -140,6 +113,27 @@ class ReadAloudDialog : BaseDialogFragment() {
|
||||
ivPlayNext.setOnClickListener { ReadAloud.nextParagraph(requireContext()) }
|
||||
llCatalog.setOnClickListener { callBack?.openChapterList() }
|
||||
llToBackstage.setOnClickListener { callBack?.finish() }
|
||||
cbTtsFollowSys.setOnCheckedChangeListener { _, isChecked ->
|
||||
requireContext().putPrefBoolean("ttsFollowSys", isChecked)
|
||||
seekTtsSpeechRate.isEnabled = !isChecked
|
||||
upTtsSpeechRate()
|
||||
}
|
||||
seekTtsSpeechRate.setOnSeekBarChangeListener(object : SeekBarChangeListener {
|
||||
|
||||
override fun onStopTrackingTouch(seekBar: SeekBar) {
|
||||
AppConfig.ttsSpeechRate = seekBar.progress
|
||||
upTtsSpeechRate()
|
||||
}
|
||||
})
|
||||
seekTimer.setOnSeekBarChangeListener(object : SeekBarChangeListener {
|
||||
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
|
||||
upTimerText(progress)
|
||||
}
|
||||
|
||||
override fun onStopTrackingTouch(seekBar: SeekBar) {
|
||||
ReadAloud.setTimer(requireContext(), seekTimer.progress)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun upPlayState() {
|
||||
|
@ -136,12 +136,10 @@ class ReadStyleDialog : BaseDialogFragment(), FontSelectDialog.CallBack {
|
||||
ReadBookConfig.pageAnim = binding.rgPageAnim.getIndexById(checkedId)
|
||||
callBack?.upPageAnim()
|
||||
}
|
||||
cbShareLayout.onCheckedChangeListener = { checkBox, isChecked ->
|
||||
if (checkBox.isPressed) {
|
||||
ReadBookConfig.shareLayout = isChecked
|
||||
upView()
|
||||
postEvent(EventBus.UP_CONFIG, true)
|
||||
}
|
||||
cbShareLayout.onCheckedChangeListener = { _, isChecked ->
|
||||
ReadBookConfig.shareLayout = isChecked
|
||||
upView()
|
||||
postEvent(EventBus.UP_CONFIG, true)
|
||||
}
|
||||
dsbTextSize.onChanged = {
|
||||
ReadBookConfig.textSize = it + 5
|
||||
|
@ -6,6 +6,7 @@ import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View.GONE
|
||||
import android.view.View.VISIBLE
|
||||
import android.widget.TextView
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.lifecycle.LiveData
|
||||
@ -214,7 +215,8 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
|
||||
intent?.getStringExtra("key")?.let {
|
||||
searchView.setQuery(it, true)
|
||||
} ?: let {
|
||||
searchView.requestFocus()
|
||||
searchView.findViewById<TextView>(androidx.appcompat.R.id.search_src_text)
|
||||
.requestFocus()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,42 +85,6 @@ class ThemeConfigFragment : BasePreferenceFragment(),
|
||||
}
|
||||
}
|
||||
}
|
||||
findPreference<ColorPreference>(PreferKey.cAccent)?.let {
|
||||
it.onSaveColor = { color ->
|
||||
val background =
|
||||
getPrefInt(PreferKey.cBackground, getCompatColor(R.color.md_grey_100))
|
||||
val textColor = getCompatColor(R.color.primaryText)
|
||||
when {
|
||||
ColorUtils.getColorDifference(color, background) <= 60 -> {
|
||||
toastOnUi(R.string.accent_background_diff)
|
||||
true
|
||||
}
|
||||
ColorUtils.getColorDifference(color, textColor) <= 60 -> {
|
||||
toastOnUi(R.string.accent_text_diff)
|
||||
true
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
}
|
||||
findPreference<ColorPreference>(PreferKey.cNAccent)?.let {
|
||||
it.onSaveColor = { color ->
|
||||
val background =
|
||||
getPrefInt(PreferKey.cNBackground, getCompatColor(R.color.md_grey_900))
|
||||
val textColor = getCompatColor(R.color.primaryText)
|
||||
when {
|
||||
ColorUtils.getColorDifference(color, background) <= 60 -> {
|
||||
toastOnUi(R.string.accent_background_diff)
|
||||
true
|
||||
}
|
||||
ColorUtils.getColorDifference(color, textColor) <= 60 -> {
|
||||
toastOnUi(R.string.accent_text_diff)
|
||||
true
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
|
@ -123,7 +123,7 @@ class FilePickerActivity :
|
||||
"txt", "xml" -> types.add("text/*")
|
||||
else -> {
|
||||
val mime = MimeTypeMap.getSingleton()
|
||||
.getMimeTypeFromExtension("json")
|
||||
.getMimeTypeFromExtension(it)
|
||||
?: "application/octet-stream"
|
||||
types.add(mime)
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ class RssSortActivity : VMBaseActivity<ActivityRssArtivlesBinding, RssSortViewMo
|
||||
|
||||
override val viewModel: RssSortViewModel
|
||||
by viewModels()
|
||||
private val fragments = linkedMapOf<String, RssArticlesFragment>()
|
||||
private var sorts = linkedMapOf<String, String>()
|
||||
private lateinit var adapter: TabFragmentPageAdapter
|
||||
private val upSourceResult = registerForActivityResult(
|
||||
ActivityResultContracts.StartActivityForResult()
|
||||
@ -40,7 +40,7 @@ class RssSortActivity : VMBaseActivity<ActivityRssArtivlesBinding, RssSortViewMo
|
||||
adapter = TabFragmentPageAdapter()
|
||||
binding.viewPager.adapter = adapter
|
||||
TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position ->
|
||||
tab.text = fragments.keys.elementAt(position)
|
||||
tab.text = sorts.keys.elementAt(position)
|
||||
}.attach()
|
||||
viewModel.titleLiveData.observe(this, {
|
||||
binding.titleBar.title = it
|
||||
@ -77,11 +77,10 @@ class RssSortActivity : VMBaseActivity<ActivityRssArtivlesBinding, RssSortViewMo
|
||||
}
|
||||
|
||||
private fun upFragments() {
|
||||
fragments.clear()
|
||||
viewModel.rssSource?.sortUrls()?.forEach {
|
||||
fragments[it.key] = RssArticlesFragment.create(it.key, it.value)
|
||||
viewModel.rssSource?.sortUrls()?.let {
|
||||
sorts = it
|
||||
}
|
||||
if (fragments.size == 1) {
|
||||
if (sorts.size == 1) {
|
||||
binding.tabLayout.gone()
|
||||
} else {
|
||||
binding.tabLayout.visible()
|
||||
@ -92,11 +91,19 @@ class RssSortActivity : VMBaseActivity<ActivityRssArtivlesBinding, RssSortViewMo
|
||||
private inner class TabFragmentPageAdapter : FragmentStateAdapter(this) {
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return fragments.size
|
||||
return sorts.size
|
||||
}
|
||||
|
||||
override fun getItemId(position: Int): Long {
|
||||
val style = viewModel.rssSource?.articleStyle ?: 0
|
||||
return style * 100 + super.getItemId(position)
|
||||
}
|
||||
|
||||
override fun createFragment(position: Int): Fragment {
|
||||
return fragments.values.elementAt(position)
|
||||
return RssArticlesFragment.create(
|
||||
sorts.keys.elementAt(position),
|
||||
sorts.values.elementAt(position)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,8 +18,10 @@ import io.legado.app.ui.association.ImportReplaceRuleActivity
|
||||
import io.legado.app.ui.association.ImportRssSourceActivity
|
||||
import io.legado.app.ui.widget.recycler.ItemTouchCallback
|
||||
import io.legado.app.utils.startActivity
|
||||
import io.legado.app.utils.toastOnUi
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
/**
|
||||
* 规则订阅界面
|
||||
@ -100,11 +102,20 @@ class RuleSubActivity : BaseActivity<ActivityRuleSubBinding>(),
|
||||
}
|
||||
customView { alertBinding.root }
|
||||
okButton {
|
||||
ruleSub.type = alertBinding.spType.selectedItemPosition
|
||||
ruleSub.name = alertBinding.etName.text?.toString() ?: ""
|
||||
ruleSub.url = alertBinding.etUrl.text?.toString() ?: ""
|
||||
launch(IO) {
|
||||
appDb.ruleSubDao.insert(ruleSub)
|
||||
launch {
|
||||
ruleSub.type = alertBinding.spType.selectedItemPosition
|
||||
ruleSub.name = alertBinding.etName.text?.toString() ?: ""
|
||||
ruleSub.url = alertBinding.etUrl.text?.toString() ?: ""
|
||||
val rs = withContext(IO) {
|
||||
appDb.ruleSubDao.findByUrl(ruleSub.url)
|
||||
}
|
||||
if (rs != null && rs.id != ruleSub.id) {
|
||||
toastOnUi("${getString(R.string.url_already)}(${rs.name})")
|
||||
return@launch
|
||||
}
|
||||
withContext(IO) {
|
||||
appDb.ruleSubDao.insert(ruleSub)
|
||||
}
|
||||
}
|
||||
}
|
||||
cancelButton()
|
||||
|
@ -97,6 +97,7 @@
|
||||
android:layout_margin="16dp"
|
||||
android:src="@drawable/ic_stop_black_24dp"
|
||||
android:visibility="invisible"
|
||||
android:contentDescription="@string/stop"
|
||||
app:fabSize="mini"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent" />
|
||||
|
@ -819,5 +819,6 @@
|
||||
<string name="toc_src">目录源码</string>
|
||||
<string name="content_src">正文源码</string>
|
||||
<string name="list_src">列表源码</string>
|
||||
<string name="url_already">此url已订阅</string>
|
||||
|
||||
</resources>
|
||||
|
@ -821,5 +821,6 @@
|
||||
<string name="toc_src">目录源码</string>
|
||||
<string name="content_src">正文源码</string>
|
||||
<string name="list_src">列表源码</string>
|
||||
<string name="url_already">此url已订阅</string>
|
||||
|
||||
</resources>
|
||||
|
@ -823,5 +823,6 @@
|
||||
<string name="toc_src">目录源码</string>
|
||||
<string name="content_src">正文源码</string>
|
||||
<string name="list_src">列表源码</string>
|
||||
<string name="url_already">此url已订阅</string>
|
||||
|
||||
</resources>
|
||||
|
@ -826,5 +826,6 @@
|
||||
<string name="toc_src">目录源码</string>
|
||||
<string name="content_src">正文源码</string>
|
||||
<string name="list_src">列表源码</string>
|
||||
<string name="url_already">此url已订阅</string>
|
||||
|
||||
</resources>
|
||||
|
@ -13,8 +13,6 @@ buildscript {
|
||||
classpath 'com.android.tools.build:gradle:4.1.3'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath "de.timfreiheit.resourceplaceholders:placeholders:0.3"
|
||||
classpath "com.google.gms:google-services:4.3.4"
|
||||
classpath "com.google.firebase:firebase-crashlytics-gradle:2.4.1"
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user