Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor home widget #2344

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
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
Original file line number Diff line number Diff line change
Expand Up @@ -157,16 +157,9 @@ internal fun updateAppWidget(
views.setImageViewResource(R.id.appwidget_image, R.drawable.no_thumbnail)
}

val base64Medium = dailyInfo.medium
if (base64Medium.isNotEmpty()) {
if (dailyInfo.displayMediumIcon) {
try {
// Decode Base64 string to a byte array
val imageBytes = Base64.decode(base64Medium, Base64.DEFAULT)
// Convert byte array to Bitmap
val bitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)

// Set the image to the widget
views.setImageViewBitmap(R.id.medium_image, bitmap)
views.setImageViewResource(R.id.medium_image, R.drawable.medium_icon)
} catch (e: Exception) {
// Handle error in decoding, set a placeholder image
views.setImageViewResource(R.id.medium_image, R.drawable.failed_daily_image)
Expand All @@ -181,7 +174,7 @@ data class DailyInfo(
val base64ImageData: String, // Changed from thumbnailUrl to base64ImageData
val title: String,
val artistName: String,
val medium: String
val displayMediumIcon: Boolean
)


Expand All @@ -197,36 +190,22 @@ fun getDailyInfo(context: Context, callback: (DailyInfo) -> Unit) {

private fun getStoredDailyInfo(context: Context): DailyInfo {
val widgetData = HomeWidgetPlugin.getData(context)

val currentDateKey = getCurrentDateKey();

// Retrieve JSON string for the current date
val jsonString = widgetData.getString(currentDateKey, null)

if (jsonString != null) {
try {
// Parse JSON string
val jsonObject = JSONObject(jsonString)
val base64ImageData = jsonObject.optString("base64ImageData", "")
val title = jsonObject.optString("title", "default_title")
val artistName = jsonObject.optString("artistName", "default_artist_name")
val medium = jsonObject.optString("base64MediumIcon", "")

// Return DailyInfo object with the parsed data
return DailyInfo(
base64ImageData = base64ImageData,
title = title,
artistName = artistName,
medium = medium
)
} catch (e: Exception) {
e.printStackTrace()
return getDefaultDailyInfo()
}
val dailyDataString = widgetData.getString("dailyData", null) ?: return getDefaultDailyInfo()
try {
val dailyObject = JSONObject(dailyDataString)
val currentDateKey = getCurrentDateKey()
val todayDailyString = dailyObject.optString(currentDateKey) ?: return getDefaultDailyInfo()
val todayDailyObject = JSONObject(todayDailyString)
return DailyInfo(
base64ImageData = todayDailyObject.optString("base64ImageData", ""),
title = todayDailyObject.optString("title", "Daily Artwork"),
artistName = todayDailyObject.optString("artistName", "Artist"),
displayMediumIcon = todayDailyObject.optBoolean("displayMediumIcon", false)
)
} catch (e: Exception) {
e.printStackTrace()
return getDefaultDailyInfo()
}

// Return default DailyInfo if data for current date is not found or parsing fails
return getDefaultDailyInfo()
}

private fun getCurrentDateKey(): String {
Expand All @@ -240,6 +219,6 @@ private fun getDefaultDailyInfo(): DailyInfo {
base64ImageData = "",
title = "Daily Artwork",
artistName = "Daily is not available",
medium = ""
displayMediumIcon = false
)
}
Binary file added android/app/src/main/res/drawable/medium_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 0 additions & 18 deletions ios/Daily Widget/AppIntent.swift

This file was deleted.

23 changes: 23 additions & 0 deletions ios/Daily Widget/Assets.xcassets/MediumIcon.imageset/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "MediumIcon.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "MediumIcon@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "MediumIcon@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
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.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
196 changes: 93 additions & 103 deletions ios/Daily Widget/Daily_Widget.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,50 +30,37 @@ struct Provider: TimelineProvider {
completion(timeline)
}
}



func getStoredDailyInfo() -> DailyInfo {
let widgetData = UserDefaults.init(suiteName: widgetGroupId)

let currentDate = Date()
guard
let widgetData = UserDefaults(suiteName: widgetGroupId),
let dailyDataString = widgetData.string(forKey: "dailyData"),
let dailyData = dailyDataString.data(using: .utf8),
let dailyObject = try? JSONSerialization.jsonObject(with: dailyData, options: []) as? [String: Any]
else {
return DailyInfo.empty
}

let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
formatter.locale = Locale.current
formatter.timeZone = TimeZone.current

let currentDateKey = formatter.string(from: currentDate) // Format the date to string

// Retrieve JSON string for the current date
if let jsonString = widgetData?.string(forKey: currentDateKey) {
do {
if let jsonData = jsonString.data(using: .utf8),
let jsonObject = try JSONSerialization.jsonObject(with: jsonData) as? [String: Any] {

let title = jsonObject["title"] as? String ?? nil
let artistName = jsonObject["artistName"] as? String ?? nil
let base64MediumIcon = jsonObject["base64MediumIcon"] as? String ?? nil
let base64ImageData = jsonObject["base64ImageData"] as? String ?? nil
let base64SmallImageData = jsonObject["base64SmallImageData"] as? String ?? nil

return DailyInfo(
title: title,
artistName: artistName,
base64ImageData: base64ImageData,
base64SmallImageData: base64SmallImageData,
base64MediumIcon: base64MediumIcon
)
}
} catch {
print("Error parsing JSON: \(error)")
}
let currentDateKey = formatter.string(from: Date())

guard
let todayDailyString = dailyObject[currentDateKey] as? String,
let todayDailyData = todayDailyString.data(using: .utf8),
let todayDailyObject = try? JSONSerialization.jsonObject(with: todayDailyData, options: []) as? [String: Any]
else {
return DailyInfo.empty
}

return DailyInfo(
title: nil,
artistName: nil,
base64ImageData: nil,
base64SmallImageData: nil,
base64MediumIcon: nil
title: todayDailyObject["title"] as? String,
artistName: todayDailyObject["artistName"] as? String,
base64ImageData: todayDailyObject["base64ImageData"] as? String,
base64SmallImageData: todayDailyObject["base64SmallImageData"] as? String,
displayMediumIcon: (todayDailyObject["displayMediumIcon"] as? Bool) ?? false
)
}
}
Expand All @@ -83,7 +70,9 @@ struct DailyInfo {
let artistName: String?
let base64ImageData: String?
let base64SmallImageData: String?
let base64MediumIcon: String?
let displayMediumIcon: Bool

static let empty = DailyInfo(title: nil, artistName: nil, base64ImageData: nil, base64SmallImageData: nil, displayMediumIcon: false)
}

struct SimpleEntry: TimelineEntry {
Expand All @@ -97,6 +86,14 @@ struct Daily_WidgetEntryView : View {
@Environment(\.colorScheme) var colorScheme
@Environment(\.widgetFamily) var family

private var backgroundColor: Color {
colorScheme == .dark ? Color("#1C1C1E") : .white
}

private var textColor: Color {
colorScheme == .dark ? .white : .black
}

private var heightReader: some View {
GeometryReader { reader in
Color.clear
Expand All @@ -118,73 +115,66 @@ struct Daily_WidgetEntryView : View {

GeometryReader { geo in
VStack(spacing: 0) {
ZStack {
if let artworkThumbnail = imageFromBase64(
(family == .systemSmall ? entry.dailyInfo?.base64SmallImageData : entry.dailyInfo?.base64ImageData) ?? "") {
Image(uiImage: artworkThumbnail)
.resizable()
.scaledToFill()
.frame(maxWidth: geo.size.width, maxHeight: geo.size.height - infoViewHeight)
.clipped()
} else {
colorScheme == .dark ? Color("#1C1C1E").edgesIgnoringSafeArea(.all) : Color.white.edgesIgnoringSafeArea(.all)
}


if let mediumIcon = imageFromBase64(entry.dailyInfo?.base64MediumIcon ?? "") {
Image(uiImage: mediumIcon)
.resizable()
.frame(width: 60, height: 58, alignment: .center)
}
}
.frame(
maxWidth: geo.size.width,
maxHeight: geo.size.height - infoViewHeight
)

HStack(spacing: family == .systemSmall ? 10 : 20) {
VStack(alignment: .leading, spacing: -2) {
if let artistName = entry.dailyInfo?.artistName {
Text("\(artistName),")
.foregroundColor(colorScheme == .dark ? .white : .black)
.font(.footnote)
.lineLimit(1)
.truncationMode(.tail)
} else {
Text("Daily artwork")
.foregroundColor(colorScheme == .dark ? .white : .black)
.font(.footnote.bold())
.lineLimit(1)
.truncationMode(.tail)
}

if let artworkTitle = entry.dailyInfo?.title {
Text(artworkTitle)
.foregroundColor(colorScheme == .dark ? .white : .black)
.font(.footnote.bold().italic())
.lineLimit(1)
.truncationMode(.tail)
} else {
Text("Daily artwork is not available")
.foregroundColor(colorScheme == .dark ? .white : .black)
.font(.footnote)
.lineLimit(1)
.truncationMode(.tail)
}
}
.frame(maxWidth: .infinity, alignment: .leading)
.layoutPriority(1)

Image(colorScheme == .dark ? "FFDarkIcon" : "FFLightIcon").frame(width: 30, height: 20)

}
.padding(.all, 15)
.frame(maxWidth: .infinity)
.background(colorScheme == .dark ? Color("#1C1C1E") : Color.white)
.background { heightReader }
imageSection(geo.size)
infoSection
}
.frame(maxWidth: geo.size.width, maxHeight: .infinity)
}.widgetURL(URL(string: "home-widget://message?message=dailyWidgetClicked&widget=daily&homeWidget"))
}
.widgetURL(URL(string: "home-widget://message?message=dailyWidgetClicked&widget=daily&homeWidget"))
}

@ViewBuilder
private func imageSection(_ size: CGSize) -> some View {
ZStack {
if let artworkThumbnail = imageFromBase64(
(family == .systemSmall ? entry.dailyInfo?.base64SmallImageData : entry.dailyInfo?.base64ImageData) ?? ""
) {
Image(uiImage: artworkThumbnail)
.resizable()
.scaledToFill()
.frame(maxWidth: size.width, maxHeight: size.height - infoViewHeight)
.clipped()
} else {
backgroundColor.edgesIgnoringSafeArea(.all)
}

if (entry.dailyInfo != nil && entry.dailyInfo!.displayMediumIcon) {
Image("MediumIcon")
.resizable()
.frame(width: 60, height: 58, alignment: .center)
}
}
.frame(
maxWidth: size.width,
maxHeight: size.height - infoViewHeight
)
}

private var infoSection: some View {
HStack(spacing: family == .systemSmall ? 10 : 20) {
VStack(alignment: .leading, spacing: -2) {
Text(entry.dailyInfo?.artistName ?? "Daily artwork")
.font(.footnote)
.foregroundColor(textColor)
.lineLimit(1)
.truncationMode(.tail)

Text(entry.dailyInfo?.title ?? "Daily artwork is not available")
.font(.footnote.bold().italic())
.foregroundColor(textColor)
.lineLimit(1)
.truncationMode(.tail)
}
.frame(maxWidth: .infinity, alignment: .leading)
.layoutPriority(1)

Image(colorScheme == .dark ? "FFDarkIcon" : "FFLightIcon")
.frame(width: 30, height: 20)
}
.padding(.all, 15)
.frame(maxWidth: .infinity)
.background(backgroundColor)
.background { heightReader }
}
}

Expand Down
Loading