Skip to content

Commit ef6e107

Browse files
Click to expand.
1 parent ab0c94e commit ef6e107

File tree

1 file changed

+66
-28
lines changed

1 file changed

+66
-28
lines changed

samples/KristofferStrube.Blazor.GraphEditor.WasmExample/Pages/FollowingGraph.razor

Lines changed: 66 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@
1717
}
1818
else
1919
{
20-
<text>Selected user: <b>@selectedUser.Id</b></text>
20+
<text>
21+
Selected user: <b>@selectedUser.Id</b>
22+
&nbsp;
23+
<button class="btn btn-primary" @onclick="Expand">Expand with their followings</button>
24+
&nbsp; <small>(We only show 50 followings for each user)</small>
25+
</text>
2126
}
2227
</p>
2328

@@ -31,7 +36,8 @@
3136
NodeColorMapper="n => n.Color"
3237
NodeImageMapper="n => n.Image"
3338
NodeRepulsionMapper="_ => 1200"
34-
EdgeSpringConstantMapper="_ => 0.8"
39+
EdgeSpringConstantMapper="_ => 0.7"
40+
EdgeSpringLengthMapper="_ => 200"
3541
EdgeFromMapper="e => e.from"
3642
EdgeToMapper="e => e.to"
3743
EdgeWidthMapper="_ => 5"
@@ -43,6 +49,8 @@
4349
private bool running = true;
4450
private string? error;
4551
private User? selectedUser;
52+
List<Follow> edges = [];
53+
List<User> users = [];
4654

4755
protected override async Task OnAfterRenderAsync(bool firstRender)
4856
{
@@ -54,34 +62,11 @@
5462

5563
string primaryUserId = "@[email protected]";
5664

57-
var response = await httpClient.GetAsync($"https://kristoffer-strube.dk/API/mastodon/Following/{primaryUserId}");
58-
59-
if (!response.IsSuccessStatusCode)
60-
{
61-
error = await response.Content.ReadAsStringAsync();
62-
return;
63-
}
64-
65-
var followingUrls = await response.Content.ReadFromJsonAsync<string[]>();
66-
var following = followingUrls!.Select(url => url[8..].Split("/users/")).Select(parts => new User($"@{parts[1]}@{parts[0]}", "#7070f0"));
67-
6865
User primaryUser = new(primaryUserId, "#70f070", size: 50);
66+
await GetImageForUser(primaryUser);
67+
users.Add(primaryUser);
6968

70-
List<User> users = [primaryUser, .. following];
71-
72-
Task.WhenAll(users.Select(async user =>
73-
{
74-
var response = await httpClient.GetAsync($"https://kristoffer-strube.dk/API/mastodon/Profile/{user.Id}");
75-
76-
if (!response.IsSuccessStatusCode)
77-
return;
78-
79-
Person? person = await response.Content.ReadFromJsonAsync<Person>();
80-
81-
user.Image = person?.Icon?.FirstOrDefault() is Image { } image ? image.Url.FirstOrDefault()?.Href?.ToString() : null;
82-
}));
83-
84-
List<Follow> edges = following.Select(f => new Follow(primaryUser, f)).ToList();
69+
await AddMoreUsers(primaryUser, 30);
8570

8671
await GraphEditor.LoadGraph(users, edges);
8772

@@ -100,6 +85,59 @@
10085
}
10186
}
10287

88+
public async Task Expand()
89+
{
90+
await AddMoreUsers(selectedUser!, 20);
91+
await GraphEditor.UpdateGraph(users, edges);
92+
GraphEditor.MoveEdgesToBack();
93+
}
94+
95+
private async Task AddMoreUsers(User fromUser, int size)
96+
{
97+
var response = await httpClient.GetAsync($"https://kristoffer-strube.dk/API/mastodon/Following/{fromUser.Id}");
98+
99+
if (!response.IsSuccessStatusCode)
100+
{
101+
error = await response.Content.ReadAsStringAsync();
102+
return;
103+
}
104+
105+
var followingUrls = await response.Content.ReadFromJsonAsync<string[]>();
106+
var following = followingUrls!
107+
.Select(url => url.Length > 12 && url[8..].Split("/users/") is { Length: 2 } parts ? parts : null)
108+
.Where(parts => parts is not null)
109+
.Select(parts => new User($"@{parts[1]}@{parts[0]}", "#7070f0", size: size))
110+
.OrderByDescending(u => users.Any(existing => existing.Equals(u)) ? 1 : 0)
111+
.Take(50)
112+
.ToList();
113+
var allNewUsers = following.Where(f => !users.Any(u => u.Equals(f))).ToList();
114+
115+
users = [.. users, .. allNewUsers];
116+
117+
foreach (var follow in following)
118+
{
119+
var newEdge = new Follow(fromUser, follow);
120+
if (!edges.Contains(newEdge))
121+
{
122+
edges.Add(new Follow(fromUser, follow));
123+
}
124+
}
125+
126+
Task.WhenAll(allNewUsers.Select(GetImageForUser));
127+
}
128+
129+
public async Task GetImageForUser(User user)
130+
{
131+
var response = await httpClient.GetAsync($"https://kristoffer-strube.dk/API/mastodon/Profile/{user.Id}");
132+
133+
if (!response.IsSuccessStatusCode)
134+
return;
135+
136+
Person? person = await response.Content.ReadFromJsonAsync<Person>();
137+
138+
user.Image = person?.Icon?.FirstOrDefault() is Image { } image ? image.Url.FirstOrDefault()?.Href?.ToString() : null;
139+
}
140+
103141
public class User(string id, string color, float size = 30) : IEquatable<User>
104142
{
105143
public string Id = id;

0 commit comments

Comments
 (0)