Skip to content

Add latest video widget#10

Open
arjun-dureja wants to merge 1 commit intomainfrom
latest-video-widget
Open

Add latest video widget#10
arjun-dureja wants to merge 1 commit intomainfrom
latest-video-widget

Conversation

@arjun-dureja
Copy link
Owner

@arjun-dureja arjun-dureja commented Mar 16, 2026

@arjun-dureja
Copy link
Owner Author

@codex review

Copy link

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 5 additional findings.

Open in Devin Review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1149e9e0cf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

guard hasProAccess else { return false }
guard showWidgetRefreshButton else { return false }
guard channel?.channelName != YouTubeChannel.preview.channelName else { return false }
return latestUpload != nil

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep refresh button available when upload data is missing

The refresh control is hidden whenever latestUpload is nil, which means a transient API failure (or any decode/network error path that leaves the channel present but upload absent) removes the user's only manual recovery path. In that state the widget shows placeholder content but cannot be refreshed on demand, so users must wait for the next scheduled timeline reload instead of retrying immediately.

Useful? React with 👍 / 👎.

Comment on lines +122 to +127
let uploadsPlaylistId = try await getUploadsPlaylistId(for: channelIdWithoutSpaces)
let latestVideoId = try await getLatestUploadVideoId(for: uploadsPlaylistId)
let latestUpload = try await getLatestUploadVideoDetails(for: latestVideoId)

try latestUploadStorage?.setObject(latestUpload, forKey: channelIdWithoutSpaces)
return latestUpload

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: 3 sequential API calls per widget refresh for latest upload

Each latest upload widget refresh makes 3 sequential YouTube API calls: getUploadsPlaylistId (channels?part=contentDetails), getLatestUploadVideoId (playlistItems), and getLatestUploadVideoDetails (videos) — plus an image download. The 120-second cache (SubscriberWidget/Services/YouTubeService.swift:20-21) mitigates this during rapid refreshes, but each cold fetch consumes significant API quota. The uploads playlist ID for a channel is stable and could be cached with a much longer TTL to reduce calls from 3 to 2 on most refreshes.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +45 to +70
func getSnapshot(
for configuration: SelectChannelIntent,
in context: Context,
completion: @escaping (LatestUploadEntry) -> Void
) {
Task {
let channelStorageService = ChannelStorageService()

if configuration.channel == nil {
let channels = channelStorageService.getChannels()
guard let firstChannel = channels.first else {
completion(LatestUploadEntry(channel: nil, latestUpload: nil))
return
}

completion(await fetchLatestUpload(for: firstChannel))
} else {
completion(
await fetchLatestUpload(
for: configuration.channel ?? YouTubeChannelParam.global,
channelStorageService: channelStorageService
)
)
}
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚩 getSnapshot makes network calls without checking context.isPreview

The getSnapshot method at SubscriberCount/LatestUploadTimelineProvider.swift:45-70 always makes network calls to fetch the latest upload, even when called from the widget gallery (where context.isPreview is true). WidgetKit best practices recommend returning quickly with placeholder data in the preview context. The existing SubWidgetIntentTimelineProvider has a similar pattern (it fetches images in the snapshot), but the new provider is heavier because it makes 3 API calls + image download. This could cause the widget to appear blank or slow in the widget gallery if the network is slow.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant