Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions PennMobile/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ dependencies {
// If you want the foundation layout, use the bundle or the specific activity compose you have defined
implementation libs.androidx.activity.compose
implementation libs.androidx.material3.android
implementation libs.androidx.compose.ui.tooling.preview
// implementation libs.androidx.foundation.layout

ktlintRuleset libs.ktlint
Expand Down Expand Up @@ -137,6 +138,7 @@ dependencies {
implementation libs.bundles.ui
implementation libs.bundles.google
implementation libs.bundles.hilt
debugImplementation libs.androidx.compose.ui.tooling

ksp libs.androidx.room.compiler
ksp libs.androidx.hilt.compiler
Expand All @@ -146,6 +148,8 @@ dependencies {

implementation libs.androidx.hilt.android
ksp libs.androidx.hilt.compiler

implementation libs.coil.compose
}

String getPlatformClientID() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import androidx.browser.customtabs.CustomTabsClient
import androidx.browser.customtabs.CustomTabsIntent
import androidx.browser.customtabs.CustomTabsServiceConnection
import androidx.browser.customtabs.CustomTabsSession
import androidx.compose.ui.platform.ComposeView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat.getColor
import androidx.core.content.ContextCompat.startActivity
Expand Down Expand Up @@ -53,6 +54,7 @@ import com.pennapps.labs.pennmobile.home.classes.CalendarCell
import com.pennapps.labs.pennmobile.home.classes.CalendarEvent
import com.pennapps.labs.pennmobile.home.classes.HomepageDataModel
import com.pennapps.labs.pennmobile.home.classes.NewsCell
import com.pennapps.labs.pennmobile.home.classes.NewsComposableComponent
import com.pennapps.labs.pennmobile.home.classes.Poll
import com.pennapps.labs.pennmobile.home.classes.PollCell
import com.pennapps.labs.pennmobile.home.classes.Post
Expand Down Expand Up @@ -583,149 +585,10 @@ class HomeAdapter(
) {
val article = cell.article

if (article.imageUrl.isNullOrEmpty()) {
holder.itemView.visibility = View.GONE
holder.newsCardContainer.visibility = View.GONE
holder.homeNewsImageView.setImageDrawable(null)
holder.homeNewsTitle.text = ""
holder.homeNewsSubtitle.text = ""
holder.homeNewsTimestamp.text = ""
dataModel.notifyNewsBlurLoaded()
return
}

holder.homeNewsTitle.text = article.title
holder.homeNewsSubtitle.text = article.subtitle

holder.homeNewsTimestamp.text = article.timestamp?.trim()

Glide
.with(mContext)
.load(article.imageUrl)
.fitCenter()
.centerCrop()
.into(holder.homeNewsImageView)

// /** Adds dynamically generated accent color from the fetched image to the news card */
var accentColor: Int = getColor(mContext, R.color.black)
mActivity.lifecycleScope.launch(Dispatchers.Default) {
Log.d("HomeAdapter", "Image Url is ${article.imageUrl}")
val bitmap =
withContext(Dispatchers.IO) {
Glide
.with(mContext)
.load(article.imageUrl)
.submit()
.get()
}.toBitmap()

// Create palette from bitmap
fun createPaletteSync(bitmap: Bitmap): Palette = Palette.from(bitmap).generate()
val vibrantSwatch: Palette.Swatch? = createPaletteSync(bitmap).darkVibrantSwatch
vibrantSwatch?.rgb?.let { accentColor = it }

mActivity.runOnUiThread {
// Change all the components to match the accent color palette
vibrantSwatch?.titleTextColor?.let {
DrawableCompat.setTint(
DrawableCompat.wrap(holder.newsCardLogo.drawable),
ColorUtils.setAlphaComponent(it, 150),
)
DrawableCompat.setTint(
DrawableCompat.wrap(holder.newsInfoIcon.drawable),
it,
)
DrawableCompat.setTint(
DrawableCompat.wrap(holder.dotDivider.drawable),
it,
)
holder.newsButton.setTextColor(ColorUtils.setAlphaComponent(it, 150))
DrawableCompat.setTint(
DrawableCompat.wrap(holder.newsButton.background),
it,
)
holder.homeNewsTitle.setTextColor(
ColorUtils.setAlphaComponent(
it,
150,
),
)
holder.homeNewsSubtitle.setTextColor(it)
holder.homeNewsTimestamp.setTextColor(it)
}
holder.newsCardContainer.background =
BitmapDrawable(
holder.itemBinding.root.resources,
bitmap,
)
holder.newsBlurView
.setOverlayColor(ColorUtils.setAlphaComponent(accentColor, 150))

// tell model that the news blur view has been loaded
dataModel.notifyNewsBlurLoaded()
}
}

// Logic for the more info button on the news card
holder.newsInfoIcon.setOnClickListener {
when (holder.homeNewsSubtitle.visibility) {
View.GONE -> {
holder.homeNewsSubtitle.visibility = View.VISIBLE
holder.homeNewsTitle.setPadding(0, 0, 0, 0)
holder.newsBlurView
.setOverlayColor(ColorUtils.setAlphaComponent(accentColor, 250))
}

View.VISIBLE -> {
holder.homeNewsSubtitle.visibility = View.GONE
holder.homeNewsTitle.setPadding(0, 0, 0, convertToDp(mContext, 8f))
holder.newsBlurView
.setOverlayColor(ColorUtils.setAlphaComponent(accentColor, 150))
}
}
}

// Sets up blur view on news card
holder.newsBlurView
.setupWith(holder.newsCardContainer, RenderScriptBlur(mContext))
.setFrameClearDrawable(ColorDrawable(getColor(mContext, R.color.white)))
.setBlurRadius(25f)

holder.newsButton.setOnClickListener {
val url = article?.articleUrl

val connection = NewsCustomTabsServiceConnection()
builder = CustomTabsIntent.Builder()
share = Intent(Intent.ACTION_SEND)
share?.type = "text/plain"
builder?.setToolbarColor(0x3E50B4)
builder?.setStartAnimations(
mContext,
androidx.appcompat.R.anim.abc_popup_enter,
androidx.appcompat.R.anim.abc_popup_exit,
)
CustomTabsClient.bindCustomTabsService(
mContext,
NewsFragment.CUSTOM_TAB_PACKAGE_NAME,
connection,
)

if (mContext.isChromeCustomTabsSupported()) {
share?.putExtra(Intent.EXTRA_TEXT, url)
builder?.addMenuItem(
"Share",
PendingIntent.getActivity(
mContext,
0,
share,
PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE,
),
)
customTabsIntent = builder?.build()
customTabsIntent?.launchUrl(mActivity, Uri.parse(url))
} else {
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
startActivity(mContext, browserIntent, null)
val composeView = holder.itemView.findViewById<ComposeView>(R.id.news_compose_view)
composeView.apply {
setContent {
NewsComposableComponent(article)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package com.pennapps.labs.pennmobile.home.classes

import android.content.Context
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.blur
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.em
import androidx.compose.ui.unit.sp
import coil.compose.rememberAsyncImagePainter

@Composable
fun NewsComposableComponent(
article: Article,
modifier: Modifier = Modifier,
) {
val uriHandler = LocalUriHandler.current
var url = "https://www.thedp.com/"
article.articleUrl?.let {
url = article.articleUrl
}

Column(
modifier =
Modifier
.fillMaxWidth()
.aspectRatio(1f)
.padding(16.dp)
.clip(RoundedCornerShape(16.dp))
.clickable { uriHandler.openUri(url) },
) {
Box(
modifier =
Modifier
.weight(1f)
.fillMaxWidth(),
) {
Image(
painter = rememberAsyncImagePainter(article.imageUrl),
contentDescription = "News Image",
contentScale = ContentScale.Crop,
modifier =
Modifier
.matchParentSize()
.fillMaxWidth()
.fillMaxHeight(),
)
}
Box(
modifier =
Modifier
.fillMaxWidth(),
) {
Image(
painter = rememberAsyncImagePainter(article.imageUrl),
contentDescription = "News Image",
contentScale = ContentScale.Crop,
alignment = Alignment.TopCenter,
modifier =
Modifier
.matchParentSize()
.blur(16.dp)
.fillMaxWidth(),
)
Box(
modifier =
Modifier
.matchParentSize()
.background(Color.Black.copy(alpha = 0.5f)),
)
Box(
modifier =
Modifier
.fillMaxWidth()
.padding(16.dp),
) {
Column(
verticalArrangement = Arrangement.spacedBy(6.dp),
) {
Row(
modifier = Modifier.fillMaxWidth(),
) {
Text(text = " THE DAILY PENNSYLVANIAN", color = Color.LightGray)
Spacer(Modifier.weight(1f))

var time = "1 hour ago"
article.timestamp?.let {
time = article.timestamp
}
Text(time, color = Color.LightGray)
}

var title = "sample title here"
article.title?.let {
title = article.title
}

Text(
text = title,
color = Color.White,
fontWeight = FontWeight.Bold,
fontSize = 16.sp,
lineHeight = 1.25.em,
)

var description = "sample description here"
article.subtitle?.let {
description = article.subtitle
}
Text(text = description, color = Color.White, lineHeight = 1.15.em)
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,4 @@ import com.pennapps.labs.pennmobile.databinding.HomeNewsCardBinding

class HomeNewsCardHolder(
val itemBinding: HomeNewsCardBinding,
) : RecyclerView.ViewHolder(itemBinding.root) {
var homeNewsTitle = itemBinding.homeNewsTitle
var homeNewsSubtitle = itemBinding.homeNewsSubtitle
var homeNewsTimestamp = itemBinding.homeNewsTimestamp
var homeNewsImageView = itemBinding.homeNewsIv
var newsCardLogo = itemBinding.newsCardLogo
var newsInfoIcon = itemBinding.newsInfoIcon
var newsBlurView = itemBinding.blurView
var newsCardContainer = itemBinding.newsCardContainer
var newsButton = itemBinding.button
var dotDivider = itemBinding.dotDivider
}
) : RecyclerView.ViewHolder(itemBinding.root)
Loading
Loading