-
Notifications
You must be signed in to change notification settings - Fork 1
feat(llc): implement attachment uploader #11
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
Conversation
This commit introduces the `StreamAttachmentUploader` for handling file and image uploads to the Stream CDN. Key changes: - Added `CdnApi` with methods for uploading and deleting files and images. - Implemented `FeedsCdnClient` to wrap `CdnApi` and conform to the `CdnClient` interface from `stream_core`. - Integrated `StreamAttachmentUploader` into `FeedsClientImpl`. - Modified `ActivitiesRepository` and `CommentsRepository` to use `StreamAttachmentUploader` for uploading attachments before creating activities or comments. - Updated `FeedAddActivityRequest` and `ActivityAddCommentRequest` to include `attachmentUploads` (list of `StreamAttachment`). - Renamed `onSendProgress` to `onUploadProgress` in `CdnApi` for clarity. - Updated relevant public API surfaces and internal logic to support attachment uploads. - Regenerated `cdn_api.g.dart`.
Moves CDN-related files from the `file` directory to a new `cdn` directory.
# Conflicts: # packages/stream_feeds/lib/stream_feeds.dart # sample_app/lib/home_screen/home_screen.dart # sample_app/pubspec.yaml
- Updated stream_core dependency to use a git reference. - Added activityId to ActivityAddCommentRequest in sample_app.
| final uploadedAttachments = await _uploadStreamAttachments( | ||
| request.attachmentUploads, | ||
| ); | ||
|
|
||
| final currentAttachments = request.attachments ?? []; | ||
| final updatedAttachments = currentAttachments.merge( | ||
| uploadedAttachments, | ||
| key: (it) => (it.type, it.assetUrl, it.imageUrl), | ||
| ); | ||
|
|
||
| final updatedRequest = request.copyWith( | ||
| attachments: updatedAttachments.takeIf((it) => it.isNotEmpty), | ||
| ); | ||
|
|
||
| final result = await _api.addActivity( | ||
| addActivityRequest: request, | ||
| addActivityRequest: updatedRequest.toRequest(), | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we just create the activities without attachments if the uploads fail? Shouldn't we return an error in that case?
| // | ||
| // Processes the provided attachments by uploading them via the uploader | ||
| // and converting successful uploads to API attachment objects. | ||
| Future<List<api.Attachment>> _uploadStreamAttachments( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have the feeling this is the exact same code in multiple places, maybe this can also go to the helper class?
This commit introduces a new `StreamAttachmentUploader` extension with methods to handle attachment uploads for requests that implement the `HasAttachments` interface. The key changes include: - **`HasAttachments` interface:** Defines a contract for requests that support attachment uploads, ensuring they provide a way to access and update attachments. - **`processRequest` method:** Uploads `StreamAttachment` items from a single request, merges them with existing attachments, and returns an updated request. - **`processRequestsBatch` method:** Processes multiple requests with attachment uploads in parallel, leveraging `processRequest`. - **Integration with `FeedAddActivityRequest` and `ActivityAddCommentRequest`:** These request models now implement `HasAttachments` and utilize the new uploader utility in `ActivitiesRepository` and `CommentsRepository` respectively. This simplifies attachment handling in these repositories. - **Nullable `attachmentUploads`:** The `attachmentUploads` field in `FeedAddActivityRequest` and `ActivityAddCommentRequest` is now nullable to align with the uploader's behavior, where an empty or null list signifies no new uploads. This change streamlines the process of uploading attachments before sending API requests, making the code more robust and easier to maintain.
| late final feed = context.client.feedFromQuery( | ||
| FeedQuery( | ||
| fid: FeedId(group: 'user', id: widget.currentUser.id), | ||
| fid: FeedId(group: 'user', id: context.currentUser.id), | ||
| data: FeedInputData( | ||
| visibility: FeedVisibility.public, | ||
| members: [FeedMemberRequestData(userId: widget.currentUser.id)], | ||
| members: [FeedMemberRequestData(userId: context.currentUser.id)], | ||
| ), | ||
| ), | ||
| ); | ||
|
|
||
| @override | ||
| void initState() { | ||
| super.initState(); | ||
| void didChangeDependencies() { | ||
| super.didChangeDependencies(); | ||
| feed.getOrCreate(); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
context.client might be different here, so we also have to (re)create the feed object in didChangeDependencies.
| return SessionScope( | ||
| user: user, | ||
| client: client, | ||
| child: const AutoRouter(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you use AutoRouter here? That's already done by the material app right?
| @override | ||
| void initState() { | ||
| super.initState(); | ||
| void didChangeDependencies() { | ||
| super.didChangeDependencies(); | ||
| feed.getOrCreate(); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another issue here is that this is being called every time you resize the window, as the MediaQuery changes.
In this video you see 429 responses in the logs on the background.
screen.resizing.mov
I think what you want to do here is to only getOrCreate the feed when the current user changes?
So something like this:
Feed? feed;
String? currentUserId;
@override
void didChangeDependencies() {
super.didChangeDependencies();
if (currentUserId != context.currentUser.id) {
currentUserId = context.currentUser.id;
feed?.dispose();
feed = context.client.feedFromQuery(
FeedQuery(
fid: FeedId(group: 'user', id: context.currentUser.id),
data: FeedInputData(
visibility: FeedVisibility.public,
members: [FeedMemberRequestData(userId: context.currentUser.id)],
),
),
)..getOrCreate();
}
}This commit introduces a dedicated session scope for dependency injection using `injectable`. This replaces the previous `SessionScope` InheritedWidget. Key changes: - **`SessionModule`:** A new module is added to provide `StreamFeedsClient` within the session scope. - **`HomeScreen`:** Now manages the session scope lifecycle. It initializes the scope in `initState` and disposes of it in `dispose`. - **Removed `SessionScope` widget:** The `SessionScope` InheritedWidget and its associated extension have been removed. - **Updated `UserFeedScreen`:** Now retrieves `StreamFeedsClient` and the current user directly from the DI container within the session scope. - **`AuthGuard`:** Simplified logging. This change centralizes session-specific dependency management and aligns with standard DI practices.
This commit renames `AuthModule` to `SessionModule` to better reflect its purpose. Additionally, the method `authenticatedFeeds` within the module has been renamed to `authenticatedFeedsClient` for clarity. This change has been propagated to the dependency injection configuration.
# Conflicts: # melos.yaml # packages/stream_feeds/lib/stream_feeds.dart # packages/stream_feeds/pubspec.yaml # sample_app/lib/screens/user_feed/user_feed_screen.dart
This commit updates the documentation snippets for file uploads and activities to reflect recent changes and best practices.
**Key changes:**
- **`03_03_file_uploads.dart`:**
- Added comprehensive examples for uploading files and images, including:
- Step-by-step instructions for uploading individual files.
- How to include `StreamAttachment` objects directly in `FeedAddActivityRequest` and `ActivityAddCommentRequest` for automatic uploading.
- Guidance on implementing a custom `CdnClient` for users who want to use their own CDN.
- **`01_01_quickstart.dart` and `sample_app`:**
- Updated `addComment` calls to use the named `request` parameter and `ActivityAddCommentRequest`.
- **`04_01_feeds.dart`:**
- Improved formatting and added comments for clarity in feed reading and filtering examples.
- **`03_01_activities.dart`:**
- Added `custom` data examples to image and video `Attachment` objects.
- Simplified the delete activity example.
- **`sample_app` UI:**
- Updated icons in `activity_content.dart` for comments, hearts, and reposts to use outlined variants for inactive states and filled variants for active states.
- Changed the `type` of new activities created in `create_activity_bottom_sheet.dart` from 'activity' to 'post'.
- **`models.dart`:**
- Exported `FeedsConfig`.
- **`pubspec.lock`:**
- Updated various dependency versions.
This commit updates the `deleteFile` and `deleteImage` methods in `FeedsClient` and `FeedsClientImpl` to accept the `url` parameter as a named, required argument. Additionally, it adds a new code snippet to the documentation demonstrating how to use these methods to delete files and images from the CDN.
This pull request adds comprehensive support for file and image uploads and deletions via a new CDN client abstraction, and improves how attachments are handled when adding comments. The changes introduce a new
CdnClientinterface and implementation, update the configuration and client initialization to support custom CDN clients, and enhance theActivityAddCommentRequestmodel to better support attachment uploads.CDN Client Integration and File Management:
CdnClientinterface and a defaultFeedsCdnClientimplementation for handling file and image uploads and deletions, with progress tracking and cancellation support. This includes new methods foruploadFile,uploadImage,deleteFile, anddeleteImagein both the API and client layers. [1] [2] [3] [4]StreamFeedsClientImpl) to initialize and expose the CDN client and attachment uploader, and to delegate file/image deletion to the CDN client. [1] [2] [3] [4]Configuration and Extensibility:
FeedsConfigmodel to allow injection of a customCdnClient, enabling flexible CDN integration. [1] [2]Attachment Uploads in Comments:
ActivityAddCommentRequestmodel to include fields foractivityId,activityType, and a list ofStreamAttachmentuploads, improving support for adding comments with file/image attachments. The corresponding mapper and generated code were updated accordingly. [1] [2] [3] [4] [5] [6] [7] [8]API and Internal Refactoring:
sendFile→uploadFile), add progress/cancellation parameters, and support new response types for image uploads and deletions. [1] [2] [3] [4] [5] [6]These changes collectively make file and image management more robust and extensible, and improve the developer experience when working with attachments in comments.