• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

knowledgepixels / nanodash / 22618039211

03 Mar 2026 10:05AM UTC coverage: 16.058% (+0.2%) from 15.884%
22618039211

Pull #365

github

web-flow
Merge 1e7e700f0 into a8c4b4a77
Pull Request #365: Refactor of `ResourceWithProfile` and related classes

699 of 5287 branches covered (13.22%)

Branch coverage included in aggregate %.

1721 of 9783 relevant lines covered (17.59%)

2.41 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
src/main/java/com/knowledgepixels/nanodash/page/UserPage.java
1
package com.knowledgepixels.nanodash.page;
2

3
import com.google.common.collect.ArrayListMultimap;
4
import com.google.common.collect.Multimap;
5
import com.knowledgepixels.nanodash.*;
6
import com.knowledgepixels.nanodash.component.*;
7
import com.knowledgepixels.nanodash.domain.IndividualAgent;
8
import com.knowledgepixels.nanodash.domain.User;
9
import org.apache.wicket.AttributeModifier;
10
import org.apache.wicket.Component;
11
import org.apache.wicket.extensions.ajax.markup.html.AjaxLazyLoadPanel;
12
import org.apache.wicket.markup.html.basic.Label;
13
import org.apache.wicket.markup.html.link.AbstractLink;
14
import org.apache.wicket.markup.html.panel.EmptyPanel;
15
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
16
import org.apache.wicket.model.Model;
17
import org.apache.wicket.request.flow.RedirectToUrlException;
18
import org.apache.wicket.request.mapper.parameter.PageParameters;
19
import org.eclipse.rdf4j.model.IRI;
20
import org.nanopub.extra.services.ApiResponse;
21
import org.slf4j.Logger;
22
import org.slf4j.LoggerFactory;
23

24
import java.util.ArrayList;
25
import java.util.List;
26

27
/**
28
 * Page that shows a user profile, including their nanopubs and stats.
29
 */
