Migrate from Glide to Coil
This commit is contained in:
parent
401a493864
commit
0447d3072d
@ -101,8 +101,8 @@ dependencies {
|
|||||||
implementation(libs.androidx.work)
|
implementation(libs.androidx.work)
|
||||||
implementation(libs.androidx.multidex)
|
implementation(libs.androidx.multidex)
|
||||||
|
|
||||||
implementation(libs.glide)
|
implementation(libs.coil.core)
|
||||||
implementation(libs.glidetransformations)
|
implementation(libs.coil.svg)
|
||||||
|
|
||||||
implementation(libs.lottie.core)
|
implementation(libs.lottie.core)
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,9 @@ package de.mm20.launcher2
|
|||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
|
import coil.ImageLoader
|
||||||
|
import coil.ImageLoaderFactory
|
||||||
|
import coil.decode.SvgDecoder
|
||||||
import de.mm20.launcher2.accounts.accountsModule
|
import de.mm20.launcher2.accounts.accountsModule
|
||||||
import de.mm20.launcher2.applications.applicationsModule
|
import de.mm20.launcher2.applications.applicationsModule
|
||||||
import de.mm20.launcher2.badges.badgesModule
|
import de.mm20.launcher2.badges.badgesModule
|
||||||
@ -34,7 +37,7 @@ import org.koin.core.logger.Level
|
|||||||
import java.text.Collator
|
import java.text.Collator
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
class LauncherApplication : Application(), CoroutineScope {
|
class LauncherApplication : Application(), CoroutineScope, ImageLoaderFactory {
|
||||||
|
|
||||||
override val coroutineContext: CoroutineContext
|
override val coroutineContext: CoroutineContext
|
||||||
get() = Dispatchers.Main + SupervisorJob()
|
get() = Dispatchers.Main + SupervisorJob()
|
||||||
@ -85,6 +88,16 @@ class LauncherApplication : Application(), CoroutineScope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun newImageLoader(): ImageLoader {
|
||||||
|
return ImageLoader.Builder(applicationContext)
|
||||||
|
.componentRegistry {
|
||||||
|
add(SvgDecoder(applicationContext))
|
||||||
|
}
|
||||||
|
.crossfade(true)
|
||||||
|
.crossfade(200)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
val collator: Collator by lazy {
|
val collator: Collator by lazy {
|
||||||
|
|||||||
@ -77,13 +77,6 @@ val OpenSourceLicenses = arrayOf(
|
|||||||
copyrightNote = "Copyright (c) 2009-2021 Jonathan Hedley <https://jsoup.org/>",
|
copyrightNote = "Copyright (c) 2009-2021 Jonathan Hedley <https://jsoup.org/>",
|
||||||
url = "https://jsoup.org/"
|
url = "https://jsoup.org/"
|
||||||
),
|
),
|
||||||
OpenSourceLibrary(
|
|
||||||
name = "Glide",
|
|
||||||
description = "A fast and efficient open source media management and image loading framework for Android",
|
|
||||||
licenseName = R.string.glide_license_name,
|
|
||||||
licenseText = R.raw.license_glide,
|
|
||||||
url = "https://bumptech.github.io/glide/"
|
|
||||||
),
|
|
||||||
OpenSourceLibrary(
|
OpenSourceLibrary(
|
||||||
name = "Glide Transformations",
|
name = "Glide Transformations",
|
||||||
description = "An Android transformation library providing a variety of image transformations for Glide",
|
description = "An Android transformation library providing a variety of image transformations for Glide",
|
||||||
|
|||||||
@ -1,94 +0,0 @@
|
|||||||
License for everything not in third_party and not otherwise marked:
|
|
||||||
|
|
||||||
Copyright 2014 Google, Inc. All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification, are
|
|
||||||
permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
conditions and the following disclaimer.
|
|
||||||
|
|
||||||
2. 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.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY GOOGLE, INC. ``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 GOOGLE, INC. OR
|
|
||||||
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.
|
|
||||||
|
|
||||||
The views and conclusions contained in the software and documentation are those of the
|
|
||||||
authors and should not be interpreted as representing official policies, either expressed
|
|
||||||
or implied, of Google, Inc.
|
|
||||||
---------------------------------------------------------------------------------------------
|
|
||||||
License for third_party/disklrucache:
|
|
||||||
|
|
||||||
Copyright 2012 Jake Wharton
|
|
||||||
Copyright 2011 The Android Open Source Project
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
---------------------------------------------------------------------------------------------
|
|
||||||
License for third_party/gif_decoder:
|
|
||||||
|
|
||||||
Copyright (c) 2013 Xcellent Creations, Inc.
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
a copy of this software and associated documentation files (the
|
|
||||||
"Software"), to deal in the Software without restriction, including
|
|
||||||
without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be
|
|
||||||
included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
---------------------------------------------------------------------------------------------
|
|
||||||
License for third_party/gif_encoder/AnimatedGifEncoder.java and
|
|
||||||
third_party/gif_encoder/LZWEncoder.java:
|
|
||||||
|
|
||||||
No copyright asserted on the source code of this class. May be used for any
|
|
||||||
purpose, however, refer to the Unisys LZW patent for restrictions on use of
|
|
||||||
the associated LZWEncoder class. Please forward any corrections to
|
|
||||||
kweiner@fmsware.com.
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
License for third_party/gif_encoder/NeuQuant.java
|
|
||||||
|
|
||||||
Copyright (c) 1994 Anthony Dekker
|
|
||||||
|
|
||||||
NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994. See
|
|
||||||
"Kohonen neural networks for optimal colour quantization" in "Network:
|
|
||||||
Computation in Neural Systems" Vol. 5 (1994) pp 351-367. for a discussion of
|
|
||||||
the algorithm.
|
|
||||||
|
|
||||||
Any party obtaining a copy of these files from the author, directly or
|
|
||||||
indirectly, is granted, free of charge, a full and unrestricted irrevocable,
|
|
||||||
world-wide, paid up, royalty-free, nonexclusive right and license to deal in
|
|
||||||
this software and documentation files (the "Software"), including without
|
|
||||||
limitation the rights to use, copy, modify, merge, publish, distribute,
|
|
||||||
sublicense, and/or sell copies of the Software, and to permit persons who
|
|
||||||
receive copies from any such party to do so, with the only requirement being
|
|
||||||
that this copyright notice remain intact.
|
|
||||||
@ -4,7 +4,6 @@
|
|||||||
<string name="bsd_2clause_name" translatable="false">Simplified BSD license</string>
|
<string name="bsd_2clause_name" translatable="false">Simplified BSD license</string>
|
||||||
<string name="bsd_3clause_name" translatable="false">Modified BSD license</string>
|
<string name="bsd_3clause_name" translatable="false">Modified BSD license</string>
|
||||||
<string name="apache_license_name" translatable="false">Apache license 2.0</string>
|
<string name="apache_license_name" translatable="false">Apache license 2.0</string>
|
||||||
<string name="glide_license_name" translatable="false">Glide license</string>
|
|
||||||
<string name="gpl3_name" translatable="false">GNU General Public License Version 3</string>
|
<string name="gpl3_name" translatable="false">GNU General Public License Version 3</string>
|
||||||
<string name="open_font_license_name" translatable="false">SIL OPEN FONT LICENSE</string>
|
<string name="open_font_license_name" translatable="false">SIL OPEN FONT LICENSE</string>
|
||||||
</resources>
|
</resources>
|
||||||
@ -289,6 +289,9 @@ dependencyResolutionManagement {
|
|||||||
alias("coil.core")
|
alias("coil.core")
|
||||||
.to("io.coil-kt", "coil")
|
.to("io.coil-kt", "coil")
|
||||||
.versionRef("coil")
|
.versionRef("coil")
|
||||||
|
alias("coil.svg")
|
||||||
|
.to("io.coil-kt", "coil-svg")
|
||||||
|
.versionRef("coil")
|
||||||
alias("coil.compose")
|
alias("coil.compose")
|
||||||
.to("io.coil-kt", "coil-compose")
|
.to("io.coil-kt", "coil-compose")
|
||||||
.versionRef("coil")
|
.versionRef("coil")
|
||||||
@ -309,14 +312,6 @@ dependencyResolutionManagement {
|
|||||||
.to("org.jsoup", "jsoup")
|
.to("org.jsoup", "jsoup")
|
||||||
.version("1.14.2")
|
.version("1.14.2")
|
||||||
|
|
||||||
alias("glide")
|
|
||||||
.to("com.github.bumptech.glide", "glide")
|
|
||||||
.version("4.12.0")
|
|
||||||
|
|
||||||
alias("glidetransformations")
|
|
||||||
.to("jp.wasabeef", "glide-transformations")
|
|
||||||
.version("4.3.0")
|
|
||||||
|
|
||||||
version("materialdialogs", "3.3.0")
|
version("materialdialogs", "3.3.0")
|
||||||
alias("materialdialogs.core")
|
alias("materialdialogs.core")
|
||||||
.to("com.afollestad.material-dialogs", "core")
|
.to("com.afollestad.material-dialogs", "core")
|
||||||
|
|||||||
@ -74,10 +74,8 @@ dependencies {
|
|||||||
implementation(libs.materialcomponents.composethemeadapter3)
|
implementation(libs.materialcomponents.composethemeadapter3)
|
||||||
|
|
||||||
implementation(libs.viewpropertyobjectanimator)
|
implementation(libs.viewpropertyobjectanimator)
|
||||||
implementation(libs.glide)
|
|
||||||
implementation(libs.draglinearlayout)
|
implementation(libs.draglinearlayout)
|
||||||
implementation(libs.lottie.core)
|
implementation(libs.lottie.core)
|
||||||
implementation(libs.glidetransformations)
|
|
||||||
|
|
||||||
implementation(libs.accompanist.insets)
|
implementation(libs.accompanist.insets)
|
||||||
implementation(libs.accompanist.systemuicontroller)
|
implementation(libs.accompanist.systemuicontroller)
|
||||||
|
|||||||
@ -12,16 +12,19 @@ import androidx.appcompat.app.AppCompatActivity
|
|||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import com.bumptech.glide.Glide
|
import coil.imageLoader
|
||||||
import com.bumptech.glide.request.target.SimpleTarget
|
import coil.request.ImageRequest
|
||||||
import com.bumptech.glide.request.transition.Transition
|
import coil.size.Scale
|
||||||
import com.google.android.material.chip.Chip
|
import com.google.android.material.chip.Chip
|
||||||
import de.mm20.launcher2.ktx.dp
|
import de.mm20.launcher2.ktx.dp
|
||||||
|
import de.mm20.launcher2.ktx.lifecycleScope
|
||||||
import de.mm20.launcher2.legacy.helper.ActivityStarter
|
import de.mm20.launcher2.legacy.helper.ActivityStarter
|
||||||
import de.mm20.launcher2.search.data.Websearch
|
import de.mm20.launcher2.search.data.Websearch
|
||||||
import de.mm20.launcher2.ui.R
|
import de.mm20.launcher2.ui.R
|
||||||
import de.mm20.launcher2.ui.databinding.ViewWebsearchBinding
|
import de.mm20.launcher2.ui.databinding.ViewWebsearchBinding
|
||||||
import de.mm20.launcher2.ui.launcher.search.SearchViewModel
|
import de.mm20.launcher2.ui.launcher.search.SearchViewModel
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
class WebSearchView : FrameLayout {
|
class WebSearchView : FrameLayout {
|
||||||
constructor(context: Context) : super(context)
|
constructor(context: Context) : super(context)
|
||||||
@ -50,18 +53,19 @@ class WebSearchView : FrameLayout {
|
|||||||
for (search in websearches) {
|
for (search in websearches) {
|
||||||
val chip = Chip(context)
|
val chip = Chip(context)
|
||||||
chip.text = search.label
|
chip.text = search.label
|
||||||
if (search.icon != null) {
|
val icon = search.icon
|
||||||
Glide.with(context)
|
if (icon != null) {
|
||||||
.load(search.icon)
|
val imageRequest = ImageRequest.Builder(context)
|
||||||
.into(object : SimpleTarget<Drawable>() {
|
.data(File(icon))
|
||||||
override fun onResourceReady(
|
.size((32*dp).toInt())
|
||||||
resource: Drawable,
|
.scale(Scale.FIT)
|
||||||
transition: Transition<in Drawable>?
|
.target {
|
||||||
) {
|
chip.chipIcon = it
|
||||||
chip.chipIcon = resource
|
}
|
||||||
}
|
.build()
|
||||||
|
lifecycleScope.launch {
|
||||||
})
|
context.imageLoader.execute(imageRequest)
|
||||||
|
}
|
||||||
chip.chipIconTint = null
|
chip.chipIconTint = null
|
||||||
} else {
|
} else {
|
||||||
chip.chipIcon = ContextCompat.getDrawable(context, R.drawable.ic_search)
|
chip.chipIcon = ContextCompat.getDrawable(context, R.drawable.ic_search)
|
||||||
|
|||||||
@ -10,7 +10,8 @@ import androidx.appcompat.app.AppCompatActivity
|
|||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.repeatOnLifecycle
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import androidx.transition.Scene
|
import androidx.transition.Scene
|
||||||
import com.bumptech.glide.Glide
|
import coil.load
|
||||||
|
import coil.size.Scale
|
||||||
import de.mm20.launcher2.icons.IconRepository
|
import de.mm20.launcher2.icons.IconRepository
|
||||||
import de.mm20.launcher2.ktx.dp
|
import de.mm20.launcher2.ktx.dp
|
||||||
import de.mm20.launcher2.ktx.lifecycleOwner
|
import de.mm20.launcher2.ktx.lifecycleOwner
|
||||||
@ -61,7 +62,7 @@ class WebsiteDetailRepresentation : Representation, KoinComponent {
|
|||||||
website.image.isNotBlank() -> {
|
website.image.isNotBlank() -> {
|
||||||
websiteImage.visibility = View.VISIBLE
|
websiteImage.visibility = View.VISIBLE
|
||||||
websiteFavIcon.visibility = FrameLayout.GONE
|
websiteFavIcon.visibility = FrameLayout.GONE
|
||||||
Glide.with(context).load(website.image).into(websiteImage)
|
websiteImage.load(website.image)
|
||||||
websiteImage.transitionName = "icon"
|
websiteImage.transitionName = "icon"
|
||||||
label.transitionName = "label"
|
label.transitionName = "label"
|
||||||
websiteFavIcon.transitionName = null
|
websiteFavIcon.transitionName = null
|
||||||
|
|||||||
@ -10,12 +10,11 @@ import androidx.appcompat.app.AppCompatActivity
|
|||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.repeatOnLifecycle
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import androidx.transition.Scene
|
import androidx.transition.Scene
|
||||||
import com.bumptech.glide.Glide
|
import coil.load
|
||||||
import de.mm20.launcher2.badges.BadgeRepository
|
import de.mm20.launcher2.badges.BadgeRepository
|
||||||
import de.mm20.launcher2.icons.IconRepository
|
import de.mm20.launcher2.icons.IconRepository
|
||||||
import de.mm20.launcher2.ktx.dp
|
import de.mm20.launcher2.ktx.dp
|
||||||
import de.mm20.launcher2.ktx.lifecycleOwner
|
import de.mm20.launcher2.ktx.lifecycleOwner
|
||||||
import de.mm20.launcher2.ktx.lifecycleScope
|
|
||||||
import de.mm20.launcher2.legacy.helper.ActivityStarter
|
import de.mm20.launcher2.legacy.helper.ActivityStarter
|
||||||
import de.mm20.launcher2.search.data.Searchable
|
import de.mm20.launcher2.search.data.Searchable
|
||||||
import de.mm20.launcher2.search.data.Website
|
import de.mm20.launcher2.search.data.Website
|
||||||
@ -26,7 +25,6 @@ import de.mm20.launcher2.ui.legacy.view.LauncherIconView
|
|||||||
import de.mm20.launcher2.ui.legacy.view.ToolbarAction
|
import de.mm20.launcher2.ui.legacy.view.ToolbarAction
|
||||||
import de.mm20.launcher2.ui.legacy.view.ToolbarView
|
import de.mm20.launcher2.ui.legacy.view.ToolbarView
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.flow.collect
|
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.koin.core.component.KoinComponent
|
import org.koin.core.component.KoinComponent
|
||||||
@ -66,7 +64,8 @@ class WebsiteListRepresentation : Representation, KoinComponent {
|
|||||||
website.image.isNotBlank() -> {
|
website.image.isNotBlank() -> {
|
||||||
websiteImage.visibility = View.VISIBLE
|
websiteImage.visibility = View.VISIBLE
|
||||||
websiteFavIcon.visibility = FrameLayout.GONE
|
websiteFavIcon.visibility = FrameLayout.GONE
|
||||||
Glide.with(context).load(website.image).into(websiteImage)
|
websiteImage.load(website.image)
|
||||||
|
websiteImage.load(website.image)
|
||||||
websiteImage.transitionName = "icon"
|
websiteImage.transitionName = "icon"
|
||||||
label.transitionName = "label"
|
label.transitionName = "label"
|
||||||
websiteFavIcon.transitionName = null
|
websiteFavIcon.transitionName = null
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import android.widget.ImageView
|
|||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.core.text.HtmlCompat
|
import androidx.core.text.HtmlCompat
|
||||||
import androidx.transition.Scene
|
import androidx.transition.Scene
|
||||||
import com.bumptech.glide.Glide
|
import coil.load
|
||||||
import de.mm20.launcher2.search.data.Searchable
|
import de.mm20.launcher2.search.data.Searchable
|
||||||
import de.mm20.launcher2.search.data.Wikipedia
|
import de.mm20.launcher2.search.data.Wikipedia
|
||||||
import de.mm20.launcher2.ui.R
|
import de.mm20.launcher2.ui.R
|
||||||
@ -35,7 +35,7 @@ class WikipediaDetailRepresentation : Representation {
|
|||||||
it.scaleType = ImageView.ScaleType.CENTER_CROP
|
it.scaleType = ImageView.ScaleType.CENTER_CROP
|
||||||
}
|
}
|
||||||
it.visibility = View.VISIBLE
|
it.visibility = View.VISIBLE
|
||||||
Glide.with(context).load(wikipedia.image).into(it)
|
it.load(wikipedia.image)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val toolbar = findViewById<ToolbarView>(R.id.wikipediaToolbar)
|
val toolbar = findViewById<ToolbarView>(R.id.wikipediaToolbar)
|
||||||
|
|||||||
@ -7,7 +7,8 @@ import android.widget.ImageView
|
|||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.core.text.HtmlCompat
|
import androidx.core.text.HtmlCompat
|
||||||
import androidx.transition.Scene
|
import androidx.transition.Scene
|
||||||
import com.bumptech.glide.Glide
|
import coil.load
|
||||||
|
import coil.size.Scale
|
||||||
import de.mm20.launcher2.search.data.Searchable
|
import de.mm20.launcher2.search.data.Searchable
|
||||||
import de.mm20.launcher2.search.data.Wikipedia
|
import de.mm20.launcher2.search.data.Wikipedia
|
||||||
import de.mm20.launcher2.ui.R
|
import de.mm20.launcher2.ui.R
|
||||||
@ -17,13 +18,19 @@ import de.mm20.launcher2.ui.legacy.view.ToolbarAction
|
|||||||
import de.mm20.launcher2.ui.legacy.view.ToolbarView
|
import de.mm20.launcher2.ui.legacy.view.ToolbarView
|
||||||
|
|
||||||
class WikipediaListRepresentation : Representation {
|
class WikipediaListRepresentation : Representation {
|
||||||
override fun getScene(rootView: SearchableView, searchable: Searchable, previousRepresentation: Int?): Scene {
|
override fun getScene(
|
||||||
|
rootView: SearchableView,
|
||||||
|
searchable: Searchable,
|
||||||
|
previousRepresentation: Int?
|
||||||
|
): Scene {
|
||||||
val wikipedia = searchable as Wikipedia
|
val wikipedia = searchable as Wikipedia
|
||||||
val scene = Scene.getSceneForLayout(rootView, R.layout.view_wikipedia_list, rootView.context)
|
val scene =
|
||||||
|
Scene.getSceneForLayout(rootView, R.layout.view_wikipedia_list, rootView.context)
|
||||||
scene.setEnterAction {
|
scene.setEnterAction {
|
||||||
with(rootView) {
|
with(rootView) {
|
||||||
findViewById<TextView>(R.id.wikipediaTitle).text = wikipedia.label
|
findViewById<TextView>(R.id.wikipediaTitle).text = wikipedia.label
|
||||||
findViewById<TextView>(R.id.wikipediaText).text = HtmlCompat.fromHtml(wikipedia.text, HtmlCompat.FROM_HTML_MODE_LEGACY)
|
findViewById<TextView>(R.id.wikipediaText).text =
|
||||||
|
HtmlCompat.fromHtml(wikipedia.text, HtmlCompat.FROM_HTML_MODE_LEGACY)
|
||||||
findViewById<ImageView>(R.id.wikipediaImage).also {
|
findViewById<ImageView>(R.id.wikipediaImage).also {
|
||||||
if (wikipedia.image.isNullOrBlank()) {
|
if (wikipedia.image.isNullOrBlank()) {
|
||||||
it.visibility = View.GONE
|
it.visibility = View.GONE
|
||||||
@ -35,7 +42,7 @@ class WikipediaListRepresentation : Representation {
|
|||||||
it.scaleType = ImageView.ScaleType.CENTER_CROP
|
it.scaleType = ImageView.ScaleType.CENTER_CROP
|
||||||
}
|
}
|
||||||
it.visibility = View.VISIBLE
|
it.visibility = View.VISIBLE
|
||||||
Glide.with(context).load(wikipedia.image).into(it)
|
it.load(wikipedia.image)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val toolbar = findViewById<ToolbarView>(R.id.wikipediaToolbar)
|
val toolbar = findViewById<ToolbarView>(R.id.wikipediaToolbar)
|
||||||
@ -62,9 +69,11 @@ class WikipediaListRepresentation : Representation {
|
|||||||
private fun share(context: Context, wikipedia: Wikipedia) {
|
private fun share(context: Context, wikipedia: Wikipedia) {
|
||||||
val text = wikipedia.text.toString()
|
val text = wikipedia.text.toString()
|
||||||
val shareIntent = Intent(Intent.ACTION_SEND)
|
val shareIntent = Intent(Intent.ACTION_SEND)
|
||||||
shareIntent.putExtra(Intent.EXTRA_TEXT, "${wikipedia.label}\n\n" +
|
shareIntent.putExtra(
|
||||||
"${text.substring(0, 200)}…\n\n" +
|
Intent.EXTRA_TEXT, "${wikipedia.label}\n\n" +
|
||||||
"${context.getString(R.string.wikipedia_url)}/wiki?curid=${wikipedia.id}")
|
"${text.substring(0, 200)}…\n\n" +
|
||||||
|
"${context.getString(R.string.wikipedia_url)}/wiki?curid=${wikipedia.id}"
|
||||||
|
)
|
||||||
shareIntent.type = "text/plain"
|
shareIntent.type = "text/plain"
|
||||||
context.startActivity(Intent.createChooser(shareIntent, null))
|
context.startActivity(Intent.createChooser(shareIntent, null))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,10 +4,14 @@ import android.content.Context
|
|||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import androidx.core.graphics.drawable.toBitmap
|
||||||
import androidx.core.graphics.scale
|
import androidx.core.graphics.scale
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.asLiveData
|
import androidx.lifecycle.asLiveData
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import coil.imageLoader
|
||||||
|
import coil.request.ImageRequest
|
||||||
|
import coil.size.Scale
|
||||||
import de.mm20.launcher2.search.WebsearchRepository
|
import de.mm20.launcher2.search.WebsearchRepository
|
||||||
import de.mm20.launcher2.search.data.Websearch
|
import de.mm20.launcher2.search.data.Websearch
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@ -44,14 +48,13 @@ class WebSearchSettingsScreenVM: ViewModel(), KoinComponent {
|
|||||||
suspend fun createIcon(context: Context, uri: Uri, size: Int): String? = withContext(
|
suspend fun createIcon(context: Context, uri: Uri, size: Int): String? = withContext(
|
||||||
Dispatchers.IO) {
|
Dispatchers.IO) {
|
||||||
val file = File(context.dataDir, System.currentTimeMillis().toString())
|
val file = File(context.dataDir, System.currentTimeMillis().toString())
|
||||||
val stream = context.contentResolver.openInputStream(uri)
|
val imageRequest = ImageRequest.Builder(context)
|
||||||
val icon = BitmapFactory.decodeStream(stream) ?: return@withContext null
|
.data(uri)
|
||||||
val (scaledW, scaledH) = if (icon.width > icon.height) {
|
.size(size)
|
||||||
size * icon.width / icon.height to size
|
.scale(Scale.FIT)
|
||||||
} else {
|
.build()
|
||||||
size to size * icon.height / icon.width
|
val drawable = context.imageLoader.execute(imageRequest).drawable ?: return@withContext null
|
||||||
}
|
val scaledIcon = drawable.toBitmap()
|
||||||
val scaledIcon = icon.scale(scaledW, scaledH)
|
|
||||||
val out = FileOutputStream(file)
|
val out = FileOutputStream(file)
|
||||||
scaledIcon.compress(Bitmap.CompressFormat.PNG, 100, out)
|
scaledIcon.compress(Bitmap.CompressFormat.PNG, 100, out)
|
||||||
out.close()
|
out.close()
|
||||||
|
|||||||
@ -4,7 +4,6 @@
|
|||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:clipChildren="false"
|
|
||||||
android:transitionName="cardLayout">
|
android:transitionName="cardLayout">
|
||||||
|
|
||||||
<de.mm20.launcher2.ui.legacy.view.AspectRationImageView
|
<de.mm20.launcher2.ui.legacy.view.AspectRationImageView
|
||||||
|
|||||||
@ -6,7 +6,6 @@
|
|||||||
android:id="@+id/wikipediaRoot"
|
android:id="@+id/wikipediaRoot"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:clipChildren="false"
|
|
||||||
android:transitionName="cardLayout">
|
android:transitionName="cardLayout">
|
||||||
|
|
||||||
<de.mm20.launcher2.ui.legacy.view.AspectRationImageView
|
<de.mm20.launcher2.ui.legacy.view.AspectRationImageView
|
||||||
@ -14,7 +13,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@color/color_divider"
|
android:background="@color/color_divider"
|
||||||
android:scaleType="centerCrop"
|
android:scaleType="fitCenter"
|
||||||
app:aspectRatio="0.5625"
|
app:aspectRatio="0.5625"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
|||||||
@ -44,11 +44,12 @@ dependencies {
|
|||||||
implementation(libs.bundles.androidx.lifecycle)
|
implementation(libs.bundles.androidx.lifecycle)
|
||||||
|
|
||||||
implementation(libs.okhttp)
|
implementation(libs.okhttp)
|
||||||
implementation(libs.glide)
|
|
||||||
implementation(libs.jsoup)
|
implementation(libs.jsoup)
|
||||||
|
|
||||||
implementation(libs.koin.android)
|
implementation(libs.koin.android)
|
||||||
|
|
||||||
|
implementation(libs.coil.core)
|
||||||
|
|
||||||
implementation(project(":preferences"))
|
implementation(project(":preferences"))
|
||||||
implementation(project(":search"))
|
implementation(project(":search"))
|
||||||
implementation(project(":base"))
|
implementation(project(":base"))
|
||||||
|
|||||||
@ -8,7 +8,8 @@ import android.graphics.drawable.ColorDrawable
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import androidx.core.graphics.drawable.toBitmap
|
import androidx.core.graphics.drawable.toBitmap
|
||||||
import androidx.palette.graphics.Palette
|
import androidx.palette.graphics.Palette
|
||||||
import com.bumptech.glide.Glide
|
import coil.imageLoader
|
||||||
|
import coil.request.ImageRequest
|
||||||
import de.mm20.launcher2.graphics.TextDrawable
|
import de.mm20.launcher2.graphics.TextDrawable
|
||||||
import de.mm20.launcher2.icons.LauncherIcon
|
import de.mm20.launcher2.icons.LauncherIcon
|
||||||
import de.mm20.launcher2.ktx.sp
|
import de.mm20.launcher2.ktx.sp
|
||||||
@ -30,24 +31,24 @@ class Website(
|
|||||||
override suspend fun loadIcon(context: Context, size: Int): LauncherIcon? {
|
override suspend fun loadIcon(context: Context, size: Int): LauncherIcon? {
|
||||||
if (favicon.isEmpty()) return null
|
if (favicon.isEmpty()) return null
|
||||||
try {
|
try {
|
||||||
return withContext(Dispatchers.IO) {
|
val request = ImageRequest.Builder(context)
|
||||||
val icon = Glide.with(context)
|
.data(favicon)
|
||||||
.asDrawable()
|
.size(size)
|
||||||
.load(favicon)
|
.build()
|
||||||
.submit()
|
val icon = context.imageLoader.execute(request).drawable ?: return null
|
||||||
.get()
|
val color = if (color != 0) color else {
|
||||||
val color = if (color != 0) color else {
|
withContext(Dispatchers.Default) {
|
||||||
Palette
|
Palette
|
||||||
.from(icon.toBitmap())
|
.from(icon.toBitmap())
|
||||||
.generate()
|
.generate()
|
||||||
.getLightMutedColor(Color.WHITE)
|
.getLightMutedColor(Color.WHITE)
|
||||||
}
|
}
|
||||||
LauncherIcon(
|
|
||||||
foreground = icon,
|
|
||||||
background = ColorDrawable(color),
|
|
||||||
foregroundScale = 0.7f
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
return LauncherIcon(
|
||||||
|
foreground = icon,
|
||||||
|
background = ColorDrawable(color),
|
||||||
|
foregroundScale = 0.7f
|
||||||
|
)
|
||||||
} catch (e: ExecutionException) {
|
} catch (e: ExecutionException) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user