Skip to content

Commit b7b2ada

Browse files
committed
Bookmarks: enhance documentation clarity and i18n support
Fix unclear descriptions in text and sample code. Add file operation examples. Introduce i18n(zh-Hans) documentation.
1 parent a3660e2 commit b7b2ada

File tree

3 files changed

+474
-35
lines changed
  • docs/concepts/services/storage-provider
  • i18n
    • ru/docusaurus-plugin-content-docs/current/concepts/services/storage-provider
    • zh-Hans/docusaurus-plugin-content-docs/current/concepts/services/storage-provider

3 files changed

+474
-35
lines changed

docs/concepts/services/storage-provider/bookmarks.md

Lines changed: 80 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -56,27 +56,29 @@ private async Task SaveBookmarksAsync(Control control)
5656
{
5757
// Save the bookmarkId to a local file for later use.
5858
// ... (code to save bookmarkId)
59-
CurrentActiveBookmarkId = bookmarkId;
6059
}
6160
}
6261
```
6362

64-
You can use the `OpenFolderBookmarkAsync()` methods to open a bookmarked folder via a `bookmark ID`. This will return the bookmarked file or folder or null if the operating system denies the request.
63+
You can use the `OpenFolderBookmarkAsync()` methods to open a bookmarked folder via a `bookmark ID`. This will return the bookmarked folder or null if the operating system denies the request.
6564

6665
```csharp
6766
// Example usage
68-
private async Task LoadSelectedBookmarkAsync(Control control)
67+
private async Task LoadFolderByBookmarkAsync(Control control, string bookmarkId)
6968
{
70-
if (string.IsNullOrEmpty(SelectedBookmarkId)) return;
69+
if (string.IsNullOrEmpty(bookmarkId)) return;
7170

7271
var toplevel = TopLevel.GetTopLevel(control);
73-
var folder = await toplevel.StorageProvider.OpenFolderBookmarkAsync(SelectedBookmarkId);
74-
75-
if (folder != null)
72+
if (toplevel?.StorageProvider != null)
7673
{
77-
// Successfully opened the bookmarked folder.
78-
LastSelectedFolder = folder;
79-
SelectedFolder = folder.Path.LocalPath;
74+
var folder = await toplevel.StorageProvider.OpenFolderBookmarkAsync(bookmarkId);
75+
76+
if (folder != null)
77+
{
78+
// Successfully opened the bookmarked folder.
79+
// ... (code to save folder as a var)
80+
LastSelectedFolder = folder;
81+
}
8082
}
8183
}
8284
```
@@ -85,29 +87,83 @@ private async Task LoadSelectedBookmarkAsync(Control control)
8587

8688
```csharp
8789
// Example usage
88-
private async Task ReleaseBookmarkAsync(Control control)
90+
private async Task ReleaseBookmarkAsync(Control control, string bookmarkId)
8991
{
90-
if (!string.IsNullOrEmpty(SelectedBookmarkId))
92+
if (string.IsNullOrEmpty(bookmarkId)) return;
93+
94+
// First, try to release the OS bookmark.
95+
var toplevel = TopLevel.GetTopLevel(control);
96+
if (toplevel?.StorageProvider != null)
9197
{
92-
// First, try to release the OS bookmark.
93-
var toplevel = TopLevel.GetTopLevel(control);
94-
if (toplevel?.StorageProvider != null)
98+
var folder = await toplevel.StorageProvider.OpenFolderBookmarkAsync(bookmarkId);
99+
if (folder is IStorageBookmarkItem storageBookmark)
95100
{
96-
var folder = await toplevel.StorageProvider.OpenFolderBookmarkAsync(SelectedBookmarkId);
97-
if (folder is IStorageBookmarkItem storageBookmark)
98-
{
99-
await storageBookmark.ReleaseBookmarkAsync();
100-
storageBookmark.Dispose();
101-
}
101+
await storageBookmark.ReleaseBookmarkAsync();
102+
storageBookmark.Dispose();
102103
}
104+
}
103105

104-
// Then, remove the ID from local storage.
105-
// ... (code to remove bookmarkId from file)
106+
// Then, remove the ID from local storage.
107+
// ... (code to remove bookmarkId from file)
108+
109+
}
110+
```
111+
112+
113+
### Reading and Writing File Content from a Bookmark
114+
115+
`OpenFileBookmarkAsync()`: This method is used to open a bookmarked file from a stored `bookmark ID`. It will return the bookmarked file or null if the operating system denies the request.
116+
117+
118+
Once you retrieve a bookmarked file using `OpenFileBookmarkAsync()`, you can read its content with `OpenReadAsync()` or modify it with `OpenWriteAsync()`.
119+
120+
`OpenReadAsync()`: Opens a stream for read access to the bookmarked file.
121+
122+
```csharp
123+
// Example usage
124+
private async Task LoadFileByBookmarkAsync(Control control, string bookmarkId)
125+
{
126+
if (string.IsNullOrEmpty(bookmarkId)) return;
127+
var toplevel = TopLevel.GetTopLevel(control);
128+
if (toplevel?.StorageProvider != null)
129+
{
130+
IStorageFile bookmarkedFile = await toplevel.StorageProvider.OpenFileBookmarkAsync(bookmarkId);
131+
if (bookmarkedFile != null)
132+
{
133+
// Read bookmarkedFile content
134+
// ... (code to use a read stream)
135+
await using var readStream = await bookmarkedFile.OpenReadAsync();
136+
using var reader = new StreamReader(readStream, Encoding.UTF8);
137+
FileContent = await reader.ReadToEndAsync();
138+
}
139+
}
140+
}
141+
```
106142

143+
`OpenWriteAsync()`: Opens a stream for writing to the bookmarked file.
144+
145+
```csharp
146+
// Example usage
147+
private async Task SaveFileByBookmarkAsync(Control control, string bookmarkId)
148+
{
149+
if (string.IsNullOrEmpty(bookmarkId)) return;
150+
var toplevel = TopLevel.GetTopLevel(control);
151+
if (toplevel?.StorageProvider != null)
152+
{
153+
IStorageFile bookmarkedFile = await toplevel.StorageProvider.OpenFileBookmarkAsync(bookmarkId);
154+
if (bookmarkedFile != null)
155+
{
156+
// Write bookmarkedFile content
157+
// ... (code to use a write stream)
158+
await using var writeStream = await bookmarkedFile.OpenWriteAsync();
159+
await using var writer = new StreamWriter(writeStream, Encoding.UTF8);
160+
await writer.WriteAsync(FileContent);
161+
}
107162
}
108163
}
109164
```
110165

166+
111167
### Managing Bookmarked Files and Folders
112168
Once a bookmark is loaded, you can use the inherited methods from `IStorageItem` to manipulate the file or folder.
113169

@@ -164,7 +220,7 @@ The way a `bookmark ID` is represented can vary by platform:
164220

165221
**Windows**: A bookmark is a simple absolute path string, so a bookmark might look like `C:\Documents\Avalonia\bookmarks.pdf`
166222

167-
**Android**: Think of the content provider like a waiter that your apps can ask for a certain file/folder through a Content URI. The URI format looks like `content://[Authority]/[path]/[id]`. For example, `com.android.externalstorage.documents` is an `Authority` for accessing External Storage providers, so a bookmark might look like `content://com.android.externalstorage.documents/tree/[your folder path]`.
223+
**Android**: Think of the content provider like a waiter that your apps can ask for a certain file/folder through a Content URI. The URI format looks like `content://[Authority]/[path]/[id]`. For example, `com.android.externalstorage.documents` is an `Authority` for accessing External Storage providers, so a bookmark might look like `content://com.android.externalstorage.documents/tree/[your folder path]`(Reference: [Create a content provider | Android Developers](https://developer.android.com/guide/topics/providers/content-provider-creating)).
168224

169225
:::note
170226
The exact behavior and capabilities can depend on the specific operating system and its security policies. For instance, on some platforms, a bookmark might become invalid if the user moves or renames the file or folder that it points to.

i18n/ru/docusaurus-plugin-content-docs/current/concepts/services/storage-provider/bookmarks.md

Lines changed: 213 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,223 @@ title: Bookmarks
44
---
55

66
# Bookmarks
7-
87
Bookmarks are particularly important for maintaining access to files and folders in modern operating systems that have strict security and privacy controls. For instance, on platforms like iOS and newer versions of macOS, direct file system access is heavily restricted. Instead, applications request the user to select a file or folder through a system-provided file picker, and the operating system then gives the application a security-scoped bookmark that it can use to access that file or folder in the future.
98

109
In Avalonia's `StorageProvider`, these bookmarks are represented as `IStorageBookmarkFile` and `IStorageBookmarkFolder` interfaces.
1110

12-
To get bookmark ID from the specific folder or file, please use `SaveBookmarkAsync` async method on storage item.
13-
After retrieving bookmark ID, it can be saved in a local database for the further use instead of asking user to pick a folder each time.
14-
You can use the `OpenFileBookmarkAsync` and `OpenFolderBookmarkAsync` methods to open a bookmarked file or folder using its bookmark ID. This will return the bookmarked file or folder, or null if the operating system denies the request.
11+
## Avalonia.Platform.Storage
12+
### IStorageBookmarkItem Interface
13+
The `IStorageBookmarkItem` interface represents a bookmarked storage item. It inherits from IStorageItem and IDisposable. This interface is not client implementable, meaning you cannot create your own classes that implement it without special permissions.
14+
15+
Here are the key properties and methods it provides:
16+
17+
#### Properties:
18+
19+
`CanBookmark`: A property that indicates if the item can be bookmarked and reused later.
20+
21+
`Name`: The name of the item.
22+
23+
`Path`: The file-system path of the item.
24+
25+
#### Methods:
26+
`CreateFileAsync(String)`,`CreateFolderAsync(String)`,`DeleteAsync()`,`Dispose()`,`GetBasicPropertiesAsync()`,`GetFileAsync(String)`,`GetFolderAsync(String)`,`GetItemsAsync()`,`GetParentAsync()`,`MoveAsync(IStorageFolder)`,`ReleaseBookmarkAsync()`,`SaveBookmarkAsync()`.
27+
28+
### IStorageBookmarkFolder Interface
29+
30+
#### Properties:
31+
same as IStorageBookmarkItem
32+
33+
#### Methods:
34+
`DeleteAsync()`,`Dispose()`,`GetBasicPropertiesAsync()`,`GetBasicPropertiesAsync()`,`GetParentAsync()`,`MoveAsync(IStorageFolder)`,`OpenReadAsync()`,`OpenWriteAsync()`,`ReleaseBookmarkAsync()`,`SaveBookmarkAsync()`.
35+
36+
37+
38+
## How to Use Bookmark Methods
39+
This section provides a practical guide on using `bookmark`.
40+
41+
### Saving and Loading Bookmarks
42+
To get a bookmark ID for a specific folder or file, use the `SaveBookmarkAsync()` asynchronous method on a storage item. Once you have a bookmark ID, you can save it to a local database for future use instead of requiring the user to select a folder every time.
43+
44+
`SaveBookmarkAsync()`: This method is used to get a `bookmark ID` for a selected file or folder, which can be stored for future use.
45+
46+
```csharp
47+
// Example usage
48+
private async Task SaveBookmarksAsync(Control control)
49+
{
50+
// A folder must be selected first
51+
if (_lastSelectedFolder == null) return;
52+
53+
var bookmarkId = await _lastSelectedFolder.SaveBookmarkAsync();
54+
55+
if (bookmarkId != null)
56+
{
57+
// Save the bookmarkId to a local file for later use.
58+
// ... (code to save bookmarkId)
59+
}
60+
}
61+
```
62+
63+
You can use the `OpenFolderBookmarkAsync()` methods to open a bookmarked folder via a `bookmark ID`. This will return the bookmarked folder or null if the operating system denies the request.
64+
65+
```csharp
66+
// Example usage
67+
private async Task LoadFolderByBookmarkAsync(Control control, string bookmarkId)
68+
{
69+
if (string.IsNullOrEmpty(bookmarkId)) return;
70+
71+
var toplevel = TopLevel.GetTopLevel(control);
72+
if (toplevel?.StorageProvider != null)
73+
{
74+
var folder = await toplevel.StorageProvider.OpenFolderBookmarkAsync(bookmarkId);
75+
76+
if (folder != null)
77+
{
78+
// Successfully opened the bookmarked folder.
79+
// ... (code to save folder as a var)
80+
LastSelectedFolder = folder;
81+
}
82+
}
83+
}
84+
```
85+
86+
`ReleaseBookmarkAsync()`: This method is used to revoke the security-scoped access granted by the operating system. You should call this when you no longer need access to the bookmarked item.
87+
88+
```csharp
89+
// Example usage
90+
private async Task ReleaseBookmarkAsync(Control control, string bookmarkId)
91+
{
92+
if (string.IsNullOrEmpty(bookmarkId)) return;
93+
94+
// First, try to release the OS bookmark.
95+
var toplevel = TopLevel.GetTopLevel(control);
96+
if (toplevel?.StorageProvider != null)
97+
{
98+
var folder = await toplevel.StorageProvider.OpenFolderBookmarkAsync(bookmarkId);
99+
if (folder is IStorageBookmarkItem storageBookmark)
100+
{
101+
await storageBookmark.ReleaseBookmarkAsync();
102+
storageBookmark.Dispose();
103+
}
104+
}
105+
106+
// Then, remove the ID from local storage.
107+
// ... (code to remove bookmarkId from file)
108+
109+
}
110+
```
111+
112+
113+
### Reading and Writing File Content from a Bookmark
114+
115+
`OpenFileBookmarkAsync()`: This method is used to open a bookmarked file from a stored `bookmark ID`. It will return the bookmarked file or null if the operating system denies the request.
116+
117+
118+
Once you retrieve a bookmarked file using `OpenFileBookmarkAsync()`, you can read its content with `OpenReadAsync()` or modify it with `OpenWriteAsync()`.
119+
120+
`OpenReadAsync()`: Opens a stream for read access to the bookmarked file.
121+
122+
```csharp
123+
// Example usage
124+
private async Task LoadFileByBookmarkAsync(Control control, string bookmarkId)
125+
{
126+
if (string.IsNullOrEmpty(bookmarkId)) return;
127+
var toplevel = TopLevel.GetTopLevel(control);
128+
if (toplevel?.StorageProvider != null)
129+
{
130+
IStorageFile bookmarkedFile = await toplevel.StorageProvider.OpenFileBookmarkAsync(bookmarkId);
131+
if (bookmarkedFile != null)
132+
{
133+
// Read bookmarkedFile content
134+
// ... (code to use a read stream)
135+
await using var readStream = await bookmarkedFile.OpenReadAsync();
136+
using var reader = new StreamReader(readStream, Encoding.UTF8);
137+
FileContent = await reader.ReadToEndAsync();
138+
}
139+
}
140+
}
141+
```
142+
143+
`OpenWriteAsync()`: Opens a stream for writing to the bookmarked file.
144+
145+
```csharp
146+
// Example usage
147+
private async Task SaveFileByBookmarkAsync(Control control, string bookmarkId)
148+
{
149+
if (string.IsNullOrEmpty(bookmarkId)) return;
150+
var toplevel = TopLevel.GetTopLevel(control);
151+
if (toplevel?.StorageProvider != null)
152+
{
153+
IStorageFile bookmarkedFile = await toplevel.StorageProvider.OpenFileBookmarkAsync(bookmarkId);
154+
if (bookmarkedFile != null)
155+
{
156+
// Write bookmarkedFile content
157+
// ... (code to use a write stream)
158+
await using var writeStream = await bookmarkedFile.OpenWriteAsync();
159+
await using var writer = new StreamWriter(writeStream, Encoding.UTF8);
160+
await writer.WriteAsync(FileContent);
161+
}
162+
}
163+
}
164+
```
165+
166+
167+
### Managing Bookmarked Files and Folders
168+
Once a bookmark is loaded, you can use the inherited methods from `IStorageItem` to manipulate the file or folder.
169+
170+
`DeleteAsync()`: This method asynchronously deletes the current storage item and its contents.
171+
172+
```csharp
173+
// Example usage
174+
private async Task DeleteFileAsync()
175+
{
176+
if (SelectedFile != null && LastSelectedFolder != null)
177+
{
178+
await SelectedFile.DeleteAsync();
179+
// Then refresh the UI.
180+
}
181+
}
182+
```
183+
184+
`MoveAsync(IStorageFolder)`: This method asynchronously moves the bookmarked item to a new location.
185+
186+
```csharp
187+
IStorageFile bookmarkedFile = ...;
188+
IStorageFolder newDestinationFolder = ...;
189+
await bookmarkedFile.MoveAsync(newDestinationFolder);
190+
```
191+
192+
`GetBasicPropertiesAsync()`: This method asynchronously retrieves basic properties of the storage item, such as its size and modification date.
193+
194+
```csharp
195+
// Example usage
196+
IStorageFile bookmarkedFile = ...;
197+
var properties = await bookmarkedFile.GetBasicPropertiesAsync();
198+
long size = properties.Size;
199+
```
200+
201+
`GetParentAsync()`: This method asynchronously gets the parent folder of the current storage item.
202+
203+
```csharp
204+
// Example usage
205+
IStorageFile bookmarkedFile = ...;
206+
var parentFolder = await bookmarkedFile.GetParentAsync();
207+
string parentName = parentFolder.Name;
208+
```
209+
210+
`TryGetLocalPath()`: This extension method attempts to get the local file system path as a string. It's useful for platform-specific operations where a local path is required.
211+
212+
```csharp
213+
// This will work on Windows but may return null on other platforms
214+
IStorageFile bookmarkedFile = ...;
215+
string? localPath = bookmarkedFile.TryGetLocalPath();
216+
```
217+
218+
## Platform-Specific Bookmark Representation
219+
The way a `bookmark ID` is represented can vary by platform:
220+
221+
**Windows**: A bookmark is a simple absolute path string, so a bookmark might look like `C:\Documents\Avalonia\bookmarks.pdf`
222+
223+
**Android**: Think of the content provider like a waiter that your apps can ask for a certain file/folder through a Content URI. The URI format looks like `content://[Authority]/[path]/[id]`. For example, `com.android.externalstorage.documents` is an `Authority` for accessing External Storage providers, so a bookmark might look like `content://com.android.externalstorage.documents/tree/[your folder path]`(Reference: [Create a content provider | Android Developers](https://developer.android.com/guide/topics/providers/content-provider-creating)).
15224

16225
:::note
17226
The exact behavior and capabilities can depend on the specific operating system and its security policies. For instance, on some platforms, a bookmark might become invalid if the user moves or renames the file or folder that it points to.

0 commit comments

Comments
 (0)