30
public class UserPage extends NanodashPage {
31

32
    private static final Logger logger = LoggerFactory.getLogger(UserPage.class);
×
33

34
    /**
35
     * The mount path for this page.
36
     */
37
    public static final String MOUNT_PATH = "/user";
38

39
    /**
40
     * {@inheritDoc}
41
     */
42
    @Override
43
    public String getMountPath() {
44
        return MOUNT_PATH;
×
45
    }
46

47
    private IRI userIri;
48
    private String pubkeyHashes = "";
×
49

50
    /**
51
     * Constructor for UserPage.
52
     *
53
     * @param parameters Page parameters, must include "id" with the user IRI.
54
     */
55
    public UserPage(final PageParameters parameters) {
56
        super(parameters);
×
57
        setOutputMarkupId(true);
×
58

59
        if (parameters.get("id") == null) throw new RedirectToUrlException(ProfilePage.MOUNT_PATH);
×
60
        final String userIriString = parameters.get("id").toString();
×
61
        userIri = Utils.vf.createIRI(userIriString);
×
62
        //NanodashSession session = NanodashSession.get();
63

64
        for (String pk : User.getPubkeyhashes(userIri, null)) {
×
65
            pubkeyHashes += " " + pk;
×
66
        }
×
67
        if (!pubkeyHashes.isEmpty()) pubkeyHashes = pubkeyHashes.substring(1);
×
68

69
        String pageType = "users";
×
70
        add(new TitleBar("titlebar", this, pageType));
×
71

72
        add(new JustPublishedMessagePanel("justPublishedMessage", parameters));
×
73

74
        final String displayName = User.getShortDisplayName(userIri);
×
75
        add(new Label("pagetitle", displayName + " (user) | nanodash"));
×
76
        EmptyPanel userIcon = new EmptyPanel("userIcon");
×
77
        userIcon.add(AttributeModifier.replace("class", IndividualAgent.isSoftware(userIri) ? "bot-icon" : "user-icon"));
×
78
        add(userIcon);
×
79
        add(new Label("username", displayName));
×
80

81
        add(new BookmarkablePageLink<Void>("fullid", ExplorePage.class, parameters.set("label", displayName)).setBody(Model.of(userIriString)));
×
82

83
        add(new BookmarkablePageLink<Void>("showprofile", ProfilePage.class).setVisible(userIri.equals(NanodashSession.get().getUserIri())));
×
84
        add(new BookmarkablePageLink<Void>("showchannel", ListPage.class, new PageParameters().add("userid", userIriString)));
×
85

86

87
//                final Map<String,String> statsParams = new HashMap<>();
88
//                final String statsQueryName;
89
//                if (pubkeyHashes.isEmpty()) {
90
//                        statsQueryName = "get-user-stats-from-userid";
91
//                        statsParams.put("userid", userIriString);
92
//                } else {
93
//                        statsQueryName = "get-user-stats-from-pubkeys";
94
//                        statsParams.put("userid", userIriString);
95
//                        statsParams.put("pubkeyhashes", pubkeyHashes);
96
//                } 
97
//                Map<String,String> statsMap = ApiCache.retrieveMap(statsQueryName, statsParams);
98
//                if (statsMap != null) {
99
//                        add(new StatsPanel("stats", userIriString, pubkeyHashes, statsMap));
100
//                } else {
101
//                        add(new AjaxLazyLoadPanel<Component>("stats") {
102
//        
103
//                                @Override
104
//                                public Component getLazyLoadComponent(String markupId) {
105
//                                        Map<String,String> m = null;
106
//                                        while (true) {
107
//                                                try {
108
//                                                        Thread.sleep(500);
109
//                                                } catch (InterruptedException ex) {
110
//                                                        logger.error();
111
//                                                }
112
//                                                if (!ApiCache.isRunning(statsQueryName, statsParams)) {
113
//                                                        m = ApiCache.retrieveMap(statsQueryName, statsParams);
114
//                                                        if (m != null) break;
115
//                                                }
116
//                                        }
117
//                                        return new StatsPanel(markupId, userIriString, pubkeyHashes, m);
118
//                                }
119
//
120
//                                @Override
121
//                                protected void onContentLoaded(Component content, Optional<AjaxRequestTarget> target) {
122
//                                        super.onContentLoaded(content, target);
123
//                                        if (target.get() != null) target.get().appendJavaScript("updateElements();");
124
//                                }
125
//        
126
//                        });
127
//                }
128

129
        final Multimap<String, String> params = ArrayListMultimap.create();
×
130
        final String queryName;
131
        if (pubkeyHashes.isEmpty()) {
×
132
            queryName = "get-latest-nanopubs-from-userid";
×
133
            params.put("userid", userIri.stringValue());
×
134
        } else {
135
            queryName = "get-latest-nanopubs-from-pubkeys";
×
136
            params.put("pubkeyhashes", pubkeyHashes);
×
137
            params.put("userid", userIri.stringValue());
×
138
        }
139
        /*final QueryRef queryRef = new QueryRef(queryName, params);
140
        ApiResponse response = ApiCache.retrieveResponseAsync(queryRef);
141
        if (response != null) {
142
            add(makeNanopubResultComponent("latestnanopubs", response));
143
        } else {
144
            add(new AjaxLazyLoadPanel<Component>("latestnanopubs") {
145

146
                @Override
147
                public Component getLazyLoadComponent(String markupId) {
148
                    ApiResponse r = null;
149
                    while (true) {
150
                        try {
151
                            Thread.sleep(500);
152
                        } catch (InterruptedException ex) {
153
                            logger.error("Thread interrupted while waiting for API response", ex);
154
                        }
155
                        if (!ApiCache.isRunning(queryRef)) {
156
                            r = ApiCache.retrieveResponseAsync(queryRef);
157
                            if (r != null) break;
158
                        }
159
                    }
160
                    return makeNanopubResultComponent(markupId, r);
161
                }
162

163
//                                @Override
164
//                                protected void onContentLoaded(Component content, Optional<AjaxRequestTarget> target) {
165
//                                        super.onContentLoaded(content, target);
166
//                                        if (target.get() != null) target.get().appendJavaScript("updateElements();");
167
//                                }
168

169
            });
170
        }*/
171

172
//        if (pubkeyHashes.isEmpty()) {
173
//            add(new Label("activity", "<span class=\"negative\">Activity cannot be shown for this user due to missing user introduction.</span>").setEscapeModelStrings(false));
174
//        } else {
175
//            final QueryRef activityQueryRef = new QueryRef("get-monthly-type-overview-by-pubkeys");
176
//            for (String pk : pubkeyHashes.split(" ")) {
177
//                activityQueryRef.getParams().put("pubkey", pk);
178
//            }
179
//            ApiResponse activityQueryResponse = ApiCache.retrieveResponse(activityQueryRef);
180
//            if (activityQueryResponse != null) {
181
//                if (activityQueryResponse.getData().isEmpty()) {
182
//                    add(new Label("activity", "<em>No recent activity to show for this user.</em>").setEscapeModelStrings(false));
183
//                } else {
184
//                    add(new ActivityPanel("activity", activityQueryResponse));
185
//                }
186
//            } else {
187
//                add(new ApiResultComponent("activity", activityQueryRef) {
188
//
189
//                    @Override
190
//                    public Component getApiResultComponent(String markupId, ApiResponse response) {
191
//                        if (response.getData().isEmpty()) {
192
//                            return new Label(markupId, "<em>No recent activity to show for this user.</em>").setEscapeModelStrings(false);
193
//                        } else {
194
//                            return new ActivityPanel(markupId, response);
195
//                        }
196
//                    }
197
//                });
198
//
199
//            }
200
//        }
201

202
        final List<AbstractLink> viewButtons = new ArrayList<>();
×
203
        AbstractLink addViewButton = new BookmarkablePageLink<NanodashPage>("button", PublishPage.class, new PageParameters()
×
204
                .set("template", "https://w3id.org/np/RAQhTCHtfzGCj1YiE1LualWcZjg3thlRiquFWUE14UF-g")
×
205
                .set("template-version", "latest")
×
206
                .set("param_resource", userIriString)
×
207
                .set("param_appliesToResource", userIriString)
×
208
                .set("context", userIriString)
×
209
                .set("refresh-upon-publish", userIriString)
×
210
        );
211
        addViewButton.setBody(Model.of("+ view display"));
×
212
        viewButtons.add(addViewButton);
×
213

214
        IndividualAgent individualAgent = IndividualAgent.get(userIriString);
×
215
        if (individualAgent.isDataInitialized()) {
×
216
            add(new ViewList("views", individualAgent, null, null, null, individualAgent, viewButtons));
×
217
        } else {
218
            add(new AjaxLazyLoadPanel<Component>("views") {
×
219

220
                @Override
221
                public Component getLazyLoadComponent(String markupId) {
222
                    return new ViewList(markupId, individualAgent, null, null, null, individualAgent, viewButtons);
×
223
                }
224

225
                @Override
226
                protected boolean isContentReady() {
227
                    return individualAgent.isDataInitialized();
×
228
                }
229

230
                @Override
231
                public Component getLoadingComponent(String id) {
232
                    return new Label(id, "<div class=\"row-section\"><div class=\"col-12\">" + ResultComponent.getWaitIconHtml() + "</div></div>").setEscapeModelStrings(false);
×
233
                }
234

235
            });
236
        }
237
    }
×
238

239
    private static Component makeNanopubResultComponent(String markupId, ApiResponse response) {
240
        if (response.getData().isEmpty()) {
×
241
            return new Label(markupId, "(none)");
×
242
        } else {
243
            return NanopubResults.fromApiResponse(markupId, response, 5);
×
244
        }
245
    }
246

247
    /**
248
     * <p>hasAutoRefreshEnabled.</p>
249
     *
250
     * @return a boolean
251
     */
252
    protected boolean hasAutoRefreshEnabled() {
253
        return true;
×
254
    }
255

256
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc