Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
e5d2904
Added Glance Widget for JetChat
shangeethsivan Jun 28, 2024
09fe44f
Added Glance Widget for JetChat
shangeethsivan Jun 28, 2024
78716ea
Added Glance Widget for JetChat
shangeethsivan Jun 28, 2024
6c54e0c
Merge branch 'android:main' into main
shangeethsivan Jul 3, 2024
7982007
Added Glance Widget for JetChat
shangeethsivan Jun 28, 2024
ed13f9a
Added Glance Widget for JetChat
shangeethsivan Jun 28, 2024
25e745f
Added widget preview in readme.
shangeethsivan Jul 3, 2024
27929da
Added Glance Widget for JetChat
shangeethsivan Jun 28, 2024
f9fc151
Added Glance Widget for JetChat
shangeethsivan Jun 28, 2024
8321785
Added Glance Widget for JetChat
shangeethsivan Jun 28, 2024
b532df8
Added Glance Widget for JetChat
shangeethsivan Jun 28, 2024
5f6382f
Added Glance Widget for JetChat
shangeethsivan Jun 28, 2024
a97068c
Added widget preview in readme.
shangeethsivan Jul 3, 2024
f3ff8c4
Merge remote-tracking branch 'origin/main'
shangeethsivan Oct 17, 2024
3304bc8
Added JetchatWidget: Introduced repository to fetch messages, Also in…
shangeethsivan Nov 10, 2024
75399bd
Merge remote-tracking branch 'origin2/main'
shangeethsivan Nov 10, 2024
84d5187
Glance Widget JetChat :Moved code to not exceed max line length.
shangeethsivan Nov 16, 2024
78617e7
Merge branch 'main' of https://github.com/android/compose-samples
shangeethsivan Nov 16, 2024
bb03275
Glance Widget JetChat : Ran SpotlessApply
shangeethsivan Nov 25, 2024
b7f5199
Merge branch 'main' of https://github.com/android/compose-samples
shangeethsivan Jan 1, 2025
d10602e
Added JetChatWidget: Moved the settings section along with widget dis…
shangeethsivan Jan 1, 2025
5ca6e31
Using HorizontalDivider instead of Divider as its deprecated
shangeethsivan Jan 1, 2025
668120e
Removed the DI pattern and added the unread messages in the FakeData.…
shangeethsivan Jan 9, 2025
5038653
Glance Widget JetChat : Removed MessagesRepository.kt and ran spotless.
shangeethsivan Jan 10, 2025
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 Jetchat/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ This sample showcases:

<img src="screenshots/screenshots.png"/>

<img src="screenshots/widget.png" width="300"/>

<img src="screenshots/widget_discoverability.png" width="300"/>

### Status: 🚧 In progress

Jetchat is still in under development, and some features are not yet implemented.
Expand Down
2 changes: 2 additions & 0 deletions Jetchat/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ dependencies {
implementation(composeBom)
androidTestImplementation(composeBom)

implementation(libs.androidx.glance.appwidget)
implementation(libs.androidx.glance.material3)
implementation(libs.kotlin.stdlib)
implementation(libs.kotlinx.coroutines.android)

Expand Down
10 changes: 9 additions & 1 deletion Jetchat/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<receiver android:name=".widget.WidgetReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/my_app_widget_info" />
</receiver>
</application>
</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@

package com.example.compose.jetchat.components

import android.appwidget.AppWidgetManager
import android.content.ComponentName
import android.content.Context
import android.os.Build
import android.widget.Toast
import androidx.annotation.DrawableRes
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
Expand Down Expand Up @@ -44,13 +49,16 @@ import androidx.compose.ui.Alignment.Companion.CenterVertically
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.compose.jetchat.R
import com.example.compose.jetchat.data.colleagueProfile
import com.example.compose.jetchat.data.meProfile
import com.example.compose.jetchat.theme.JetchatTheme
import com.example.compose.jetchat.widget.WidgetReceiver

@Composable
fun JetchatDrawerContent(
Expand All @@ -73,9 +81,13 @@ fun JetchatDrawerContent(
ProfileItem("Taylor Brooks", colleagueProfile.photo) {
onProfileClicked(colleagueProfile.userId)
}
DividerItem(modifier = Modifier.padding(horizontal = 28.dp))
DrawerItemHeader("Settings")
WidgetDiscoverability()
}
}


@Composable
private fun DrawerHeader() {
Row(modifier = Modifier.padding(16.dp), verticalAlignment = CenterVertically) {
Expand All @@ -90,6 +102,7 @@ private fun DrawerHeader() {
)
}
}

@Composable
private fun DrawerItemHeader(text: String) {
Box(
Expand Down Expand Up @@ -199,6 +212,7 @@ fun DrawerPreview() {
}
}
}

@Composable
@Preview
fun DrawerPreviewDark() {
Expand All @@ -210,3 +224,50 @@ fun DrawerPreviewDark() {
}
}
}


