Skip to content

Commit 91e70af

Browse files
Merge pull request #675 from pennlabs/vkakar
Vkakar
2 parents 54f1a0f + f8af86c commit 91e70af

7 files changed

Lines changed: 179 additions & 308 deletions

File tree

PennMobile/build.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ dependencies {
7676
// If you want the foundation layout, use the bundle or the specific activity compose you have defined
7777
implementation libs.androidx.activity.compose
7878
implementation libs.androidx.material3.android
79+
implementation libs.androidx.compose.ui.tooling.preview
7980
// implementation libs.androidx.foundation.layout
8081

8182
ktlintRuleset libs.ktlint
@@ -137,6 +138,7 @@ dependencies {
137138
implementation libs.bundles.ui
138139
implementation libs.bundles.google
139140
implementation libs.bundles.hilt
141+
debugImplementation libs.androidx.compose.ui.tooling
140142

141143
ksp libs.androidx.room.compiler
142144
ksp libs.androidx.hilt.compiler
@@ -146,6 +148,8 @@ dependencies {
146148

147149
implementation libs.androidx.hilt.android
148150
ksp libs.androidx.hilt.compiler
151+
152+
implementation libs.coil.compose
149153
}
150154

151155
String getPlatformClientID() {

PennMobile/src/main/java/com/pennapps/labs/pennmobile/home/adapters/HomeAdapter.kt

Lines changed: 6 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import androidx.browser.customtabs.CustomTabsClient
1818
import androidx.browser.customtabs.CustomTabsIntent
1919
import androidx.browser.customtabs.CustomTabsServiceConnection
2020
import androidx.browser.customtabs.CustomTabsSession
21+
import androidx.compose.ui.platform.ComposeView
2122
import androidx.constraintlayout.widget.ConstraintLayout
2223
import androidx.core.content.ContextCompat.getColor
2324
import androidx.core.content.ContextCompat.startActivity
@@ -53,6 +54,7 @@ import com.pennapps.labs.pennmobile.home.classes.CalendarCell
5354
import com.pennapps.labs.pennmobile.home.classes.CalendarEvent
5455
import com.pennapps.labs.pennmobile.home.classes.HomepageDataModel
5556
import com.pennapps.labs.pennmobile.home.classes.NewsCell
57+
import com.pennapps.labs.pennmobile.home.classes.NewsComposableComponent
5658
import com.pennapps.labs.pennmobile.home.classes.Poll
5759
import com.pennapps.labs.pennmobile.home.classes.PollCell
5860
import com.pennapps.labs.pennmobile.home.classes.Post
@@ -583,149 +585,10 @@ class HomeAdapter(
583585
) {
584586
val article = cell.article
585587

586-
if (article.imageUrl.isNullOrEmpty()) {
587-
holder.itemView.visibility = View.GONE
588-
holder.newsCardContainer.visibility = View.GONE
589-
holder.homeNewsImageView.setImageDrawable(null)
590-
holder.homeNewsTitle.text = ""
591-
holder.homeNewsSubtitle.text = ""
592-
holder.homeNewsTimestamp.text = ""
593-
dataModel.notifyNewsBlurLoaded()
594-
return
595-
}
596-
597-
holder.homeNewsTitle.text = article.title
598-
holder.homeNewsSubtitle.text = article.subtitle
599-
600-
holder.homeNewsTimestamp.text = article.timestamp?.trim()
601-
602-
Glide
603-
.with(mContext)
604-
.load(article.imageUrl)
605-
.fitCenter()
606-
.centerCrop()
607-
.into(holder.homeNewsImageView)
608-
609-
// /** Adds dynamically generated accent color from the fetched image to the news card */
610-
var accentColor: Int = getColor(mContext, R.color.black)
611-
mActivity.lifecycleScope.launch(Dispatchers.Default) {
612-
Log.d("HomeAdapter", "Image Url is ${article.imageUrl}")
613-
val bitmap =
614-
withContext(Dispatchers.IO) {
615-
Glide
616-
.with(mContext)
617-
.load(article.imageUrl)
618-
.submit()
619-
.get()
620-
}.toBitmap()
621-
622-
// Create palette from bitmap
623-
fun createPaletteSync(bitmap: Bitmap): Palette = Palette.from(bitmap).generate()
624-
val vibrantSwatch: Palette.Swatch? = createPaletteSync(bitmap).darkVibrantSwatch
625-
vibrantSwatch?.rgb?.let { accentColor = it }
626-
627-
mActivity.runOnUiThread {
628-
// Change all the components to match the accent color palette
629-
vibrantSwatch?.titleTextColor?.let {
630-
DrawableCompat.setTint(
631-
DrawableCompat.wrap(holder.newsCardLogo.drawable),
632-
ColorUtils.setAlphaComponent(it, 150),
633-
)
634-
DrawableCompat.setTint(
635-
DrawableCompat.wrap(holder.newsInfoIcon.drawable),
636-
it,
637-
)
638-
DrawableCompat.setTint(
639-
DrawableCompat.wrap(holder.dotDivider.drawable),
640-
it,
641-
)
642-
holder.newsButton.setTextColor(ColorUtils.setAlphaComponent(it, 150))
643-
DrawableCompat.setTint(
644-
DrawableCompat.wrap(holder.newsButton.background),
645-
it,
646-
)
647-
holder.homeNewsTitle.setTextColor(
648-
ColorUtils.setAlphaComponent(
649-
it,
650-
150,
651-
),
652-
)
653-
holder.homeNewsSubtitle.setTextColor(it)
654-
holder.homeNewsTimestamp.setTextColor(it)
655-
}
656-
holder.newsCardContainer.background =
657-
BitmapDrawable(
658-
holder.itemBinding.root.resources,
659-
bitmap,
660-
)
661-
holder.newsBlurView
662-
.setOverlayColor(ColorUtils.setAlphaComponent(accentColor, 150))
663-
664-
// tell model that the news blur view has been loaded
665-
dataModel.notifyNewsBlurLoaded()
666-
}
667-
}
668-
669-
// Logic for the more info button on the news card
670-
holder.newsInfoIcon.setOnClickListener {
671-
when (holder.homeNewsSubtitle.visibility) {
672-
View.GONE -> {
673-
holder.homeNewsSubtitle.visibility = View.VISIBLE
674-
holder.homeNewsTitle.setPadding(0, 0, 0, 0)
675-
holder.newsBlurView
676-
.setOverlayColor(ColorUtils.setAlphaComponent(accentColor, 250))
677-
}
678-
679-
View.VISIBLE -> {
680-
holder.homeNewsSubtitle.visibility = View.GONE
681-
holder.homeNewsTitle.setPadding(0, 0, 0, convertToDp(mContext, 8f))
682-
holder.newsBlurView
683-
.setOverlayColor(ColorUtils.setAlphaComponent(accentColor, 150))
684-
}
685-
}
686-
}
687-
688-
// Sets up blur view on news card
689-
holder.newsBlurView
690-
.setupWith(holder.newsCardContainer, RenderScriptBlur(mContext))
691-
.setFrameClearDrawable(ColorDrawable(getColor(mContext, R.color.white)))
692-
.setBlurRadius(25f)
693-
694-
holder.newsButton.setOnClickListener {
695-
val url = article?.articleUrl
696-
697-
val connection = NewsCustomTabsServiceConnection()
698-
builder = CustomTabsIntent.Builder()
699-
share = Intent(Intent.ACTION_SEND)
700-
share?.type = "text/plain"
701-
builder?.setToolbarColor(0x3E50B4)
702-
builder?.setStartAnimations(
703-
mContext,
704-
androidx.appcompat.R.anim.abc_popup_enter,
705-
androidx.appcompat.R.anim.abc_popup_exit,
706-
)
707-
CustomTabsClient.bindCustomTabsService(
708-
mContext,
709-
NewsFragment.CUSTOM_TAB_PACKAGE_NAME,
710-
connection,
711-
)
712-
713-
if (mContext.isChromeCustomTabsSupported()) {
714-
share?.putExtra(Intent.EXTRA_TEXT, url)
715-
builder?.addMenuItem(
716-
"Share",
717-
PendingIntent.getActivity(
718-
mContext,
719-
0,
720-
share,
721-
PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE,
722-
),
723-
)
724-
customTabsIntent = builder?.build()
725-
customTabsIntent?.launchUrl(mActivity, Uri.parse(url))
726-
} else {
727-
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
728-
startActivity(mContext, browserIntent, null)
588+
val composeView = holder.itemView.findViewById<ComposeView>(R.id.news_compose_view)
589+
composeView.apply {
590+
setContent {
591+
NewsComposableComponent(article)
729592
}
730593
}
731594
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
package com.pennapps.labs.pennmobile.home.classes
2+
3+
import android.content.Context
4+
import androidx.compose.foundation.Image
5+
import androidx.compose.foundation.background
6+
import androidx.compose.foundation.clickable
7+
import androidx.compose.foundation.layout.Arrangement
8+
import androidx.compose.foundation.layout.Box
9+
import androidx.compose.foundation.layout.Column
10+
import androidx.compose.foundation.layout.Row
11+
import androidx.compose.foundation.layout.Spacer
12+
import androidx.compose.foundation.layout.aspectRatio
13+
import androidx.compose.foundation.layout.fillMaxHeight
14+
import androidx.compose.foundation.layout.fillMaxSize
15+
import androidx.compose.foundation.layout.fillMaxWidth
16+
import androidx.compose.foundation.layout.height
17+
import androidx.compose.foundation.layout.padding
18+
import androidx.compose.foundation.shape.RoundedCornerShape
19+
import androidx.compose.material3.Button
20+
import androidx.compose.material3.Text
21+
import androidx.compose.runtime.Composable
22+
import androidx.compose.ui.Alignment
23+
import androidx.compose.ui.Modifier
24+
import androidx.compose.ui.draw.blur
25+
import androidx.compose.ui.draw.clip
26+
import androidx.compose.ui.graphics.Color
27+
import androidx.compose.ui.layout.ContentScale
28+
import androidx.compose.ui.platform.LocalUriHandler
29+
import androidx.compose.ui.text.font.FontWeight
30+
import androidx.compose.ui.unit.dp
31+
import androidx.compose.ui.unit.em
32+
import androidx.compose.ui.unit.sp
33+
import coil.compose.rememberAsyncImagePainter
34+
35+
@Composable
36+
fun NewsComposableComponent(
37+
article: Article,
38+
modifier: Modifier = Modifier,
39+
) {
40+
val uriHandler = LocalUriHandler.current
41+
var url = "https://www.thedp.com/"
42+
article.articleUrl?.let {
43+
url = article.articleUrl
44+
}
45+
46+
Column(
47+
modifier =
48+
Modifier
49+
.fillMaxWidth()
50+
.aspectRatio(1f)
51+
.padding(16.dp)
52+
.clip(RoundedCornerShape(16.dp))
53+
.clickable { uriHandler.openUri(url) },
54+
) {
55+
Box(
56+
modifier =
57+
Modifier
58+
.weight(1f)
59+
.fillMaxWidth(),
60+
) {
61+
Image(
62+
painter = rememberAsyncImagePainter(article.imageUrl),
63+
contentDescription = "News Image",
64+
contentScale = ContentScale.Crop,
65+
modifier =
66+
Modifier
67+
.matchParentSize()
68+
.fillMaxWidth()
69+
.fillMaxHeight(),
70+
)
71+
}
72+
Box(
73+
modifier =
74+
Modifier
75+
.fillMaxWidth(),
76+
) {
77+
Image(
78+
painter = rememberAsyncImagePainter(article.imageUrl),
79+
contentDescription = "News Image",
80+
contentScale = ContentScale.Crop,
81+
alignment = Alignment.TopCenter,
82+
modifier =
83+
Modifier
84+
.matchParentSize()
85+
.blur(16.dp)
86+
.fillMaxWidth(),
87+
)
88+
Box(
89+
modifier =
90+
Modifier
91+
.matchParentSize()
92+
.background(Color.Black.copy(alpha = 0.5f)),
93+
)
94+
Box(
95+
modifier =
96+
Modifier
97+
.fillMaxWidth()
98+
.padding(16.dp),
99+
) {
100+
Column(
101+
verticalArrangement = Arrangement.spacedBy(6.dp),
102+
) {
103+
Row(
104+
modifier = Modifier.fillMaxWidth(),
105+
) {
106+
Text(text = " THE DAILY PENNSYLVANIAN", color = Color.LightGray)
107+
Spacer(Modifier.weight(1f))
108+
109+
var time = "1 hour ago"
110+
article.timestamp?.let {
111+
time = article.timestamp
112+
}
113+
Text(time, color = Color.LightGray)
114+
}
115+
116+
var title = "sample title here"
117+
article.title?.let {
118+
title = article.title
119+
}
120+
121+
Text(
122+
text = title,
123+
color = Color.White,
124+
fontWeight = FontWeight.Bold,
125+
fontSize = 16.sp,
126+
lineHeight = 1.25.em,
127+
)
128+
129+
var description = "sample description here"
130+
article.subtitle?.let {
131+
description = article.subtitle
132+
}
133+
Text(text = description, color = Color.White, lineHeight = 1.15.em)
134+
}
135+
}
136+
}
137+
}
138+
}

PennMobile/src/main/java/com/pennapps/labs/pennmobile/home/viewholders/HomeNewsCardHolder.kt

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,4 @@ import com.pennapps.labs.pennmobile.databinding.HomeNewsCardBinding
55

66
class HomeNewsCardHolder(
77
val itemBinding: HomeNewsCardBinding,
8-
) : RecyclerView.ViewHolder(itemBinding.root) {
9-
var homeNewsTitle = itemBinding.homeNewsTitle
10-
var homeNewsSubtitle = itemBinding.homeNewsSubtitle
11-
var homeNewsTimestamp = itemBinding.homeNewsTimestamp
12-
var homeNewsImageView = itemBinding.homeNewsIv
13-
var newsCardLogo = itemBinding.newsCardLogo
14-
var newsInfoIcon = itemBinding.newsInfoIcon
15-
var newsBlurView = itemBinding.blurView
16-
var newsCardContainer = itemBinding.newsCardContainer
17-
var newsButton = itemBinding.button
18-
var dotDivider = itemBinding.dotDivider
19-
}
8+
) : RecyclerView.ViewHolder(itemBinding.root)

0 commit comments

Comments
 (0)