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

Boost Action : Share Link #2536

Merged
merged 7 commits into from
Jan 31, 2025
Merged
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
1 change: 1 addition & 0 deletions .changes/2536-add-link-action-boost.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- [New] : Now you can also add link with Boost Actions.
12 changes: 0 additions & 12 deletions app/lib/features/news/model/news_references_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,3 @@ String _toCamelCase(String s) {
words[0] = words[0].toLowerCase();
return words.join();
}

class NewsReferencesModel {
NewsReferencesType type;
String? id;
String? title;

NewsReferencesModel({
required this.type,
this.title,
this.id,
});
}
5 changes: 5 additions & 0 deletions app/lib/features/news/pages/add_news_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,11 @@ class AddNewsState extends ConsumerState<AddNewsPage> {
final notifier = ref.read(newsStateProvider.notifier);
await notifier.selectTaskListToShare(buildContext);
},
onShareLinkSelected: () async {
Navigator.pop(context);
final notifier = ref.read(newsStateProvider.notifier);
await notifier.enterLinkToShare(buildContext);
},
),
);
},
Expand Down
18 changes: 18 additions & 0 deletions app/lib/features/news/providers/news_post_editor_providers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ import 'package:acter/common/widgets/event/event_selector_drawer.dart';
import 'package:acter/common/widgets/pin/pin_selector_drawer.dart';
import 'package:acter/common/widgets/spaces/space_selector_drawer.dart';
import 'package:acter/common/widgets/task/taskList_selector_drawer.dart';
import 'package:acter/features/attachments/actions/add_edit_link_bottom_sheet.dart';
import 'package:acter/features/events/providers/event_providers.dart';
import 'package:acter/features/home/providers/client_providers.dart';
import 'package:acter/features/news/model/news_post_color_data.dart';
import 'package:acter/features/news/model/news_post_state.dart';
import 'package:acter/features/news/model/news_slide_model.dart';
import 'package:acter/features/pins/providers/pins_provider.dart';
import 'package:acter/features/tasks/providers/tasklists_providers.dart';
import 'package:acter_flutter_sdk/acter_flutter_sdk_ffi.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:riverpod/riverpod.dart';

final newsStateProvider =
Expand Down Expand Up @@ -86,6 +89,21 @@ class NewsStateNotifier extends StateNotifier<NewsPostState> {
selectedNewsSlide?.refDetails = refDetails;
state = state.copyWith(currentNewsSlide: selectedNewsSlide);
}
Future<void> enterLinkToShare(BuildContext context) async {
showAddEditLinkBottomSheet(
context: context,
bottomSheetTitle: L10n.of(context).addLink,
onSave: (title, link) async {
Navigator.pop(context);
final client = await ref.read(alwaysClientProvider.future);
RefDetails refDetails = client.newLinkRefDetails(title, link);
NewsSlideItem? selectedNewsSlide = state.currentNewsSlide;
selectedNewsSlide?.refDetails = refDetails;
state = state.copyWith(currentNewsSlide: selectedNewsSlide);
},
);

}