@Composable
private fun WidgetDiscoverability() {
val context = LocalContext.current
Row(
modifier = Modifier
.height(56.dp)
.fillMaxWidth()
.padding(horizontal = 12.dp)
.clip(CircleShape)
.clickable(onClick = {
addWidgetToHomeScreen(context)
}),
verticalAlignment = CenterVertically
) {
Text(
stringResource(id = R.string.add_widget_to_home_page),
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurface,
modifier = Modifier.padding(start = 12.dp)
)
}
}

private fun addWidgetToHomeScreen(context: Context) {
val appWidgetManager = AppWidgetManager.getInstance(context)
val myProvider = ComponentName(context, WidgetReceiver::class.java)

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (appWidgetManager.isRequestPinAppWidgetSupported) {
appWidgetManager.requestPinAppWidget(myProvider, null, null)
} else {
Toast.makeText(
context,
"Unable to add widget, please add from home screen",
Toast.LENGTH_LONG
).show()
}
} else {
Toast.makeText(
context,
"Unable to add widget, please add from home screen",
Toast.LENGTH_LONG
).show()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,5 @@ data class Message(
val content: String,
val timestamp: String,
val image: Int? = null,
val authorImage: Int = if (author == "me") R.drawable.ali else R.drawable.someone_else
val authorImage: Int = if (author == "me") R.drawable.ali else R.drawable.someone_else,
)
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,58 @@ private val initialMessages = listOf(
"8:03 PM"
)
)
val unreadMessages = listOf(
Message(
"Taylor Brooks",
"You can use all the same stuff",
"8:05 PM"
),
Message(
"Taylor Brooks",
"@aliconors Take a look at the `Flow.collectAsStateWithLifecycle()` APIs",
"8:05 PM"
),
Message(
"Taylor Brooks",
"You can use all the same stuff",
"8:05 PM"
),
Message(
"Taylor Brooks",
"@aliconors Take a look at the `Flow.collectAsStateWithLifecycle()` APIs",
"8:05 PM"
),
Message(
"Taylor Brooks",
"You can use all the same stuff",
"8:05 PM"
),
Message(
"Taylor Brooks",
"@aliconors Take a look at the `Flow.collectAsStateWithLifecycle()` APIs",
"8:05 PM"
),
Message(
"Taylor Brooks",
"You can use all the same stuff",
"8:05 PM"
),
Message(
"Taylor Brooks",
"@aliconors Take a look at the `Flow.collectAsStateWithLifecycle()` APIs",
"8:05 PM"
),
Message(
"Taylor Brooks",
"You can use all the same stuff",
"8:05 PM"
),
Message(
"Taylor Brooks",
"@aliconors Take a look at the `Flow.collectAsStateWithLifecycle()` APIs",
"8:05 PM"
),
)

