mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: open the duplicated space by default (#5638)
This commit is contained in:
parent
ecc5555a4e
commit
605a53f2ae
@ -297,12 +297,11 @@ class SpaceBloc extends Bloc<SpaceEvent, SpaceState> {
|
|||||||
if (currentSpace == null) {
|
if (currentSpace == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await ViewBackendService.duplicate(
|
final newSpace = await _duplicateSpace(currentSpace);
|
||||||
view: currentSpace,
|
// open the duplicated space
|
||||||
openAfterDuplicate: false,
|
if (newSpace != null) {
|
||||||
includeChildren: true,
|
add(SpaceEvent.open(newSpace));
|
||||||
);
|
}
|
||||||
add(const SpaceEvent.didReceiveSpaceUpdate());
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -602,6 +601,40 @@ class SpaceBloc extends Bloc<SpaceEvent, SpaceState> {
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<ViewPB?> _duplicateSpace(ViewPB space) async {
|
||||||
|
// if the space is not duplicated, try to create a new space
|
||||||
|
final icon = space.icon.value.isNotEmpty
|
||||||
|
? space.icon.value
|
||||||
|
: builtInSpaceIcons.first;
|
||||||
|
final iconColor = space.spaceIconColor ?? builtInSpaceColors.first;
|
||||||
|
final newSpace = await _createSpace(
|
||||||
|
name: '${space.name} (copy)',
|
||||||
|
icon: icon,
|
||||||
|
iconColor: iconColor,
|
||||||
|
permission: space.spacePermission,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (newSpace == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final view in space.childViews) {
|
||||||
|
unawaited(
|
||||||
|
ViewBackendService.duplicate(
|
||||||
|
view: view,
|
||||||
|
openAfterDuplicate: true,
|
||||||
|
includeChildren: true,
|
||||||
|
parentViewId: newSpace.id,
|
||||||
|
suffix: '',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.info('Space duplicated: $newSpace');
|
||||||
|
add(const SpaceEvent.didReceiveSpaceUpdate());
|
||||||
|
return newSpace;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
|
@ -141,11 +141,22 @@ class ViewBackendService {
|
|||||||
required bool openAfterDuplicate,
|
required bool openAfterDuplicate,
|
||||||
// should include children views
|
// should include children views
|
||||||
required bool includeChildren,
|
required bool includeChildren,
|
||||||
|
String? parentViewId,
|
||||||
|
String? suffix,
|
||||||
}) {
|
}) {
|
||||||
final payload = DuplicateViewPayloadPB.create()
|
final payload = DuplicateViewPayloadPB.create()
|
||||||
..viewId = view.id
|
..viewId = view.id
|
||||||
..openAfterDuplicate = openAfterDuplicate
|
..openAfterDuplicate = openAfterDuplicate
|
||||||
..includeChildren = includeChildren;
|
..includeChildren = includeChildren;
|
||||||
|
|
||||||
|
if (parentViewId != null) {
|
||||||
|
payload.parentViewId = parentViewId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (suffix != null) {
|
||||||
|
payload.suffix = suffix;
|
||||||
|
}
|
||||||
|
|
||||||
return FolderEventDuplicateView(payload).send();
|
return FolderEventDuplicateView(payload).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,6 +584,16 @@ pub struct DuplicateViewPayloadPB {
|
|||||||
|
|
||||||
#[pb(index = 3)]
|
#[pb(index = 3)]
|
||||||
pub include_children: bool,
|
pub include_children: bool,
|
||||||
|
|
||||||
|
// duplicate the view to the specified parent view.
|
||||||
|
// if the parent_view_id is None, the view will be duplicated to the same parent view.
|
||||||
|
#[pb(index = 4, one_of)]
|
||||||
|
pub parent_view_id: Option<String>,
|
||||||
|
|
||||||
|
// The suffix of the duplicated view name.
|
||||||
|
// If the suffix is None, the duplicated view will have the same name with (copy) suffix.
|
||||||
|
#[pb(index = 5, one_of)]
|
||||||
|
pub suffix: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -593,6 +603,10 @@ pub struct DuplicateViewParams {
|
|||||||
pub open_after_duplicate: bool,
|
pub open_after_duplicate: bool,
|
||||||
|
|
||||||
pub include_children: bool,
|
pub include_children: bool,
|
||||||
|
|
||||||
|
pub parent_view_id: Option<String>,
|
||||||
|
|
||||||
|
pub suffix: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryInto<DuplicateViewParams> for DuplicateViewPayloadPB {
|
impl TryInto<DuplicateViewParams> for DuplicateViewPayloadPB {
|
||||||
@ -604,6 +618,8 @@ impl TryInto<DuplicateViewParams> for DuplicateViewPayloadPB {
|
|||||||
view_id,
|
view_id,
|
||||||
open_after_duplicate: self.open_after_duplicate,
|
open_after_duplicate: self.open_after_duplicate,
|
||||||
include_children: self.include_children,
|
include_children: self.include_children,
|
||||||
|
parent_view_id: self.parent_view_id,
|
||||||
|
suffix: self.suffix,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -741,12 +741,17 @@ impl FolderManager {
|
|||||||
let view = self
|
let view = self
|
||||||
.with_folder(|| None, |folder| folder.views.get_view(¶ms.view_id))
|
.with_folder(|| None, |folder| folder.views.get_view(¶ms.view_id))
|
||||||
.ok_or_else(|| FlowyError::record_not_found().with_context("Can't duplicate the view"))?;
|
.ok_or_else(|| FlowyError::record_not_found().with_context("Can't duplicate the view"))?;
|
||||||
|
let parent_view_id = params
|
||||||
|
.parent_view_id
|
||||||
|
.clone()
|
||||||
|
.unwrap_or(view.parent_view_id.clone());
|
||||||
self
|
self
|
||||||
.duplicate_view_with_parent_id(
|
.duplicate_view_with_parent_id(
|
||||||
&view.id,
|
&view.id,
|
||||||
&view.parent_view_id,
|
&parent_view_id,
|
||||||
params.open_after_duplicate,
|
params.open_after_duplicate,
|
||||||
params.include_children,
|
params.include_children,
|
||||||
|
params.suffix,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
@ -761,6 +766,7 @@ impl FolderManager {
|
|||||||
parent_view_id: &str,
|
parent_view_id: &str,
|
||||||
open_after_duplicated: bool,
|
open_after_duplicated: bool,
|
||||||
include_children: bool,
|
include_children: bool,
|
||||||
|
suffix: Option<String>,
|
||||||
) -> Result<(), FlowyError> {
|
) -> Result<(), FlowyError> {
|
||||||
if view_id == parent_view_id {
|
if view_id == parent_view_id {
|
||||||
return Err(FlowyError::new(
|
return Err(FlowyError::new(
|
||||||
@ -777,6 +783,7 @@ impl FolderManager {
|
|||||||
let mut is_source_view = true;
|
let mut is_source_view = true;
|
||||||
// use a stack to duplicate the view and its children
|
// use a stack to duplicate the view and its children
|
||||||
let mut stack = vec![(view_id.to_string(), parent_view_id.to_string())];
|
let mut stack = vec![(view_id.to_string(), parent_view_id.to_string())];
|
||||||
|
let suffix = suffix.unwrap_or(" (copy)".to_string());
|
||||||
|
|
||||||
while let Some((current_view_id, current_parent_id)) = stack.pop() {
|
while let Some((current_view_id, current_parent_id)) = stack.pop() {
|
||||||
let view = self
|
let view = self
|
||||||
@ -812,7 +819,7 @@ impl FolderManager {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let name = if is_source_view {
|
let name = if is_source_view {
|
||||||
format!("{} (copy)", &view.name)
|
format!("{}{}", &view.name, suffix)
|
||||||
} else {
|
} else {
|
||||||
view.name.clone()
|
view.name.clone()
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user