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

feat: added notifications guide #1379

Merged
merged 20 commits into from
Aug 28, 2023
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
10 changes: 5 additions & 5 deletions src/components/PluginBreadcrumb.astro
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ interface Props {
cratesio?: string;
jsApi?: string;
rustApi?: string;
docsio?: string;
docsrs?: string;
}
const { version, github, npm, cratesio, jsApi, rustApi, docsio } = Astro.props;
const hasApiLinks = jsApi || rustApi || docsio;
const { version, github, npm, cratesio, jsApi, rustApi, docsrs } = Astro.props;
const hasApiLinks = jsApi || rustApi || docsrs;
---

<div class="flex row not-content">
Expand Down Expand Up @@ -60,8 +60,8 @@ const hasApiLinks = jsApi || rustApi || docsio;
</svg>
</a>
)}
{docsio && (
<a href={docsio} class="flex" target="_blank" aria-label="Docs.io API Reference">
{docsrs && (
<a href={docsrs} class="flex" target="_blank" aria-label="Docs.io API Reference">
<svg viewBox="0 0 512 512" fill="currentColor">
<path d="M488.6 250.2L392 214V105.5c0-15-9.3-28.4-23.4-33.7l-100-37.5c-8.1-3.1-17.1-3.1-25.3 0l-100 37.5c-14.1 5.3-23.4 18.7-23.4 33.7V214l-96.6 36.2C9.3 255.5 0 268.9 0 283.9V394c0 13.6 7.7 26.1 19.9 32.2l100 50c10.1 5.1 22.1 5.1 32.2 0l103.9-52 103.9 52c10.1 5.1 22.1 5.1 32.2 0l100-50c12.2-6.1 19.9-18.6 19.9-32.2V283.9c0-15-9.3-28.4-23.4-33.7zM358 214.8l-85 31.9v-68.2l85-37v73.3zM154 104.1l102-38.2 102 38.2v.6l-102 41.4-102-41.4v-.6zm84 291.1l-85 42.5v-79.1l85-38.8v75.4zm0-112l-102 41.4-102-41.4v-.6l102-38.2 102 38.2v.6zm240 112l-85 42.5v-79.1l85-38.8v75.4zm0-112l-102 41.4-102-41.4v-.6l102-38.2 102 38.2v.6z" />
</svg>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Stub.astro
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const baseUrl = 'https://github.com/tauri-apps/tauri-docs/tree/next';

<Card title="Contribute" icon="pencil">
<p>
This page is a stub and is waiting for contributions. Get involved by
This is a stub and is waiting for contributions. Get involved by
<a href={baseUrl}>visiting us on GitHub</a> or <a href="https://discord.com/invite/tauri"
>joining us on Discord</a
>.
Expand Down
160 changes: 155 additions & 5 deletions src/content/docs/2/guide/notification.mdx
Original file line number Diff line number Diff line change
@@ -1,10 +1,160 @@
---
title: Notification
title: Notifications
description: Send native notifications to the user.
---

import PluginBreadcrumb from '@components/PluginBreadcrumb.astro';
import { Tabs, TabItem } from '@astrojs/starlight/components';
import CommandTabs from '@components/CommandTabs.astro';
import Stub from '@components/Stub.astro';

<Stub>
Based on
https://github.com/tauri-apps/plugins-workspace/tree/v2/plugins/notification
</Stub>
<PluginBreadcrumb
version="v2.0.0-alpha.2"
github="https://github.com/tauri-apps/plugins-workspace/tree/v2/plugins/notification"
npm="https://www.npmjs.com/package/@tauri-apps/plugin-notification"
cratesio="https://crates.io/crates/tauri-plugin-notification"
jsApi="/2/reference/js/notification"
docsrs="https://docs.rs/tauri-plugin-notification/2.0.0-alpha.2/tauri_plugin_notification/"
/>

Send native notifications to your user using the notification plugin.

## Setup

Install the notifications plugin to get started.

<Tabs>
<TabItem label="Automatic">

1. Use your project's package manager to add the dependency:

<CommandTabs npm="npm run tauri plugin add notification"
yarn="yarn run tauri plugin add notification"
pnpm="pnpm tauri plugin add notification"
cargo="cargo tauri plugin add notification" />

2. Modify `lib.rs` to initialize the plugin:

{/* TODO: Revise once https://github.com/tauri-apps/tauri/issues/7696 is in */}

```rust
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
// Initialize the plugin
.plugin(tauri_plugin_notification::init())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
```

</TabItem>
<TabItem label="Manual">

1. Run `cargo add tauri-plugin-notification` to add the plugin to the project's dependencies in `Cargo.toml`.

2. Modify `lib.rs` to initialize the plugin:

```rust
// lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
// Initialize the plugin
.plugin(tauri_plugin_notification::init())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
```

3. If you'd like to use notifications in JavaScript then install the npm package as well:

<CommandTabs
Copy link
Member

Choose a reason for hiding this comment

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

I fully realise this goes against my own UX principals so feel free to rake me across the coals if you don't think it works here @simonhyll 😅

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I should screenshot this and post on the Astro server 😂

It certainly makes more sense to do it like that if you structure things without the separated Frontend and Backend sections. As I see it it's not actually nested tabs, it's just the ability to switch which package manager you wanna use

Speaking of choosing your package manager, what if when the user switches tabs we save that to LocalStorage so all CommandTabs default to the last one they picked?

Copy link
Member

Choose a reason for hiding this comment

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

I should screenshot this and post on the Astro server 😂

Please do, I'm sure Chris would get a kick out of it 😆

Speaking of choosing your package manager, what if when the user switches tabs we save that to LocalStorage so all CommandTabs default to the last one they picked?

I believe that's what they've discussed in withastro/starlight#462. If you get bored and want to dive into Starlight land I'm sure HiDeoo would love to have a contribution based on his issue.

npm="npm install @tauri-apps/plugin-notification"
yarn="yarn add @tauri-apps/plugin-notification"
pnpm="pnpm add @tauri-apps/plugin-notification"
/>

</TabItem>

</Tabs>

## Usage

Here are a few examples of how to use the notification plugin:

- [Sent notification to users](#send-notification)
- [Add an action to a notification](#actions)
- [Add an attachment to a notification](#attachments)
- [Send a notification in a specific channel](#channels)

{/* TODO: Link to which language to use, frontend vs. backend guide when it's made */}

The notification plugin is available in both JavaScript and Rust.

### Send Notification

{/* TODO: Demo component */}

Follow these steps to send a notification:

1. Check if permission is granted
2. Request permission if not granted
3. Send the notification

<Tabs>
<TabItem label="JavaScript">

```js
import {
isPermissionGranted,
requestPermission,
sendNotification,
} from '@tauri-apps/plugin-notification';

// Do you have permission to send a notification?
let permissionGranted = await isPermissionGranted();

// If not we need to request it
if (!permissionGranted) {
const permission = await requestPermission();
permissionGranted = permission === 'granted';
}

// Once permission has been granted we can send the notification
if (permissionGranted) {
sendNotification({ title: 'Tauri', body: 'Tauri is awesome!' });
}
```

</TabItem>
<TabItem label="Rust">

{/* TODO: */}

<Stub />

</TabItem>
</Tabs>

### Actions
Copy link
Member

Choose a reason for hiding this comment

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

@simonhyll what do you think about this sort of structure? I think this could go a really long way to give link-able places for support

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I would put Security Considerations further down, feels like the sort of more in-depth topic you read about later on in a post

Not sure what Actions, Attachments or Channels are for? Is it to explain notification concepts or are they general sections that all recipes could have? Options I assume is just a simplified version of what you'd find in the actual API. As long as they aren't too wordy and are copy-paste friendly I'm probably fine with them.

I'm still not overly fond of the terminology of Javascript vs Rust since we should really also have the Rust version avilable using something like Jonas' tauri-sys crate so that the Rust frameworks also get included, because with just JS and Rust (backend) we're kinda leaving them hanging, and I don't see a nice way of adding them without ending up with really annoying names. I'd prefer it if we write about Frontend and Backend as core concepts of Tauri and if people skipped that part then it's not really our problem they refused to read what is almost literally called "the only stuff that's non-optional for you to skip reading". I could also accept Javascript, Rust and Backend I guess because then all frontend languages get included plus one for the backend, but even that isn't completely future proof since we have plans for language bindings at some point.

In the end I defer to your wisdom on the docs in general, so feel free to overrule me on basically anything 😅

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note that I read your comments from the bottom to the top and just saw your comment earlier explaining what you meant with Actions, Attachments etc. I'm tired, brain no work 😅

Copy link
Member

Choose a reason for hiding this comment

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

Open to whatever you feel would be best for security considerations. I figured if there was anything in-depth that would link out either externally or to a concept and maybe not include it in the guide (unless it really is only very specific to that guide/feature).

Actions, Attachment, Channels, and Options are part of the plugins APIs, so really just more copy-pasteable examples:

RE: Frontend/backend/rust/js how about we put some data-driven decisions in practice and make a poll we can post to Twitter, Discord, and Mastodon and see what comes out?

I'm still not overly fond of the terminology of Javascript vs Rust since we should really also have the Rust version avilable using something like Jonas' tauri-sys crate so that the Rust frameworks also get included, because with just JS and Rust (backend) we're kinda leaving them hanging, and I don't see a nice way of adding them without ending up with really annoying names.

Literally have never heard of that until today (looks cool!): https://github.com/JonasKruckenberg/tauri-sys. I do wonder if this is really a more advanced-level usage that's outside of the target audience (i.e. beginners) for docs?


A piece that maybe just fell in place for me: do you not like "Rust" because you can have both a Rust frontend (yew, sycamore, etc.) and a Rust backend (application logic, what you're truly referring to as backend) in the same app? Because if that's the case then it just clicked for me and your points are a lot more clear to me now.

Copy link
Member

Choose a reason for hiding this comment

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

Note that I read your comments from the bottom to the top and just saw your comment earlier explaining what you meant with Actions, Attachments etc. I'm tired, brain no work 😅

I mean we've only had like a million comments on this one poor PR the past few days 😅

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yea exactly, we want to support our buddies over at the Rust based frontend frameworks, so saying "rust" just for the backend isnt as inclusive

And tauri-sys I would say is the more beginner friendly option than the alternative if you develop using e.g. Yew Leptos or Sycamore. You dont even want to know what the alternative looks like, Jonas really did make aomething awesome and at some point we might wanna make it the actual official approach and "take over" his project. It's kind alike the official JS API but for Rust

Copy link
Member

Choose a reason for hiding this comment

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

Could you give some examples of how it's different to use the Rust API in Rust frontend code vs. Rust backend code? Might be better to do it outside of the context of notifications where it's a more practical example, but I think that context is what I'm missing.

Keep in mind that for now we're only covering how to do things with the first-party APIs (I don't think you were thinking of putting tauri-sys code in here, and let's talk about it if so, but just wanted to make sure).


I do wonder if "covering all the ways to consume the API" is a similar rabbit hole we got into with "cover all the different JS frontend frameworks"? And if we're wanting to say "here's how you do it in x, then here's a common guide on using Tauri within the context of that". But I doubt we want to NEED to document all of these combinations in every single feature/guide 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Even if we dont do tauri-sys specifically skipping Rust entirely will leave our beloved rustaceans behind. Using tauri-sys isnt quite the same thing as the framework rabbit hole imo, but if we skip it we should at least offer a "vanilla Rust" example same as we do with vanilla JS

Copy link
Member

Choose a reason for hiding this comment

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

I agree, but we need the dev team to either do that upstream if it doesn't already, or they need to provide the docs and examples to help us write the guides for it. Right now I didn't find any examples for the Rust side of things to be able to fill it out.


{/* TODO: */}

<Stub />

### Attachments

{/* TODO: */}

<Stub />

### Channels

{/* TODO: */}

<Stub />

## Security Considerations

Aside from normal sanitization procedures of user input there are currently no known security considerations.