val exampleUiState = ConversationUiState(
initialMessages = initialMessages,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.example.compose.jetchat.widget

import android.content.Context
import androidx.glance.GlanceId
import androidx.glance.GlanceTheme
import androidx.glance.appwidget.GlanceAppWidget
import androidx.glance.appwidget.provideContent
import com.example.compose.jetchat.widget.composables.MessagesWidget

class JetChatWidget : GlanceAppWidget() {

override suspend fun provideGlance(context: Context, id: GlanceId) {
provideContent {
GlanceTheme {
MessagesWidget()
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.example.compose.jetchat.widget

import androidx.glance.appwidget.GlanceAppWidget
import androidx.glance.appwidget.GlanceAppWidgetReceiver

class WidgetReceiver : GlanceAppWidgetReceiver() {

override val glanceAppWidget: GlanceAppWidget
get() = JetChatWidget()

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.example.compose.jetchat.widget.composables

import androidx.compose.runtime.Composable
import androidx.compose.ui.unit.dp
import androidx.glance.GlanceModifier
import androidx.glance.ImageProvider
import androidx.glance.LocalContext
import androidx.glance.action.actionStartActivity
import androidx.glance.action.clickable
import androidx.glance.appwidget.components.Scaffold
import androidx.glance.appwidget.components.TitleBar
import androidx.glance.appwidget.lazy.LazyColumn
import androidx.glance.layout.Column
import androidx.glance.layout.Spacer
import androidx.glance.layout.fillMaxWidth
import androidx.glance.layout.height
import androidx.glance.text.FontWeight
import androidx.glance.text.Text
import androidx.glance.text.TextStyle
import com.example.compose.jetchat.NavActivity
import com.example.compose.jetchat.R
import com.example.compose.jetchat.conversation.Message
import com.example.compose.jetchat.data.unreadMessages

@Composable
fun MessagesWidget() {
Scaffold(titleBar = {
TitleBar(
startIcon = ImageProvider(R.drawable.ic_jetchat),
iconColor = null,
title = LocalContext.current.getString(R.string.app_name_unreads),
)
}) {
val unreadMessage = unreadMessages
LazyColumn(modifier = GlanceModifier.fillMaxWidth()) {
unreadMessage.forEach {
item {
Column(modifier = GlanceModifier.fillMaxWidth()) {
MessageItem(it)
Spacer(modifier = GlanceModifier.height(10.dp))
}
}
}
}
}
}

@Composable
fun MessageItem(message: Message) {
Column(modifier = GlanceModifier.clickable(actionStartActivity<NavActivity>()).fillMaxWidth()) {
Text(
text = message.author,
style = TextStyle(fontWeight = FontWeight.Bold)
)
Text(
text = message.content,
style = TextStyle(fontWeight = FontWeight.Normal)
)
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions Jetchat/app/src/main/res/layout/widget_error_layout.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:gravity="center">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/black30"
android:text="@string/widget_loading_error" />
</RelativeLayout>
11 changes: 11 additions & 0 deletions Jetchat/app/src/main/res/layout/widget_loading_layout.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff">

<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</FrameLayout>
3 changes: 3 additions & 0 deletions Jetchat/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,8 @@
<string name="more_options">More options</string>
<string name="touch_and_hold_to_record">Touch and hold to record</string>
<string name="record_message">Record voice message</string>
<string name="widget_loading_error">Cannot load Widget</string>
<string name="app_name_unreads">JetChat (Un-Reads)</string>
<string name="add_widget_to_home_page">Add Widget to Home Page</string>

</resources>
9 changes: 9 additions & 0 deletions Jetchat/app/src/main/res/xml/my_app_widget_info.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="@layout/widget_loading_layout"
android:minWidth="276dp"
android:minHeight="102dp"
android:previewImage="@drawable/widget_icon"
android:resizeMode="none"
android:targetCellWidth="4"
android:targetCellHeight="3" />
Binary file added Jetchat/screenshots/widget.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.