void changeTextSlideValue(String body, String? html) {
state.currentNewsSlide?.text = body;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,12 @@ class NewsSlideActions extends ConsumerWidget {
title,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: textTheme.labelMedium,
),
subtitle: Text(
uri,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: textTheme.labelSmall,
),
),
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ class SelectActionItem extends StatelessWidget {
final VoidCallback onShareEventSelected;
final VoidCallback onSharePinSelected;
final VoidCallback onShareTaskListSelected;
final VoidCallback onShareLinkSelected;

const SelectActionItem({
super.key,
required this.onShareEventSelected,
required this.onSharePinSelected,
required this.onShareTaskListSelected,
required this.onShareLinkSelected,
});

@override
Expand All @@ -38,10 +40,16 @@ class SelectActionItem extends StatelessWidget {
context: context,
actionIcon: Atlas.list,
actionName: L10n.of(context).shareTaskList,

onTap: onShareTaskListSelected,
),
const SizedBox(height: 20),
actionItemUI(
context: context,
actionIcon: Atlas.link,
actionName: L10n.of(context).shareLink,
onTap: onShareLinkSelected,
),
const SizedBox(height: 20),
],
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:acter/common/actions/open_link.dart';
import 'package:acter/features/events/providers/event_providers.dart';
import 'package:acter/features/events/widgets/event_item.dart';
import 'package:acter/features/events/widgets/skeletons/event_item_skeleton_widget.dart';
Expand All @@ -8,6 +9,7 @@ import 'package:acter/features/tasks/providers/tasklists_providers.dart';
import 'package:acter/features/tasks/widgets/skeleton/tasks_list_skeleton.dart';
import 'package:acter/features/tasks/widgets/task_list_item_card.dart';
import 'package:acter_flutter_sdk/acter_flutter_sdk_ffi.dart';
import 'package:atlas_icons/atlas_icons.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
Expand All @@ -26,20 +28,25 @@ class SelectedActionButton extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
if (refDetails == null) return SizedBox();
final refObjectId = refDetails!.targetIdStr();
final refObjectType = refDetails!.typeStr();
if (refObjectId == null) return SizedBox();

return switch (refObjectType) {
'pin' => pinActionButton(context, ref, refObjectId),
'calendar-event' => calendarActionButton(context, ref, refObjectId),
'task-list' => taskListActionButton(context, ref, refObjectId),
'pin' => pinActionButton(context, ref, refDetails!),
'calendar-event' => calendarActionButton(context, ref, refDetails!),
'task-list' => taskListActionButton(context, ref, refDetails!),
'link' => linkActionButton(context, refDetails!),
_ => const SizedBox(),
};
}

Widget calendarActionButton(BuildContext context, WidgetRef ref, String id) {
return ref.watch(calendarEventProvider(id)).when(
Widget calendarActionButton(
BuildContext context,
WidgetRef ref,
RefDetails refDetail,
) {
final refObjectId = refDetails!.targetIdStr();
if (refObjectId == null) return SizedBox();
return ref.watch(calendarEventProvider(refObjectId)).when(
data: (calendarEvent) {
return SizedBox(
width: 300,
Expand All @@ -66,8 +73,14 @@ class SelectedActionButton extends ConsumerWidget {
);
}

Widget pinActionButton(BuildContext context, WidgetRef ref, String id) {
return ref.watch(pinProvider(id)).when(
Widget pinActionButton(
BuildContext context,
WidgetRef ref,
RefDetails refDetail,
) {
final refObjectId = refDetails!.targetIdStr();
if (refObjectId == null) return SizedBox();
return ref.watch(pinProvider(refObjectId)).when(
data: (pin) {
return SizedBox(
width: 300,
Expand All @@ -94,8 +107,14 @@ class SelectedActionButton extends ConsumerWidget {
);
}

Widget taskListActionButton(BuildContext context, WidgetRef ref, String id) {
return ref.watch(taskListProvider(id)).when(
Widget taskListActionButton(
BuildContext context,
WidgetRef ref,
RefDetails refDetail,
) {
final refObjectId = refDetails!.targetIdStr();
if (refObjectId == null) return SizedBox();
return ref.watch(taskListProvider(refObjectId)).when(
data: (taskList) {
return SizedBox(
width: 300,
Expand Down Expand Up @@ -123,4 +142,29 @@ class SelectedActionButton extends ConsumerWidget {
},
);
}

Widget linkActionButton(BuildContext context, RefDetails refDetail) {
final uri = refDetail.uri();
if (uri == null) return SizedBox.shrink();
return SizedBox(
width: 300,
child: Card(
child: ListTile(
leading: const Icon(Atlas.link),
onTap: () => openLink(uri, context),
title: Text(
refDetail.title() ?? L10n.of(context).unknown,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
subtitle: Text(
uri,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.labelSmall,
),
),
),
);
}
}
1 change: 1 addition & 0 deletions app/lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -2327,5 +2327,6 @@
"removeReference": "Remove Reference",
"removeReferenceConfirmation": "Are you sure you want to remove this reference?",
"noObjectAccess": "You are not part of {spaceName} so you can't access this {objectType}",
"shareLink": "Share link",
"@addComment": {}
}
6 changes: 5 additions & 1 deletion native/acter/api.rsh
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ fn new_display_builder() -> DisplayBuilder;
/// position: top-left/top-middle/top-right/center-left/center-middle/center-right/bottom-left/bottom-middle/bottom-right
fn new_obj_ref_builder(position: Option<string>, reference: RefDetails) -> Result<ObjRefBuilder>;


// ######## ######## #### ## ## #### ######## #### ## ## ######## ######
// ## ## ## ## ## ### ### ## ## ## ## ## ## ## ##
// ## ## ## ## ## #### #### ## ## ## ## ## ## ##
Expand Down Expand Up @@ -3119,6 +3118,11 @@ object Client {

/// Room preview
fn room_preview(room_id_or_alias: string, server_names: VecStringBuilder) -> Future<Result<RoomPreview>>;


/// create a link ref details
fn new_link_ref_details(title: string, uri: string) -> Result<RefDetails>;

}

object NotificationSettings {
Expand Down
2 changes: 1 addition & 1 deletion native/acter/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ pub use convo::{
new_convo_settings_builder, Convo, ConvoDiff, CreateConvoSettings, CreateConvoSettingsBuilder,
};
pub use core::time::Duration as EfkDuration;
pub use deep_linking::{ObjRef, RefDetails};
pub use deep_linking::{new_link_ref_details, ObjRef, RefDetails};
pub use device::DeviceEvent;
pub use invitation::Invitation;
pub use message::{EventSendState, RoomEventItem, RoomMessage, RoomVirtualItem};
Expand Down
13 changes: 13 additions & 0 deletions native/acter/src/api/deep_linking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,19 @@
}
}

pub fn new_link_ref_details(title: String, uri: String) -> Result<CoreRefDetails> {
Ok(CoreRefDetails::Link { title, uri })
}
impl Client {
/// create a link ref details
pub fn new_link_ref_details(&self, title: String, uri: String) -> Result<RefDetails> {
Ok(RefDetails::new(
self.clone(),
new_link_ref_details(title, uri)?,

Check warning on line 56 in native/acter/src/api/deep_linking.rs

View check run for this annotation

Codecov / codecov/patch

native/acter/src/api/deep_linking.rs#L53-L56

Added lines #L53 - L56 were not covered by tests
))
}

Check warning on line 58 in native/acter/src/api/deep_linking.rs

View check run for this annotation

Codecov / codecov/patch

native/acter/src/api/deep_linking.rs#L58

Added line #L58 was not covered by tests
}

fn generate_object_link(
room_id: &OwnedRoomId,
path: &[(&str, &OwnedEventId)],
Expand Down
1 change: 1 addition & 0 deletions native/test/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ mod pins;
mod push;
mod reaction;
mod redact;
mod ref_details;
mod reply;
mod rsvp;
mod spaces;
Expand Down
26 changes: 26 additions & 0 deletions native/test/src/tests/ref_details.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/// testing the ref details API
use anyhow::Result;

use acter::api::new_link_ref_details;

#[test]
fn test_ref_details_for_link_smoketest() -> Result<()> {
let ref_details = new_link_ref_details(
"Link Title".to_owned(),
"mxc://acter.global/test".to_owned(),
)?;
assert_eq!(ref_details.type_str().as_str(), "link");
assert_eq!(ref_details.title().unwrap().as_str(), "Link Title");
assert_eq!(
ref_details.uri().unwrap().as_str(),
"mxc://acter.global/test"
);

// second one for good measure
let ref_details =
new_link_ref_details("Smoketest".to_owned(), "https://matrix.org".to_owned())?;
assert_eq!(ref_details.type_str().as_str(), "link");
assert_eq!(ref_details.title().unwrap().as_str(), "Smoketest");
assert_eq!(ref_details.uri().unwrap().as_str(), "https://matrix.org");
Ok(())
}
Loading