Mirror of https://github.com/improsocial/impro-sample-plugin
0

Configure Feed

Select the types of activity you want to include in your feed.

Add readme

Grace Kind (May 31, 2026, 1:50 PM -0500) ed7d3930 f6074334

+99 -16
+3
README.md
··· 1 + # Impro Sample Plugin 2 + 3 + A starter reference plugin demonstrating commands, modals, and the host bridge.
+95 -15
main.js
··· 107 107 }); 108 108 } 109 109 }; 110 + var PluginData = class { 111 + getPost(uri) { 112 + return hostCall("getPost", { uri }); 113 + } 114 + getProfile(did) { 115 + return hostCall("getProfile", { did }); 116 + } 117 + }; 110 118 var App = class { 111 119 constructor() { 112 120 this.currentUser = null; 121 + this.data = new PluginData(); 113 122 } 114 123 on(event, listener) { 115 124 addEventListener(event, listener); ··· 167 176 handlerId 168 177 }); 169 178 } 179 + registerSlot(name, callback = () => null) { 180 + const handlerId = uuid.create(); 181 + callHandlers.set(handlerId, async (context) => { 182 + const result = await callback(context); 183 + if (result == null) return null; 184 + if (!(result instanceof VirtualEl)) { 185 + const description = result?.constructor?.name ?? typeof result; 186 + throw new Error( 187 + `Slot "${name}" must return a VirtualEl (or null), got ${description}` 188 + ); 189 + } 190 + return result._serialize(); 191 + }); 192 + self.postMessage({ 193 + type: "register", 194 + target: "slot", 195 + name, 196 + handlerId 197 + }); 198 + } 170 199 onload() { 171 200 } 172 201 onunload() { ··· 236 265 } 237 266 display() { 238 267 } 239 - refresh() { 240 - return hostCall("refreshSettingTab"); 268 + refresh({ reset = false } = {}) { 269 + return hostCall("refreshSettingTab", { reset }); 241 270 } 242 271 }; 243 272 var Setting = class { 244 273 constructor(containerEl) { 245 - this.settingEl = containerEl.createDiv({ cls: "plugin-setting-item" }); 246 - this.infoEl = this.settingEl.createDiv({ cls: "plugin-setting-item-info" }); 247 - this.nameEl = this.infoEl.createDiv({ cls: "plugin-setting-item-name" }); 248 - this.descEl = this.infoEl.createDiv({ cls: "plugin-setting-item-desc" }); 274 + this.settingEl = containerEl.createDiv({ cls: "setting-item" }); 275 + this.infoEl = this.settingEl.createDiv({ cls: "setting-item-info" }); 276 + this.nameEl = this.infoEl.createEl("h2", { cls: "setting-item-name" }); 277 + this.descEl = this.infoEl.createEl("p", { cls: "setting-item-desc" }); 249 278 this.controlEl = this.settingEl.createDiv({ 250 - cls: "plugin-setting-item-control" 279 + cls: "setting-item-control" 251 280 }); 252 281 } 253 282 setName(text) { ··· 283 312 constructor(containerEl) { 284 313 this.el = containerEl.createEl("input", { 285 314 attr: { type: "text" }, 286 - cls: "plugin-setting-text-input" 315 + cls: "setting-item-text-input" 287 316 }); 288 317 } 289 318 setValue(value) { ··· 301 330 }; 302 331 var ToggleComponent = class { 303 332 constructor(containerEl) { 304 - this.el = containerEl.createEl("input", { 305 - attr: { type: "checkbox" }, 306 - cls: "plugin-setting-toggle" 333 + this.el = containerEl.createEl("toggle-switch", { 334 + cls: "setting-item-toggle" 307 335 }); 308 336 } 309 337 setValue(value) { ··· 319 347 var DropdownComponent = class { 320 348 constructor(containerEl) { 321 349 this.el = containerEl.createEl("select", { 322 - cls: "plugin-setting-dropdown" 350 + cls: "setting-item-dropdown" 323 351 }); 324 352 } 325 353 addOption(value, label) { ··· 350 378 var ButtonComponent = class { 351 379 constructor(containerEl) { 352 380 this.el = containerEl.createEl("button", { 353 - cls: "plugin-setting-button" 381 + cls: "rounded-button" 354 382 }); 355 383 } 356 384 setButtonText(text) { ··· 358 386 return this; 359 387 } 360 388 setCta() { 361 - this.el.addClass("primary-button"); 389 + this.el.addClass("rounded-button-primary"); 362 390 return this; 363 391 } 364 392 onClick(callback) { ··· 366 394 return this; 367 395 } 368 396 }; 397 + var IconComponent = class { 398 + constructor(containerEl) { 399 + this.el = containerEl.createEl("plugin-icon"); 400 + } 401 + setIcon(name) { 402 + this.el.setAttr("icon", name); 403 + return this; 404 + } 405 + }; 406 + var ProfilesListComponent = class { 407 + constructor(containerEl) { 408 + this.el = containerEl.createEl("plugin-profiles-list"); 409 + } 410 + setDids(dids) { 411 + const value = Array.isArray(dids) ? dids.join(",") : String(dids ?? ""); 412 + this.el.setAttr("dids", value); 413 + return this; 414 + } 415 + setEmptyMessage(message) { 416 + this.el.setAttr("empty-message", message); 417 + return this; 418 + } 419 + }; 420 + var PostsFeedComponent = class { 421 + constructor(containerEl) { 422 + this.el = containerEl.createEl("plugin-posts-feed"); 423 + } 424 + setUris(uris) { 425 + const value = Array.isArray(uris) ? uris.join(",") : String(uris ?? ""); 426 + this.el.setAttr("uris", value); 427 + return this; 428 + } 429 + setEmptyMessage(message) { 430 + this.el.setAttr("empty-message", message); 431 + return this; 432 + } 433 + }; 369 434 var VirtualEl = class _VirtualEl { 370 435 constructor(tag) { 371 436 this.tag = tag; ··· 426 491 } 427 492 createSpan(options = {}, callback) { 428 493 return this.createEl("span", options, callback); 494 + } 495 + createProfilesList(callback) { 496 + const component = new ProfilesListComponent(this); 497 + if (typeof callback === "function") callback(component); 498 + return component; 499 + } 500 + createPostsFeed(callback) { 501 + const component = new PostsFeedComponent(this); 502 + if (typeof callback === "function") callback(component); 503 + return component; 504 + } 505 + createIcon(callback) { 506 + const component = new IconComponent(this); 507 + if (typeof callback === "function") callback(component); 508 + return component; 429 509 } 430 510 _serialize() { 431 511 return { ··· 542 622 (button) => button.setButtonText("Reset").onClick(async () => { 543 623 this.plugin.settings = { ...DEFAULT_SETTINGS }; 544 624 await this.plugin.saveData(this.plugin.settings); 545 - this.refresh(); 625 + this.refresh({ reset: true }); 546 626 }) 547 627 ); 548 628 }
+1 -1
src/main.js
··· 91 91 button.setButtonText("Reset").onClick(async () => { 92 92 this.plugin.settings = { ...DEFAULT_SETTINGS }; 93 93 await this.plugin.saveData(this.plugin.settings); 94 - this.refresh(); 94 + this.refresh({ reset: true }); 95 95 }), 96 96 ); 97 97 }