| Name | Message | Date |
|---|---|---|
| 📄 FolderPickerActivity.cs | 4 days ago | |
| 📄 NoteListActivity.cs | 4 days ago | |
| 📄 NoteResultIntent.cs | 4 days ago | |
| 📄 NoteViewActivity.cs | 4 days ago | |
| 📄 SettingsActivity.cs | 4 days ago |
📄
src/Activities/FolderPickerActivity.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
using Android.Content; using Android.Views; using AndroidX.AppCompat.App; using AndroidX.RecyclerView.Widget; using Google.Android.Material.ProgressIndicator; using NotesApp.Adapters; using NotesApp.Auth; using NotesApp.Graph; using NotesApp.Models; using NotesApp.Views; using Toolbar = AndroidX.AppCompat.Widget.Toolbar; namespace NotesApp.Activities; [Activity(Label = "@string/choose_folder_title", Exported = false)] public class FolderPickerActivity : AppCompatActivity { private const int SelectFolderRequestCode = 100; public const string ExtraFolderId = "folder_id"; public const string ExtraFolderPath = "folder_path"; private LinearProgressIndicator _progressBar = null!; private FolderListAdapter _adapter = null!; private GraphService _graphService = null!; private string? _folderId; private string _folderPath = "/"; protected override void OnCreate(Bundle? savedInstanceState) { AndroidX.Activity.EdgeToEdge.Enable(this); base.OnCreate(savedInstanceState); SetContentView(Resource.Layout.activity_folder_picker); EdgeToEdgeHelper.Apply(FindViewById(Resource.Id.folder_picker_root)!); _folderId = Intent?.GetStringExtra(ExtraFolderId); _folderPath = Intent?.GetStringExtra(ExtraFolderPath) ?? "/"; var toolbar = FindViewById<Toolbar>(Resource.Id.folder_picker_toolbar)!; toolbar.Title = _folderPath; SetSupportActionBar(toolbar); SupportActionBar?.SetDisplayHomeAsUpEnabled(true); _progressBar = FindViewById<LinearProgressIndicator>(Resource.Id.folder_progress)!; var recyclerView = FindViewById<RecyclerView>(Resource.Id.folder_recycler_view)!; recyclerView.SetLayoutManager(new LinearLayoutManager(this)); _adapter = new FolderListAdapter(OnFolderTapped); recyclerView.SetAdapter(_adapter); FindViewById<Button>(Resource.Id.select_folder_button)!.Click += (_, _) => SelectThisFolder(); _graphService = new GraphService(this); _ = LoadFoldersAsync(); } public override bool OnSupportNavigateUp() { Finish(); return true; } protected override void OnActivityResult(int requestCode, Result resultCode, Intent? data) { base.OnActivityResult(requestCode, resultCode, data); AuthService.HandleActivityResult(requestCode, resultCode, data); if (requestCode == SelectFolderRequestCode && resultCode == Result.Ok && data != null) { // A nested picker (a subfolder browsed into) selected a folder; forward the // result up the recursive chain and close this level too. SetResult(Result.Ok, data); Finish(); } } private async Task LoadFoldersAsync() { var folderKey = _folderId ?? "root"; // Render instantly from a prior visit or a parent-level prefetch if we have one; // otherwise fall back to the normal network fetch with a spinner. if (FolderChildrenCache.TryGet(folderKey, out var cached)) { _adapter.SetItems(cached); PrefetchChildrenOf(cached); return; } _progressBar.Visibility = ViewStates.Visible; try { var folders = await _graphService.ListChildFoldersAsync(_folderId); FolderChildrenCache.Set(folderKey, folders); _adapter.SetItems(folders); PrefetchChildrenOf(folders); } catch (Exception ex) { Toast.MakeText(this, ex.Message, ToastLength.Long)?.Show(); } finally { _progressBar.Visibility = ViewStates.Invisible; } } // Warms the cache one level ahead so tapping into a folder shown here is usually instant // instead of waiting on a network round trip. Fire-and-forget: a normal fetch still runs // (with its own spinner/error handling) if the user navigates in before this finishes. private void PrefetchChildrenOf(List<DriveFolderItem> folders) { foreach (var folder in folders) { if (FolderChildrenCache.TryGet(folder.Id, out _)) continue; _ = PrefetchOneAsync(folder.Id); } } private async Task PrefetchOneAsync(string folderId) { try { var children = await _graphService.ListChildFoldersAsync(folderId); FolderChildrenCache.Set(folderId, children); } catch { // Best-effort warm-up; a real fetch with error handling runs if the user // navigates in before this succeeds. } } private void OnFolderTapped(DriveFolderItem folder) { var intent = new Intent(this, typeof(FolderPickerActivity)); intent.PutExtra(ExtraFolderId, folder.Id); intent.PutExtra(ExtraFolderPath, _folderPath.TrimEnd('/') + "/" + folder.Name); StartActivityForResult(intent, SelectFolderRequestCode); } private void SelectThisFolder() { var data = new Intent(); data.PutExtra(ExtraFolderId, _folderId ?? "root"); data.PutExtra(ExtraFolderPath, _folderPath); SetResult(Result.Ok, data); Finish(); } }