Skip to content

Commit f7c0600

Browse files
feat: add open button to launch installed extension (#1013)
* chore: up * support query string main_extension_id * chore: up * fix tests * open non-group/extension extensions * dbg * chore: upadate * extension SearchSource now accepts empty querystring * update * chore: open * chore: input * remove DBG statements * chore: icon * style: adjust styles * docs: update release notes --------- Co-authored-by: Steve Lau <stevelauc@outlook.com>
1 parent ed8a1cb commit f7c0600

16 files changed

Lines changed: 496 additions & 221 deletions

File tree

docs/content.en/docs/release-notes/_index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ Information about release notes of Coco App is provided here.
1313

1414
### 🚀 Features
1515

16+
- feat: add open button to launch installed extension #1013
17+
1618
### 🐛 Bug fix
1719

1820
- fix: fix the abnormal input height issue #1006

src-tauri/src/extension/mod.rs

Lines changed: 106 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -218,113 +218,118 @@ impl<'ext> PartialEq<ExtensionBundleId> for ExtensionBundleIdBorrowed<'ext> {
218218
}
219219
}
220220

221-
impl Extension {
222-
/// Whether this extension could be searched.
223-
pub(crate) fn searchable(&self) -> bool {
224-
self.on_opened().is_some()
225-
}
221+
#[tauri::command]
222+
pub(crate) fn extension_on_opened(extension: Extension) -> Option<OnOpened> {
223+
_extension_on_opened(&extension)
224+
}
226225

227-
/// Return what will happen when we open this extension.
228-
///
229-
/// `None` if it cannot be opened.
230-
pub(crate) fn on_opened(&self) -> Option<OnOpened> {
231-
let settings = self.settings.clone();
232-
let permission = self.permission.clone();
233-
234-
match self.r#type {
235-
// This function, at the time of writing this comment, is primarily
236-
// used by third-party extensions.
226+
/// Return what will happen when we open this extension.
227+
///
228+
/// `None` if it cannot be opened.
229+
pub(crate) fn _extension_on_opened(extension: &Extension) -> Option<OnOpened> {
230+
let settings = extension.settings.clone();
231+
let permission = extension.permission.clone();
232+
233+
match extension.r#type {
234+
// This function, at the time of writing this comment, is primarily
235+
// used by third-party extensions.
236+
//
237+
// Built-in extensions don't use this as they are technically not
238+
// "struct Extension"s. Typically, they directly construct a
239+
// "struct Document" from their own type.
240+
ExtensionType::Calculator => unreachable!("this is handled by frontend"),
241+
ExtensionType::AiExtension => unreachable!(
242+
"currently, all AI extensions we have are non-searchable, so we won't open them"
243+
),
244+
ExtensionType::Application => {
245+
// We can have a impl like:
237246
//
238-
// Built-in extensions don't use this as they are technically not
239-
// "struct Extension"s. Typically, they directly construct a
240-
// "struct Document" from their own type.
241-
ExtensionType::Calculator => unreachable!("this is handled by frontend"),
242-
ExtensionType::AiExtension => unreachable!(
243-
"currently, all AI extensions we have are non-searchable, so we won't open them"
244-
),
245-
ExtensionType::Application => {
246-
// We can have a impl like:
247-
//
248-
// Some(OnOpened::Application { app_path: self.id.clone() })
249-
//
250-
// but it won't be used.
251-
252-
unreachable!(
253-
"Applications are not \"struct Extension\" under the hood, they won't call this method"
247+
// Some(OnOpened::Application { app_path: self.id.clone() })
248+
//
249+
// but it won't be used.
250+
251+
unreachable!(
252+
"Applications are not \"struct Extension\" under the hood, they won't call this method"
253+
)
254+
}
255+
256+
// These 2 types of extensions cannot be opened
257+
ExtensionType::Group => return None,
258+
ExtensionType::Extension => return None,
259+
260+
ExtensionType::Command => {
261+
let ty = ExtensionOnOpenedType::Command {
262+
action: extension.action.clone().unwrap_or_else(|| {
263+
panic!(
264+
"Command extension [{}]'s [action] field is not set, something wrong with your extension validity check", extension.id
254265
)
255-
}
266+
}),
267+
};
256268

257-
// These 2 types of extensions cannot be opened
258-
ExtensionType::Group => return None,
259-
ExtensionType::Extension => return None,
260-
261-
ExtensionType::Command => {
262-
let ty = ExtensionOnOpenedType::Command {
263-
action: self.action.clone().unwrap_or_else(|| {
264-
panic!(
265-
"Command extension [{}]'s [action] field is not set, something wrong with your extension validity check", self.id
266-
)
267-
}),
268-
};
269-
270-
let extension_on_opened = ExtensionOnOpened {
271-
ty,
272-
settings,
273-
permission,
274-
};
275-
276-
Some(OnOpened::Extension(extension_on_opened))
277-
}
278-
ExtensionType::Quicklink => {
279-
let quicklink = self.quicklink.clone().unwrap_or_else(|| {
280-
panic!(
281-
"Quicklink extension [{}]'s [quicklink] field is not set, something wrong with your extension validity check", self.id
282-
)
283-
});
284-
285-
let ty = ExtensionOnOpenedType::Quicklink {
286-
link: quicklink.link,
287-
open_with: quicklink.open_with,
288-
};
289-
290-
let extension_on_opened = ExtensionOnOpened {
291-
ty,
292-
settings,
293-
permission,
294-
};
295-
296-
Some(OnOpened::Extension(extension_on_opened))
297-
}
298-
ExtensionType::Script => todo!("not supported yet"),
299-
ExtensionType::Setting => todo!("not supported yet"),
300-
ExtensionType::View => {
301-
let name = self.name.clone();
302-
let icon = self.icon.clone();
303-
let page = self.page.as_ref().unwrap_or_else(|| {
304-
panic!("View extension [{}]'s [page] field is not set, something wrong with your extension validity check", self.id);
305-
}).clone();
306-
let ui = self.ui.clone();
307-
308-
let extension_on_opened_type = ExtensionOnOpenedType::View {
309-
name,
310-
icon,
311-
page,
312-
ui,
313-
};
314-
let extension_on_opened = ExtensionOnOpened {
315-
ty: extension_on_opened_type,
316-
settings,
317-
permission,
318-
};
319-
let on_opened = OnOpened::Extension(extension_on_opened);
320-
321-
Some(on_opened)
322-
}
323-
ExtensionType::Unknown => {
324-
unreachable!("Extensions of type [Unknown] should never be opened")
325-
}
269+
let extension_on_opened = ExtensionOnOpened {
270+
ty,
271+
settings,
272+
permission,
273+
};
274+
275+
Some(OnOpened::Extension(extension_on_opened))
276+
}
277+
ExtensionType::Quicklink => {
278+
let quicklink = extension.quicklink.clone().unwrap_or_else(|| {
279+
panic!(
280+
"Quicklink extension [{}]'s [quicklink] field is not set, something wrong with your extension validity check", extension.id
281+
)
282+
});
283+
284+
let ty = ExtensionOnOpenedType::Quicklink {
285+
link: quicklink.link,
286+
open_with: quicklink.open_with,
287+
};
288+
289+
let extension_on_opened = ExtensionOnOpened {
290+
ty,
291+
settings,
292+
permission,
293+
};
294+
295+
Some(OnOpened::Extension(extension_on_opened))
296+
}
297+
ExtensionType::Script => todo!("not supported yet"),
298+
ExtensionType::Setting => todo!("not supported yet"),
299+
ExtensionType::View => {
300+
let name = extension.name.clone();
301+
let icon = extension.icon.clone();
302+
let page = extension.page.as_ref().unwrap_or_else(|| {
303+
panic!("View extension [{}]'s [page] field is not set, something wrong with your extension validity check", extension.id);
304+
}).clone();
305+
let ui = extension.ui.clone();
306+
307+
let extension_on_opened_type = ExtensionOnOpenedType::View {
308+
name,
309+
icon,
310+
page,
311+
ui,
312+
};
313+
let extension_on_opened = ExtensionOnOpened {
314+
ty: extension_on_opened_type,
315+
settings,
316+
permission,
317+
};
318+
let on_opened = OnOpened::Extension(extension_on_opened);
319+
320+
Some(on_opened)
321+
}
322+
ExtensionType::Unknown => {
323+
unreachable!("Extensions of type [Unknown] should never be opened")
326324
}
327325
}
326+
}
327+
328+
impl Extension {
329+
/// Whether this extension could be searched.
330+
pub(crate) fn searchable(&self) -> bool {
331+
_extension_on_opened(self).is_some()
332+
}
328333

329334
pub(crate) fn get_sub_extension(&self, sub_extension_id: &str) -> Option<&Self> {
330335
if !self.r#type.contains_sub_items() {

0 commit comments

Comments
 (0)