feat: Implement request/response models for all XRPC procedures, wire up to methods in the api service

Changed files
+12892 -1279
.github
instructions
lexicons
lib
models
procedures
providers
+83
.github/instructions/api.md
··· 1 + --- 2 + applyTo: "lib/api.dart" 3 + --- 4 + 5 + # Copilot Instructions: Generate Typed Dart API Client for Grain Social Endpoints 6 + 7 + ## Goal 8 + 9 + Generate a Dart API client for the Grain social endpoints, using the lexicon 10 + JSON files in `lexicons/social/grain` and its subfolders. Each endpoint should 11 + have: 12 + 13 + - Typed request and response models 14 + - API methods with correct parameters and return types 15 + - Documentation from the lexicon descriptions 16 + 17 + ## Instructions for Copilot 18 + 19 + 1. **For each lexicon JSON file:** 20 + - Parse the endpoint definition (`id`, `type`, `description`, 21 + `parameters`/`input`, `output`). 22 + - Generate a Dart class for request parameters/input. 23 + - Generate a Dart class for response/output. 24 + - Use the [freezed](https://pub.dev/packages/freezed) package to generate an 25 + immutable model for each response type. 26 + - Each model class should be created in a separate file in 27 + `models/procedures`. 28 + - Create a Dart method for the endpoint, with correct types and 29 + documentation. 30 + - Each API method should: 31 + - Accept an `apiUrl` parameter as a prefix for requests (e.g., 32 + `$apiUrl/xrpc/${id}`). 33 + - Pass the API token in the `Authorization` header for all requests. 34 + - Use the endpoint URL format `/xrpc/${id}` (e.g., 35 + `/xrpc/social.grain.actor.getProfile`). 36 + 37 + 2. **Type Mapping:** 38 + - JSON `string` → Dart `String` 39 + - JSON `object` → Dart class 40 + - JSON `array` → Dart `List<T>` 41 + - JSON `integer` → Dart `int` 42 + - JSON `boolean` → Dart `bool` 43 + - JSON `*/*` (binary) → Dart `Uint8List` or `List<int>` 44 + 45 + 3. **API Method Example:** 46 + ```dart 47 + /// Get detailed profile view of an actor. 48 + Future<ProfileViewDetailed> getProfile(String actor); 49 + 50 + /// Create a comment. 51 + Future<CommentResponse> createComment(CreateCommentRequest request); 52 + 53 + /// Create a follow relationship. 54 + Future<FollowResponse> createFollow(String subject); 55 + 56 + /// Create a photo. 57 + Future<PhotoResponse> createPhoto(Uint8List photoData); 58 + ``` 59 + 60 + 4. **Documentation:** 61 + - Use the `description` field from the lexicon for method/class docs. 62 + 63 + 5. **Error Handling:** 64 + - Generate error classes/types for API errors. 65 + 66 + 6. **Authentication:** 67 + - Mark endpoints that require auth. 68 + 69 + ## Reference 70 + 71 + Use all JSON files in `lexicons/social/grain` and subfolders. For each endpoint, 72 + use the schema references for response types if available. 73 + 74 + ## Example Endpoints 75 + 76 + ### Get Actor Profile 77 + 78 + - **ID:** `social.grain.actor.getProfile` 79 + - **Type:** Query 80 + - **Description:** Get detailed profile view of an actor. Does not require auth, 81 + but contains relevant metadata with auth. 82 + - **Parameters:** `actor` (string, at-identifier) 83 + - **Response:** JSON, schema: `social.grain.actor.defs#profileViewDetailed`
+695
lexicons/app/bsky/actor/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.actor.defs", 4 + "defs": { 5 + "nux": { 6 + "type": "object", 7 + "required": [ 8 + "id", 9 + "completed" 10 + ], 11 + "properties": { 12 + "id": { 13 + "type": "string", 14 + "maxLength": 100 15 + }, 16 + "data": { 17 + "type": "string", 18 + "maxLength": 3000, 19 + "description": "Arbitrary data for the NUX. The structure is defined by the NUX itself. Limited to 300 characters.", 20 + "maxGraphemes": 300 21 + }, 22 + "completed": { 23 + "type": "boolean", 24 + "default": false 25 + }, 26 + "expiresAt": { 27 + "type": "string", 28 + "format": "datetime", 29 + "description": "The date and time at which the NUX will expire and should be considered completed." 30 + } 31 + }, 32 + "description": "A new user experiences (NUX) storage object" 33 + }, 34 + "mutedWord": { 35 + "type": "object", 36 + "required": [ 37 + "value", 38 + "targets" 39 + ], 40 + "properties": { 41 + "id": { 42 + "type": "string" 43 + }, 44 + "value": { 45 + "type": "string", 46 + "maxLength": 10000, 47 + "description": "The muted word itself.", 48 + "maxGraphemes": 1000 49 + }, 50 + "targets": { 51 + "type": "array", 52 + "items": { 53 + "ref": "app.bsky.actor.defs#mutedWordTarget", 54 + "type": "ref" 55 + }, 56 + "description": "The intended targets of the muted word." 57 + }, 58 + "expiresAt": { 59 + "type": "string", 60 + "format": "datetime", 61 + "description": "The date and time at which the muted word will expire and no longer be applied." 62 + }, 63 + "actorTarget": { 64 + "type": "string", 65 + "default": "all", 66 + "description": "Groups of users to apply the muted word to. If undefined, applies to all users.", 67 + "knownValues": [ 68 + "all", 69 + "exclude-following" 70 + ] 71 + } 72 + }, 73 + "description": "A word that the account owner has muted." 74 + }, 75 + "savedFeed": { 76 + "type": "object", 77 + "required": [ 78 + "id", 79 + "type", 80 + "value", 81 + "pinned" 82 + ], 83 + "properties": { 84 + "id": { 85 + "type": "string" 86 + }, 87 + "type": { 88 + "type": "string", 89 + "knownValues": [ 90 + "feed", 91 + "list", 92 + "timeline" 93 + ] 94 + }, 95 + "value": { 96 + "type": "string" 97 + }, 98 + "pinned": { 99 + "type": "boolean" 100 + } 101 + } 102 + }, 103 + "preferences": { 104 + "type": "array", 105 + "items": { 106 + "refs": [ 107 + "#adultContentPref", 108 + "#contentLabelPref", 109 + "#savedFeedsPref", 110 + "#savedFeedsPrefV2", 111 + "#personalDetailsPref", 112 + "#feedViewPref", 113 + "#threadViewPref", 114 + "#interestsPref", 115 + "#mutedWordsPref", 116 + "#hiddenPostsPref", 117 + "#bskyAppStatePref", 118 + "#labelersPref", 119 + "#postInteractionSettingsPref" 120 + ], 121 + "type": "union" 122 + } 123 + }, 124 + "profileView": { 125 + "type": "object", 126 + "required": [ 127 + "did", 128 + "handle" 129 + ], 130 + "properties": { 131 + "did": { 132 + "type": "string", 133 + "format": "did" 134 + }, 135 + "avatar": { 136 + "type": "string", 137 + "format": "uri" 138 + }, 139 + "handle": { 140 + "type": "string", 141 + "format": "handle" 142 + }, 143 + "labels": { 144 + "type": "array", 145 + "items": { 146 + "ref": "com.atproto.label.defs#label", 147 + "type": "ref" 148 + } 149 + }, 150 + "viewer": { 151 + "ref": "#viewerState", 152 + "type": "ref" 153 + }, 154 + "createdAt": { 155 + "type": "string", 156 + "format": "datetime" 157 + }, 158 + "indexedAt": { 159 + "type": "string", 160 + "format": "datetime" 161 + }, 162 + "associated": { 163 + "ref": "#profileAssociated", 164 + "type": "ref" 165 + }, 166 + "description": { 167 + "type": "string", 168 + "maxLength": 2560, 169 + "maxGraphemes": 256 170 + }, 171 + "displayName": { 172 + "type": "string", 173 + "maxLength": 640, 174 + "maxGraphemes": 64 175 + } 176 + } 177 + }, 178 + "viewerState": { 179 + "type": "object", 180 + "properties": { 181 + "muted": { 182 + "type": "boolean" 183 + }, 184 + "blocking": { 185 + "type": "string", 186 + "format": "at-uri" 187 + }, 188 + "blockedBy": { 189 + "type": "boolean" 190 + }, 191 + "following": { 192 + "type": "string", 193 + "format": "at-uri" 194 + }, 195 + "followedBy": { 196 + "type": "string", 197 + "format": "at-uri" 198 + }, 199 + "mutedByList": { 200 + "ref": "app.bsky.graph.defs#listViewBasic", 201 + "type": "ref" 202 + }, 203 + "blockingByList": { 204 + "ref": "app.bsky.graph.defs#listViewBasic", 205 + "type": "ref" 206 + }, 207 + "knownFollowers": { 208 + "ref": "#knownFollowers", 209 + "type": "ref" 210 + } 211 + }, 212 + "description": "Metadata about the requesting account's relationship with the subject account. Only has meaningful content for authed requests." 213 + }, 214 + "feedViewPref": { 215 + "type": "object", 216 + "required": [ 217 + "feed" 218 + ], 219 + "properties": { 220 + "feed": { 221 + "type": "string", 222 + "description": "The URI of the feed, or an identifier which describes the feed." 223 + }, 224 + "hideReplies": { 225 + "type": "boolean", 226 + "description": "Hide replies in the feed." 227 + }, 228 + "hideReposts": { 229 + "type": "boolean", 230 + "description": "Hide reposts in the feed." 231 + }, 232 + "hideQuotePosts": { 233 + "type": "boolean", 234 + "description": "Hide quote posts in the feed." 235 + }, 236 + "hideRepliesByLikeCount": { 237 + "type": "integer", 238 + "description": "Hide replies in the feed if they do not have this number of likes." 239 + }, 240 + "hideRepliesByUnfollowed": { 241 + "type": "boolean", 242 + "default": true, 243 + "description": "Hide replies in the feed if they are not by followed users." 244 + } 245 + } 246 + }, 247 + "labelersPref": { 248 + "type": "object", 249 + "required": [ 250 + "labelers" 251 + ], 252 + "properties": { 253 + "labelers": { 254 + "type": "array", 255 + "items": { 256 + "ref": "#labelerPrefItem", 257 + "type": "ref" 258 + } 259 + } 260 + } 261 + }, 262 + "interestsPref": { 263 + "type": "object", 264 + "required": [ 265 + "tags" 266 + ], 267 + "properties": { 268 + "tags": { 269 + "type": "array", 270 + "items": { 271 + "type": "string", 272 + "maxLength": 640, 273 + "maxGraphemes": 64 274 + }, 275 + "maxLength": 100, 276 + "description": "A list of tags which describe the account owner's interests gathered during onboarding." 277 + } 278 + } 279 + }, 280 + "knownFollowers": { 281 + "type": "object", 282 + "required": [ 283 + "count", 284 + "followers" 285 + ], 286 + "properties": { 287 + "count": { 288 + "type": "integer" 289 + }, 290 + "followers": { 291 + "type": "array", 292 + "items": { 293 + "ref": "#profileViewBasic", 294 + "type": "ref" 295 + }, 296 + "maxLength": 5, 297 + "minLength": 0 298 + } 299 + }, 300 + "description": "The subject's followers whom you also follow" 301 + }, 302 + "mutedWordsPref": { 303 + "type": "object", 304 + "required": [ 305 + "items" 306 + ], 307 + "properties": { 308 + "items": { 309 + "type": "array", 310 + "items": { 311 + "ref": "app.bsky.actor.defs#mutedWord", 312 + "type": "ref" 313 + }, 314 + "description": "A list of words the account owner has muted." 315 + } 316 + } 317 + }, 318 + "savedFeedsPref": { 319 + "type": "object", 320 + "required": [ 321 + "pinned", 322 + "saved" 323 + ], 324 + "properties": { 325 + "saved": { 326 + "type": "array", 327 + "items": { 328 + "type": "string", 329 + "format": "at-uri" 330 + } 331 + }, 332 + "pinned": { 333 + "type": "array", 334 + "items": { 335 + "type": "string", 336 + "format": "at-uri" 337 + } 338 + }, 339 + "timelineIndex": { 340 + "type": "integer" 341 + } 342 + } 343 + }, 344 + "threadViewPref": { 345 + "type": "object", 346 + "properties": { 347 + "sort": { 348 + "type": "string", 349 + "description": "Sorting mode for threads.", 350 + "knownValues": [ 351 + "oldest", 352 + "newest", 353 + "most-likes", 354 + "random", 355 + "hotness" 356 + ] 357 + }, 358 + "prioritizeFollowedUsers": { 359 + "type": "boolean", 360 + "description": "Show followed users at the top of all replies." 361 + } 362 + } 363 + }, 364 + "hiddenPostsPref": { 365 + "type": "object", 366 + "required": [ 367 + "items" 368 + ], 369 + "properties": { 370 + "items": { 371 + "type": "array", 372 + "items": { 373 + "type": "string", 374 + "format": "at-uri" 375 + }, 376 + "description": "A list of URIs of posts the account owner has hidden." 377 + } 378 + } 379 + }, 380 + "labelerPrefItem": { 381 + "type": "object", 382 + "required": [ 383 + "did" 384 + ], 385 + "properties": { 386 + "did": { 387 + "type": "string", 388 + "format": "did" 389 + } 390 + } 391 + }, 392 + "mutedWordTarget": { 393 + "type": "string", 394 + "maxLength": 640, 395 + "knownValues": [ 396 + "content", 397 + "tag" 398 + ], 399 + "maxGraphemes": 64 400 + }, 401 + "adultContentPref": { 402 + "type": "object", 403 + "required": [ 404 + "enabled" 405 + ], 406 + "properties": { 407 + "enabled": { 408 + "type": "boolean", 409 + "default": false 410 + } 411 + } 412 + }, 413 + "bskyAppStatePref": { 414 + "type": "object", 415 + "properties": { 416 + "nuxs": { 417 + "type": "array", 418 + "items": { 419 + "ref": "app.bsky.actor.defs#nux", 420 + "type": "ref" 421 + }, 422 + "maxLength": 100, 423 + "description": "Storage for NUXs the user has encountered." 424 + }, 425 + "queuedNudges": { 426 + "type": "array", 427 + "items": { 428 + "type": "string", 429 + "maxLength": 100 430 + }, 431 + "maxLength": 1000, 432 + "description": "An array of tokens which identify nudges (modals, popups, tours, highlight dots) that should be shown to the user." 433 + }, 434 + "activeProgressGuide": { 435 + "ref": "#bskyAppProgressGuide", 436 + "type": "ref" 437 + } 438 + }, 439 + "description": "A grab bag of state that's specific to the bsky.app program. Third-party apps shouldn't use this." 440 + }, 441 + "contentLabelPref": { 442 + "type": "object", 443 + "required": [ 444 + "label", 445 + "visibility" 446 + ], 447 + "properties": { 448 + "label": { 449 + "type": "string" 450 + }, 451 + "labelerDid": { 452 + "type": "string", 453 + "format": "did", 454 + "description": "Which labeler does this preference apply to? If undefined, applies globally." 455 + }, 456 + "visibility": { 457 + "type": "string", 458 + "knownValues": [ 459 + "ignore", 460 + "show", 461 + "warn", 462 + "hide" 463 + ] 464 + } 465 + } 466 + }, 467 + "profileViewBasic": { 468 + "type": "object", 469 + "required": [ 470 + "did", 471 + "handle" 472 + ], 473 + "properties": { 474 + "did": { 475 + "type": "string", 476 + "format": "did" 477 + }, 478 + "avatar": { 479 + "type": "string", 480 + "format": "uri" 481 + }, 482 + "handle": { 483 + "type": "string", 484 + "format": "handle" 485 + }, 486 + "labels": { 487 + "type": "array", 488 + "items": { 489 + "ref": "com.atproto.label.defs#label", 490 + "type": "ref" 491 + } 492 + }, 493 + "viewer": { 494 + "ref": "#viewerState", 495 + "type": "ref" 496 + }, 497 + "createdAt": { 498 + "type": "string", 499 + "format": "datetime" 500 + }, 501 + "associated": { 502 + "ref": "#profileAssociated", 503 + "type": "ref" 504 + }, 505 + "displayName": { 506 + "type": "string", 507 + "maxLength": 640, 508 + "maxGraphemes": 64 509 + } 510 + } 511 + }, 512 + "savedFeedsPrefV2": { 513 + "type": "object", 514 + "required": [ 515 + "items" 516 + ], 517 + "properties": { 518 + "items": { 519 + "type": "array", 520 + "items": { 521 + "ref": "app.bsky.actor.defs#savedFeed", 522 + "type": "ref" 523 + } 524 + } 525 + } 526 + }, 527 + "profileAssociated": { 528 + "type": "object", 529 + "properties": { 530 + "chat": { 531 + "ref": "#profileAssociatedChat", 532 + "type": "ref" 533 + }, 534 + "lists": { 535 + "type": "integer" 536 + }, 537 + "labeler": { 538 + "type": "boolean" 539 + }, 540 + "feedgens": { 541 + "type": "integer" 542 + }, 543 + "starterPacks": { 544 + "type": "integer" 545 + } 546 + } 547 + }, 548 + "personalDetailsPref": { 549 + "type": "object", 550 + "properties": { 551 + "birthDate": { 552 + "type": "string", 553 + "format": "datetime", 554 + "description": "The birth date of account owner." 555 + } 556 + } 557 + }, 558 + "profileViewDetailed": { 559 + "type": "object", 560 + "required": [ 561 + "did", 562 + "handle" 563 + ], 564 + "properties": { 565 + "did": { 566 + "type": "string", 567 + "format": "did" 568 + }, 569 + "avatar": { 570 + "type": "string", 571 + "format": "uri" 572 + }, 573 + "banner": { 574 + "type": "string", 575 + "format": "uri" 576 + }, 577 + "handle": { 578 + "type": "string", 579 + "format": "handle" 580 + }, 581 + "labels": { 582 + "type": "array", 583 + "items": { 584 + "ref": "com.atproto.label.defs#label", 585 + "type": "ref" 586 + } 587 + }, 588 + "viewer": { 589 + "ref": "#viewerState", 590 + "type": "ref" 591 + }, 592 + "createdAt": { 593 + "type": "string", 594 + "format": "datetime" 595 + }, 596 + "indexedAt": { 597 + "type": "string", 598 + "format": "datetime" 599 + }, 600 + "associated": { 601 + "ref": "#profileAssociated", 602 + "type": "ref" 603 + }, 604 + "pinnedPost": { 605 + "ref": "com.atproto.repo.strongRef", 606 + "type": "ref" 607 + }, 608 + "postsCount": { 609 + "type": "integer" 610 + }, 611 + "description": { 612 + "type": "string", 613 + "maxLength": 2560, 614 + "maxGraphemes": 256 615 + }, 616 + "displayName": { 617 + "type": "string", 618 + "maxLength": 640, 619 + "maxGraphemes": 64 620 + }, 621 + "followsCount": { 622 + "type": "integer" 623 + }, 624 + "followersCount": { 625 + "type": "integer" 626 + }, 627 + "joinedViaStarterPack": { 628 + "ref": "app.bsky.graph.defs#starterPackViewBasic", 629 + "type": "ref" 630 + } 631 + } 632 + }, 633 + "bskyAppProgressGuide": { 634 + "type": "object", 635 + "required": [ 636 + "guide" 637 + ], 638 + "properties": { 639 + "guide": { 640 + "type": "string", 641 + "maxLength": 100 642 + } 643 + }, 644 + "description": "If set, an active progress guide. Once completed, can be set to undefined. Should have unspecced fields tracking progress." 645 + }, 646 + "profileAssociatedChat": { 647 + "type": "object", 648 + "required": [ 649 + "allowIncoming" 650 + ], 651 + "properties": { 652 + "allowIncoming": { 653 + "type": "string", 654 + "knownValues": [ 655 + "all", 656 + "none", 657 + "following" 658 + ] 659 + } 660 + } 661 + }, 662 + "postInteractionSettingsPref": { 663 + "type": "object", 664 + "required": [], 665 + "properties": { 666 + "threadgateAllowRules": { 667 + "type": "array", 668 + "items": { 669 + "refs": [ 670 + "app.bsky.feed.threadgate#mentionRule", 671 + "app.bsky.feed.threadgate#followerRule", 672 + "app.bsky.feed.threadgate#followingRule", 673 + "app.bsky.feed.threadgate#listRule" 674 + ], 675 + "type": "union" 676 + }, 677 + "maxLength": 5, 678 + "description": "Matches threadgate record. List of rules defining who can reply to this users posts. If value is an empty array, no one can reply. If value is undefined, anyone can reply." 679 + }, 680 + "postgateEmbeddingRules": { 681 + "type": "array", 682 + "items": { 683 + "refs": [ 684 + "app.bsky.feed.postgate#disableRule" 685 + ], 686 + "type": "union" 687 + }, 688 + "maxLength": 5, 689 + "description": "Matches postgate record. List of rules defining who can embed this users posts. If value is an empty array or is undefined, no particular rules apply and anyone can embed." 690 + } 691 + }, 692 + "description": "Default post interaction settings for the account. These values should be applied as default values when creating new posts. These refs should mirror the threadgate and postgate records exactly." 693 + } 694 + } 695 + }
+64
lexicons/app/bsky/actor/profile.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.actor.profile", 4 + "defs": { 5 + "main": { 6 + "key": "literal:self", 7 + "type": "record", 8 + "record": { 9 + "type": "object", 10 + "properties": { 11 + "avatar": { 12 + "type": "blob", 13 + "accept": [ 14 + "image/png", 15 + "image/jpeg" 16 + ], 17 + "maxSize": 1000000, 18 + "description": "Small image to be displayed next to posts from account. AKA, 'profile picture'" 19 + }, 20 + "banner": { 21 + "type": "blob", 22 + "accept": [ 23 + "image/png", 24 + "image/jpeg" 25 + ], 26 + "maxSize": 1000000, 27 + "description": "Larger horizontal image to display behind profile view." 28 + }, 29 + "labels": { 30 + "refs": [ 31 + "com.atproto.label.defs#selfLabels" 32 + ], 33 + "type": "union", 34 + "description": "Self-label values, specific to the Bluesky application, on the overall account." 35 + }, 36 + "createdAt": { 37 + "type": "string", 38 + "format": "datetime" 39 + }, 40 + "pinnedPost": { 41 + "ref": "com.atproto.repo.strongRef", 42 + "type": "ref" 43 + }, 44 + "description": { 45 + "type": "string", 46 + "maxLength": 2560, 47 + "description": "Free-form profile description text.", 48 + "maxGraphemes": 256 49 + }, 50 + "displayName": { 51 + "type": "string", 52 + "maxLength": 640, 53 + "maxGraphemes": 64 54 + }, 55 + "joinedViaStarterPack": { 56 + "ref": "com.atproto.repo.strongRef", 57 + "type": "ref" 58 + } 59 + } 60 + }, 61 + "description": "A declaration of a Bluesky account profile." 62 + } 63 + } 64 + }
+24
lexicons/app/bsky/embed/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.embed.defs", 4 + "defs": { 5 + "aspectRatio": { 6 + "type": "object", 7 + "required": [ 8 + "width", 9 + "height" 10 + ], 11 + "properties": { 12 + "width": { 13 + "type": "integer", 14 + "minimum": 1 15 + }, 16 + "height": { 17 + "type": "integer", 18 + "minimum": 1 19 + } 20 + }, 21 + "description": "width:height represents an aspect ratio. It may be approximate, and may not correspond to absolute dimensions in any given unit." 22 + } 23 + } 24 + }
+82
lexicons/app/bsky/embed/external.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.embed.external", 4 + "defs": { 5 + "main": { 6 + "type": "object", 7 + "required": [ 8 + "external" 9 + ], 10 + "properties": { 11 + "external": { 12 + "ref": "#external", 13 + "type": "ref" 14 + } 15 + }, 16 + "description": "A representation of some externally linked content (eg, a URL and 'card'), embedded in a Bluesky record (eg, a post)." 17 + }, 18 + "view": { 19 + "type": "object", 20 + "required": [ 21 + "external" 22 + ], 23 + "properties": { 24 + "external": { 25 + "ref": "#viewExternal", 26 + "type": "ref" 27 + } 28 + } 29 + }, 30 + "external": { 31 + "type": "object", 32 + "required": [ 33 + "uri", 34 + "title", 35 + "description" 36 + ], 37 + "properties": { 38 + "uri": { 39 + "type": "string", 40 + "format": "uri" 41 + }, 42 + "thumb": { 43 + "type": "blob", 44 + "accept": [ 45 + "image/*" 46 + ], 47 + "maxSize": 1000000 48 + }, 49 + "title": { 50 + "type": "string" 51 + }, 52 + "description": { 53 + "type": "string" 54 + } 55 + } 56 + }, 57 + "viewExternal": { 58 + "type": "object", 59 + "required": [ 60 + "uri", 61 + "title", 62 + "description" 63 + ], 64 + "properties": { 65 + "uri": { 66 + "type": "string", 67 + "format": "uri" 68 + }, 69 + "thumb": { 70 + "type": "string", 71 + "format": "uri" 72 + }, 73 + "title": { 74 + "type": "string" 75 + }, 76 + "description": { 77 + "type": "string" 78 + } 79 + } 80 + } 81 + } 82 + }
+91
lexicons/app/bsky/embed/images.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.embed.images", 4 + "description": "A set of images embedded in a Bluesky record (eg, a post).", 5 + "defs": { 6 + "main": { 7 + "type": "object", 8 + "required": [ 9 + "images" 10 + ], 11 + "properties": { 12 + "images": { 13 + "type": "array", 14 + "items": { 15 + "ref": "#image", 16 + "type": "ref" 17 + }, 18 + "maxLength": 4 19 + } 20 + } 21 + }, 22 + "view": { 23 + "type": "object", 24 + "required": [ 25 + "images" 26 + ], 27 + "properties": { 28 + "images": { 29 + "type": "array", 30 + "items": { 31 + "ref": "#viewImage", 32 + "type": "ref" 33 + }, 34 + "maxLength": 4 35 + } 36 + } 37 + }, 38 + "image": { 39 + "type": "object", 40 + "required": [ 41 + "image", 42 + "alt" 43 + ], 44 + "properties": { 45 + "alt": { 46 + "type": "string", 47 + "description": "Alt text description of the image, for accessibility." 48 + }, 49 + "image": { 50 + "type": "blob", 51 + "accept": [ 52 + "image/*" 53 + ], 54 + "maxSize": 1000000 55 + }, 56 + "aspectRatio": { 57 + "ref": "app.bsky.embed.defs#aspectRatio", 58 + "type": "ref" 59 + } 60 + } 61 + }, 62 + "viewImage": { 63 + "type": "object", 64 + "required": [ 65 + "thumb", 66 + "fullsize", 67 + "alt" 68 + ], 69 + "properties": { 70 + "alt": { 71 + "type": "string", 72 + "description": "Alt text description of the image, for accessibility." 73 + }, 74 + "thumb": { 75 + "type": "string", 76 + "format": "uri", 77 + "description": "Fully-qualified URL where a thumbnail of the image can be fetched. For example, CDN location provided by the App View." 78 + }, 79 + "fullsize": { 80 + "type": "string", 81 + "format": "uri", 82 + "description": "Fully-qualified URL where a large version of the image can be fetched. May or may not be the exact original blob. For example, CDN location provided by the App View." 83 + }, 84 + "aspectRatio": { 85 + "ref": "app.bsky.embed.defs#aspectRatio", 86 + "type": "ref" 87 + } 88 + } 89 + } 90 + } 91 + }
+160
lexicons/app/bsky/embed/record.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.embed.record", 4 + "description": "A representation of a record embedded in a Bluesky record (eg, a post). For example, a quote-post, or sharing a feed generator record.", 5 + "defs": { 6 + "main": { 7 + "type": "object", 8 + "required": [ 9 + "record" 10 + ], 11 + "properties": { 12 + "record": { 13 + "ref": "com.atproto.repo.strongRef", 14 + "type": "ref" 15 + } 16 + } 17 + }, 18 + "view": { 19 + "type": "object", 20 + "required": [ 21 + "record" 22 + ], 23 + "properties": { 24 + "record": { 25 + "refs": [ 26 + "#viewRecord", 27 + "#viewNotFound", 28 + "#viewBlocked", 29 + "#viewDetached", 30 + "app.bsky.feed.defs#generatorView", 31 + "app.bsky.graph.defs#listView", 32 + "app.bsky.labeler.defs#labelerView", 33 + "app.bsky.graph.defs#starterPackViewBasic" 34 + ], 35 + "type": "union" 36 + } 37 + } 38 + }, 39 + "viewRecord": { 40 + "type": "object", 41 + "required": [ 42 + "uri", 43 + "cid", 44 + "author", 45 + "value", 46 + "indexedAt" 47 + ], 48 + "properties": { 49 + "cid": { 50 + "type": "string", 51 + "format": "cid" 52 + }, 53 + "uri": { 54 + "type": "string", 55 + "format": "at-uri" 56 + }, 57 + "value": { 58 + "type": "unknown", 59 + "description": "The record data itself." 60 + }, 61 + "author": { 62 + "ref": "app.bsky.actor.defs#profileViewBasic", 63 + "type": "ref" 64 + }, 65 + "embeds": { 66 + "type": "array", 67 + "items": { 68 + "refs": [ 69 + "app.bsky.embed.images#view", 70 + "app.bsky.embed.video#view", 71 + "app.bsky.embed.external#view", 72 + "app.bsky.embed.record#view", 73 + "app.bsky.embed.recordWithMedia#view" 74 + ], 75 + "type": "union" 76 + } 77 + }, 78 + "labels": { 79 + "type": "array", 80 + "items": { 81 + "ref": "com.atproto.label.defs#label", 82 + "type": "ref" 83 + } 84 + }, 85 + "indexedAt": { 86 + "type": "string", 87 + "format": "datetime" 88 + }, 89 + "likeCount": { 90 + "type": "integer" 91 + }, 92 + "quoteCount": { 93 + "type": "integer" 94 + }, 95 + "replyCount": { 96 + "type": "integer" 97 + }, 98 + "repostCount": { 99 + "type": "integer" 100 + } 101 + } 102 + }, 103 + "viewBlocked": { 104 + "type": "object", 105 + "required": [ 106 + "uri", 107 + "blocked", 108 + "author" 109 + ], 110 + "properties": { 111 + "uri": { 112 + "type": "string", 113 + "format": "at-uri" 114 + }, 115 + "author": { 116 + "ref": "app.bsky.feed.defs#blockedAuthor", 117 + "type": "ref" 118 + }, 119 + "blocked": { 120 + "type": "boolean", 121 + "const": true 122 + } 123 + } 124 + }, 125 + "viewDetached": { 126 + "type": "object", 127 + "required": [ 128 + "uri", 129 + "detached" 130 + ], 131 + "properties": { 132 + "uri": { 133 + "type": "string", 134 + "format": "at-uri" 135 + }, 136 + "detached": { 137 + "type": "boolean", 138 + "const": true 139 + } 140 + } 141 + }, 142 + "viewNotFound": { 143 + "type": "object", 144 + "required": [ 145 + "uri", 146 + "notFound" 147 + ], 148 + "properties": { 149 + "uri": { 150 + "type": "string", 151 + "format": "at-uri" 152 + }, 153 + "notFound": { 154 + "type": "boolean", 155 + "const": true 156 + } 157 + } 158 + } 159 + } 160 + }
+49
lexicons/app/bsky/embed/recordWithMedia.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.embed.recordWithMedia", 4 + "description": "A representation of a record embedded in a Bluesky record (eg, a post), alongside other compatible embeds. For example, a quote post and image, or a quote post and external URL card.", 5 + "defs": { 6 + "main": { 7 + "type": "object", 8 + "required": [ 9 + "record", 10 + "media" 11 + ], 12 + "properties": { 13 + "media": { 14 + "refs": [ 15 + "app.bsky.embed.images", 16 + "app.bsky.embed.video", 17 + "app.bsky.embed.external" 18 + ], 19 + "type": "union" 20 + }, 21 + "record": { 22 + "ref": "app.bsky.embed.record", 23 + "type": "ref" 24 + } 25 + } 26 + }, 27 + "view": { 28 + "type": "object", 29 + "required": [ 30 + "record", 31 + "media" 32 + ], 33 + "properties": { 34 + "media": { 35 + "refs": [ 36 + "app.bsky.embed.images#view", 37 + "app.bsky.embed.video#view", 38 + "app.bsky.embed.external#view" 39 + ], 40 + "type": "union" 41 + }, 42 + "record": { 43 + "ref": "app.bsky.embed.record#view", 44 + "type": "ref" 45 + } 46 + } 47 + } 48 + } 49 + }
+90
lexicons/app/bsky/embed/video.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.embed.video", 4 + "description": "A video embedded in a Bluesky record (eg, a post).", 5 + "defs": { 6 + "main": { 7 + "type": "object", 8 + "required": [ 9 + "video" 10 + ], 11 + "properties": { 12 + "alt": { 13 + "type": "string", 14 + "maxLength": 10000, 15 + "description": "Alt text description of the video, for accessibility.", 16 + "maxGraphemes": 1000 17 + }, 18 + "video": { 19 + "type": "blob", 20 + "accept": [ 21 + "video/mp4" 22 + ], 23 + "maxSize": 50000000 24 + }, 25 + "captions": { 26 + "type": "array", 27 + "items": { 28 + "ref": "#caption", 29 + "type": "ref" 30 + }, 31 + "maxLength": 20 32 + }, 33 + "aspectRatio": { 34 + "ref": "app.bsky.embed.defs#aspectRatio", 35 + "type": "ref" 36 + } 37 + } 38 + }, 39 + "view": { 40 + "type": "object", 41 + "required": [ 42 + "cid", 43 + "playlist" 44 + ], 45 + "properties": { 46 + "alt": { 47 + "type": "string", 48 + "maxLength": 10000, 49 + "maxGraphemes": 1000 50 + }, 51 + "cid": { 52 + "type": "string", 53 + "format": "cid" 54 + }, 55 + "playlist": { 56 + "type": "string", 57 + "format": "uri" 58 + }, 59 + "thumbnail": { 60 + "type": "string", 61 + "format": "uri" 62 + }, 63 + "aspectRatio": { 64 + "ref": "app.bsky.embed.defs#aspectRatio", 65 + "type": "ref" 66 + } 67 + } 68 + }, 69 + "caption": { 70 + "type": "object", 71 + "required": [ 72 + "lang", 73 + "file" 74 + ], 75 + "properties": { 76 + "file": { 77 + "type": "blob", 78 + "accept": [ 79 + "text/vtt" 80 + ], 81 + "maxSize": 20000 82 + }, 83 + "lang": { 84 + "type": "string", 85 + "format": "language" 86 + } 87 + } 88 + } 89 + } 90 + }
+515
lexicons/app/bsky/feed/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.feed.defs", 4 + "defs": { 5 + "postView": { 6 + "type": "object", 7 + "required": [ 8 + "uri", 9 + "cid", 10 + "author", 11 + "record", 12 + "indexedAt" 13 + ], 14 + "properties": { 15 + "cid": { 16 + "type": "string", 17 + "format": "cid" 18 + }, 19 + "uri": { 20 + "type": "string", 21 + "format": "at-uri" 22 + }, 23 + "embed": { 24 + "refs": [ 25 + "app.bsky.embed.images#view", 26 + "app.bsky.embed.video#view", 27 + "app.bsky.embed.external#view", 28 + "app.bsky.embed.record#view", 29 + "app.bsky.embed.recordWithMedia#view" 30 + ], 31 + "type": "union" 32 + }, 33 + "author": { 34 + "ref": "app.bsky.actor.defs#profileViewBasic", 35 + "type": "ref" 36 + }, 37 + "labels": { 38 + "type": "array", 39 + "items": { 40 + "ref": "com.atproto.label.defs#label", 41 + "type": "ref" 42 + } 43 + }, 44 + "record": { 45 + "type": "unknown" 46 + }, 47 + "viewer": { 48 + "ref": "#viewerState", 49 + "type": "ref" 50 + }, 51 + "indexedAt": { 52 + "type": "string", 53 + "format": "datetime" 54 + }, 55 + "likeCount": { 56 + "type": "integer" 57 + }, 58 + "quoteCount": { 59 + "type": "integer" 60 + }, 61 + "replyCount": { 62 + "type": "integer" 63 + }, 64 + "threadgate": { 65 + "ref": "#threadgateView", 66 + "type": "ref" 67 + }, 68 + "repostCount": { 69 + "type": "integer" 70 + } 71 + } 72 + }, 73 + "replyRef": { 74 + "type": "object", 75 + "required": [ 76 + "root", 77 + "parent" 78 + ], 79 + "properties": { 80 + "root": { 81 + "refs": [ 82 + "#postView", 83 + "#notFoundPost", 84 + "#blockedPost" 85 + ], 86 + "type": "union" 87 + }, 88 + "parent": { 89 + "refs": [ 90 + "#postView", 91 + "#notFoundPost", 92 + "#blockedPost" 93 + ], 94 + "type": "union" 95 + }, 96 + "grandparentAuthor": { 97 + "ref": "app.bsky.actor.defs#profileViewBasic", 98 + "type": "ref", 99 + "description": "When parent is a reply to another post, this is the author of that post." 100 + } 101 + } 102 + }, 103 + "reasonPin": { 104 + "type": "object", 105 + "properties": {} 106 + }, 107 + "blockedPost": { 108 + "type": "object", 109 + "required": [ 110 + "uri", 111 + "blocked", 112 + "author" 113 + ], 114 + "properties": { 115 + "uri": { 116 + "type": "string", 117 + "format": "at-uri" 118 + }, 119 + "author": { 120 + "ref": "#blockedAuthor", 121 + "type": "ref" 122 + }, 123 + "blocked": { 124 + "type": "boolean", 125 + "const": true 126 + } 127 + } 128 + }, 129 + "interaction": { 130 + "type": "object", 131 + "properties": { 132 + "item": { 133 + "type": "string", 134 + "format": "at-uri" 135 + }, 136 + "event": { 137 + "type": "string", 138 + "knownValues": [ 139 + "app.bsky.feed.defs#requestLess", 140 + "app.bsky.feed.defs#requestMore", 141 + "app.bsky.feed.defs#clickthroughItem", 142 + "app.bsky.feed.defs#clickthroughAuthor", 143 + "app.bsky.feed.defs#clickthroughReposter", 144 + "app.bsky.feed.defs#clickthroughEmbed", 145 + "app.bsky.feed.defs#interactionSeen", 146 + "app.bsky.feed.defs#interactionLike", 147 + "app.bsky.feed.defs#interactionRepost", 148 + "app.bsky.feed.defs#interactionReply", 149 + "app.bsky.feed.defs#interactionQuote", 150 + "app.bsky.feed.defs#interactionShare" 151 + ] 152 + }, 153 + "feedContext": { 154 + "type": "string", 155 + "maxLength": 2000, 156 + "description": "Context on a feed item that was originally supplied by the feed generator on getFeedSkeleton." 157 + } 158 + } 159 + }, 160 + "requestLess": { 161 + "type": "token", 162 + "description": "Request that less content like the given feed item be shown in the feed" 163 + }, 164 + "requestMore": { 165 + "type": "token", 166 + "description": "Request that more content like the given feed item be shown in the feed" 167 + }, 168 + "viewerState": { 169 + "type": "object", 170 + "properties": { 171 + "like": { 172 + "type": "string", 173 + "format": "at-uri" 174 + }, 175 + "pinned": { 176 + "type": "boolean" 177 + }, 178 + "repost": { 179 + "type": "string", 180 + "format": "at-uri" 181 + }, 182 + "threadMuted": { 183 + "type": "boolean" 184 + }, 185 + "replyDisabled": { 186 + "type": "boolean" 187 + }, 188 + "embeddingDisabled": { 189 + "type": "boolean" 190 + } 191 + }, 192 + "description": "Metadata about the requesting account's relationship with the subject content. Only has meaningful content for authed requests." 193 + }, 194 + "feedViewPost": { 195 + "type": "object", 196 + "required": [ 197 + "post" 198 + ], 199 + "properties": { 200 + "post": { 201 + "ref": "#postView", 202 + "type": "ref" 203 + }, 204 + "reply": { 205 + "ref": "#replyRef", 206 + "type": "ref" 207 + }, 208 + "reason": { 209 + "refs": [ 210 + "#reasonRepost", 211 + "#reasonPin" 212 + ], 213 + "type": "union" 214 + }, 215 + "feedContext": { 216 + "type": "string", 217 + "maxLength": 2000, 218 + "description": "Context provided by feed generator that may be passed back alongside interactions." 219 + } 220 + } 221 + }, 222 + "notFoundPost": { 223 + "type": "object", 224 + "required": [ 225 + "uri", 226 + "notFound" 227 + ], 228 + "properties": { 229 + "uri": { 230 + "type": "string", 231 + "format": "at-uri" 232 + }, 233 + "notFound": { 234 + "type": "boolean", 235 + "const": true 236 + } 237 + } 238 + }, 239 + "reasonRepost": { 240 + "type": "object", 241 + "required": [ 242 + "by", 243 + "indexedAt" 244 + ], 245 + "properties": { 246 + "by": { 247 + "ref": "app.bsky.actor.defs#profileViewBasic", 248 + "type": "ref" 249 + }, 250 + "indexedAt": { 251 + "type": "string", 252 + "format": "datetime" 253 + } 254 + } 255 + }, 256 + "blockedAuthor": { 257 + "type": "object", 258 + "required": [ 259 + "did" 260 + ], 261 + "properties": { 262 + "did": { 263 + "type": "string", 264 + "format": "did" 265 + }, 266 + "viewer": { 267 + "ref": "app.bsky.actor.defs#viewerState", 268 + "type": "ref" 269 + } 270 + } 271 + }, 272 + "generatorView": { 273 + "type": "object", 274 + "required": [ 275 + "uri", 276 + "cid", 277 + "did", 278 + "creator", 279 + "displayName", 280 + "indexedAt" 281 + ], 282 + "properties": { 283 + "cid": { 284 + "type": "string", 285 + "format": "cid" 286 + }, 287 + "did": { 288 + "type": "string", 289 + "format": "did" 290 + }, 291 + "uri": { 292 + "type": "string", 293 + "format": "at-uri" 294 + }, 295 + "avatar": { 296 + "type": "string", 297 + "format": "uri" 298 + }, 299 + "labels": { 300 + "type": "array", 301 + "items": { 302 + "ref": "com.atproto.label.defs#label", 303 + "type": "ref" 304 + } 305 + }, 306 + "viewer": { 307 + "ref": "#generatorViewerState", 308 + "type": "ref" 309 + }, 310 + "creator": { 311 + "ref": "app.bsky.actor.defs#profileView", 312 + "type": "ref" 313 + }, 314 + "indexedAt": { 315 + "type": "string", 316 + "format": "datetime" 317 + }, 318 + "likeCount": { 319 + "type": "integer", 320 + "minimum": 0 321 + }, 322 + "contentMode": { 323 + "type": "string", 324 + "knownValues": [ 325 + "app.bsky.feed.defs#contentModeUnspecified", 326 + "app.bsky.feed.defs#contentModeVideo" 327 + ] 328 + }, 329 + "description": { 330 + "type": "string", 331 + "maxLength": 3000, 332 + "maxGraphemes": 300 333 + }, 334 + "displayName": { 335 + "type": "string" 336 + }, 337 + "descriptionFacets": { 338 + "type": "array", 339 + "items": { 340 + "ref": "app.bsky.richtext.facet", 341 + "type": "ref" 342 + } 343 + }, 344 + "acceptsInteractions": { 345 + "type": "boolean" 346 + } 347 + } 348 + }, 349 + "threadContext": { 350 + "type": "object", 351 + "properties": { 352 + "rootAuthorLike": { 353 + "type": "string", 354 + "format": "at-uri" 355 + } 356 + }, 357 + "description": "Metadata about this post within the context of the thread it is in." 358 + }, 359 + "threadViewPost": { 360 + "type": "object", 361 + "required": [ 362 + "post" 363 + ], 364 + "properties": { 365 + "post": { 366 + "ref": "#postView", 367 + "type": "ref" 368 + }, 369 + "parent": { 370 + "refs": [ 371 + "#threadViewPost", 372 + "#notFoundPost", 373 + "#blockedPost" 374 + ], 375 + "type": "union" 376 + }, 377 + "replies": { 378 + "type": "array", 379 + "items": { 380 + "refs": [ 381 + "#threadViewPost", 382 + "#notFoundPost", 383 + "#blockedPost" 384 + ], 385 + "type": "union" 386 + } 387 + }, 388 + "threadContext": { 389 + "ref": "#threadContext", 390 + "type": "ref" 391 + } 392 + } 393 + }, 394 + "threadgateView": { 395 + "type": "object", 396 + "properties": { 397 + "cid": { 398 + "type": "string", 399 + "format": "cid" 400 + }, 401 + "uri": { 402 + "type": "string", 403 + "format": "at-uri" 404 + }, 405 + "lists": { 406 + "type": "array", 407 + "items": { 408 + "ref": "app.bsky.graph.defs#listViewBasic", 409 + "type": "ref" 410 + } 411 + }, 412 + "record": { 413 + "type": "unknown" 414 + } 415 + } 416 + }, 417 + "interactionLike": { 418 + "type": "token", 419 + "description": "User liked the feed item" 420 + }, 421 + "interactionSeen": { 422 + "type": "token", 423 + "description": "Feed item was seen by user" 424 + }, 425 + "clickthroughItem": { 426 + "type": "token", 427 + "description": "User clicked through to the feed item" 428 + }, 429 + "contentModeVideo": { 430 + "type": "token", 431 + "description": "Declares the feed generator returns posts containing app.bsky.embed.video embeds." 432 + }, 433 + "interactionQuote": { 434 + "type": "token", 435 + "description": "User quoted the feed item" 436 + }, 437 + "interactionReply": { 438 + "type": "token", 439 + "description": "User replied to the feed item" 440 + }, 441 + "interactionShare": { 442 + "type": "token", 443 + "description": "User shared the feed item" 444 + }, 445 + "skeletonFeedPost": { 446 + "type": "object", 447 + "required": [ 448 + "post" 449 + ], 450 + "properties": { 451 + "post": { 452 + "type": "string", 453 + "format": "at-uri" 454 + }, 455 + "reason": { 456 + "refs": [ 457 + "#skeletonReasonRepost", 458 + "#skeletonReasonPin" 459 + ], 460 + "type": "union" 461 + }, 462 + "feedContext": { 463 + "type": "string", 464 + "maxLength": 2000, 465 + "description": "Context that will be passed through to client and may be passed to feed generator back alongside interactions." 466 + } 467 + } 468 + }, 469 + "clickthroughEmbed": { 470 + "type": "token", 471 + "description": "User clicked through to the embedded content of the feed item" 472 + }, 473 + "interactionRepost": { 474 + "type": "token", 475 + "description": "User reposted the feed item" 476 + }, 477 + "skeletonReasonPin": { 478 + "type": "object", 479 + "properties": {} 480 + }, 481 + "clickthroughAuthor": { 482 + "type": "token", 483 + "description": "User clicked through to the author of the feed item" 484 + }, 485 + "clickthroughReposter": { 486 + "type": "token", 487 + "description": "User clicked through to the reposter of the feed item" 488 + }, 489 + "generatorViewerState": { 490 + "type": "object", 491 + "properties": { 492 + "like": { 493 + "type": "string", 494 + "format": "at-uri" 495 + } 496 + } 497 + }, 498 + "skeletonReasonRepost": { 499 + "type": "object", 500 + "required": [ 501 + "repost" 502 + ], 503 + "properties": { 504 + "repost": { 505 + "type": "string", 506 + "format": "at-uri" 507 + } 508 + } 509 + }, 510 + "contentModeUnspecified": { 511 + "type": "token", 512 + "description": "Declares the feed generator returns any types of posts." 513 + } 514 + } 515 + }
+54
lexicons/app/bsky/feed/postgate.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.feed.postgate", 4 + "defs": { 5 + "main": { 6 + "key": "tid", 7 + "type": "record", 8 + "record": { 9 + "type": "object", 10 + "required": [ 11 + "post", 12 + "createdAt" 13 + ], 14 + "properties": { 15 + "post": { 16 + "type": "string", 17 + "format": "at-uri", 18 + "description": "Reference (AT-URI) to the post record." 19 + }, 20 + "createdAt": { 21 + "type": "string", 22 + "format": "datetime" 23 + }, 24 + "embeddingRules": { 25 + "type": "array", 26 + "items": { 27 + "refs": [ 28 + "#disableRule" 29 + ], 30 + "type": "union" 31 + }, 32 + "maxLength": 5, 33 + "description": "List of rules defining who can embed this post. If value is an empty array or is undefined, no particular rules apply and anyone can embed." 34 + }, 35 + "detachedEmbeddingUris": { 36 + "type": "array", 37 + "items": { 38 + "type": "string", 39 + "format": "at-uri" 40 + }, 41 + "maxLength": 50, 42 + "description": "List of AT-URIs embedding this post that the author has detached from." 43 + } 44 + } 45 + }, 46 + "description": "Record defining interaction rules for a post. The record key (rkey) of the postgate record must match the record key of the post, and that record must be in the same repository." 47 + }, 48 + "disableRule": { 49 + "type": "object", 50 + "properties": {}, 51 + "description": "Disables embedding of this post." 52 + } 53 + } 54 + }
+80
lexicons/app/bsky/feed/threadgate.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.feed.threadgate", 4 + "defs": { 5 + "main": { 6 + "key": "tid", 7 + "type": "record", 8 + "record": { 9 + "type": "object", 10 + "required": [ 11 + "post", 12 + "createdAt" 13 + ], 14 + "properties": { 15 + "post": { 16 + "type": "string", 17 + "format": "at-uri", 18 + "description": "Reference (AT-URI) to the post record." 19 + }, 20 + "allow": { 21 + "type": "array", 22 + "items": { 23 + "refs": [ 24 + "#mentionRule", 25 + "#followerRule", 26 + "#followingRule", 27 + "#listRule" 28 + ], 29 + "type": "union" 30 + }, 31 + "maxLength": 5, 32 + "description": "List of rules defining who can reply to this post. If value is an empty array, no one can reply. If value is undefined, anyone can reply." 33 + }, 34 + "createdAt": { 35 + "type": "string", 36 + "format": "datetime" 37 + }, 38 + "hiddenReplies": { 39 + "type": "array", 40 + "items": { 41 + "type": "string", 42 + "format": "at-uri" 43 + }, 44 + "maxLength": 50, 45 + "description": "List of hidden reply URIs." 46 + } 47 + } 48 + }, 49 + "description": "Record defining interaction gating rules for a thread (aka, reply controls). The record key (rkey) of the threadgate record must match the record key of the thread's root post, and that record must be in the same repository." 50 + }, 51 + "listRule": { 52 + "type": "object", 53 + "required": [ 54 + "list" 55 + ], 56 + "properties": { 57 + "list": { 58 + "type": "string", 59 + "format": "at-uri" 60 + } 61 + }, 62 + "description": "Allow replies from actors on a list." 63 + }, 64 + "mentionRule": { 65 + "type": "object", 66 + "properties": {}, 67 + "description": "Allow replies from actors mentioned in your post." 68 + }, 69 + "followerRule": { 70 + "type": "object", 71 + "properties": {}, 72 + "description": "Allow replies from actors who follow you." 73 + }, 74 + "followingRule": { 75 + "type": "object", 76 + "properties": {}, 77 + "description": "Allow replies from actors you follow." 78 + } 79 + } 80 + }
+332
lexicons/app/bsky/graph/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.graph.defs", 4 + "defs": { 5 + "modlist": { 6 + "type": "token", 7 + "description": "A list of actors to apply an aggregate moderation action (mute/block) on." 8 + }, 9 + "listView": { 10 + "type": "object", 11 + "required": [ 12 + "uri", 13 + "cid", 14 + "creator", 15 + "name", 16 + "purpose", 17 + "indexedAt" 18 + ], 19 + "properties": { 20 + "cid": { 21 + "type": "string", 22 + "format": "cid" 23 + }, 24 + "uri": { 25 + "type": "string", 26 + "format": "at-uri" 27 + }, 28 + "name": { 29 + "type": "string", 30 + "maxLength": 64, 31 + "minLength": 1 32 + }, 33 + "avatar": { 34 + "type": "string", 35 + "format": "uri" 36 + }, 37 + "labels": { 38 + "type": "array", 39 + "items": { 40 + "ref": "com.atproto.label.defs#label", 41 + "type": "ref" 42 + } 43 + }, 44 + "viewer": { 45 + "ref": "#listViewerState", 46 + "type": "ref" 47 + }, 48 + "creator": { 49 + "ref": "app.bsky.actor.defs#profileView", 50 + "type": "ref" 51 + }, 52 + "purpose": { 53 + "ref": "#listPurpose", 54 + "type": "ref" 55 + }, 56 + "indexedAt": { 57 + "type": "string", 58 + "format": "datetime" 59 + }, 60 + "description": { 61 + "type": "string", 62 + "maxLength": 3000, 63 + "maxGraphemes": 300 64 + }, 65 + "listItemCount": { 66 + "type": "integer", 67 + "minimum": 0 68 + }, 69 + "descriptionFacets": { 70 + "type": "array", 71 + "items": { 72 + "ref": "app.bsky.richtext.facet", 73 + "type": "ref" 74 + } 75 + } 76 + } 77 + }, 78 + "curatelist": { 79 + "type": "token", 80 + "description": "A list of actors used for curation purposes such as list feeds or interaction gating." 81 + }, 82 + "listPurpose": { 83 + "type": "string", 84 + "knownValues": [ 85 + "app.bsky.graph.defs#modlist", 86 + "app.bsky.graph.defs#curatelist", 87 + "app.bsky.graph.defs#referencelist" 88 + ] 89 + }, 90 + "listItemView": { 91 + "type": "object", 92 + "required": [ 93 + "uri", 94 + "subject" 95 + ], 96 + "properties": { 97 + "uri": { 98 + "type": "string", 99 + "format": "at-uri" 100 + }, 101 + "subject": { 102 + "ref": "app.bsky.actor.defs#profileView", 103 + "type": "ref" 104 + } 105 + } 106 + }, 107 + "relationship": { 108 + "type": "object", 109 + "required": [ 110 + "did" 111 + ], 112 + "properties": { 113 + "did": { 114 + "type": "string", 115 + "format": "did" 116 + }, 117 + "following": { 118 + "type": "string", 119 + "format": "at-uri", 120 + "description": "if the actor follows this DID, this is the AT-URI of the follow record" 121 + }, 122 + "followedBy": { 123 + "type": "string", 124 + "format": "at-uri", 125 + "description": "if the actor is followed by this DID, contains the AT-URI of the follow record" 126 + } 127 + }, 128 + "description": "lists the bi-directional graph relationships between one actor (not indicated in the object), and the target actors (the DID included in the object)" 129 + }, 130 + "listViewBasic": { 131 + "type": "object", 132 + "required": [ 133 + "uri", 134 + "cid", 135 + "name", 136 + "purpose" 137 + ], 138 + "properties": { 139 + "cid": { 140 + "type": "string", 141 + "format": "cid" 142 + }, 143 + "uri": { 144 + "type": "string", 145 + "format": "at-uri" 146 + }, 147 + "name": { 148 + "type": "string", 149 + "maxLength": 64, 150 + "minLength": 1 151 + }, 152 + "avatar": { 153 + "type": "string", 154 + "format": "uri" 155 + }, 156 + "labels": { 157 + "type": "array", 158 + "items": { 159 + "ref": "com.atproto.label.defs#label", 160 + "type": "ref" 161 + } 162 + }, 163 + "viewer": { 164 + "ref": "#listViewerState", 165 + "type": "ref" 166 + }, 167 + "purpose": { 168 + "ref": "#listPurpose", 169 + "type": "ref" 170 + }, 171 + "indexedAt": { 172 + "type": "string", 173 + "format": "datetime" 174 + }, 175 + "listItemCount": { 176 + "type": "integer", 177 + "minimum": 0 178 + } 179 + } 180 + }, 181 + "notFoundActor": { 182 + "type": "object", 183 + "required": [ 184 + "actor", 185 + "notFound" 186 + ], 187 + "properties": { 188 + "actor": { 189 + "type": "string", 190 + "format": "at-identifier" 191 + }, 192 + "notFound": { 193 + "type": "boolean", 194 + "const": true 195 + } 196 + }, 197 + "description": "indicates that a handle or DID could not be resolved" 198 + }, 199 + "referencelist": { 200 + "type": "token", 201 + "description": "A list of actors used for only for reference purposes such as within a starter pack." 202 + }, 203 + "listViewerState": { 204 + "type": "object", 205 + "properties": { 206 + "muted": { 207 + "type": "boolean" 208 + }, 209 + "blocked": { 210 + "type": "string", 211 + "format": "at-uri" 212 + } 213 + } 214 + }, 215 + "starterPackView": { 216 + "type": "object", 217 + "required": [ 218 + "uri", 219 + "cid", 220 + "record", 221 + "creator", 222 + "indexedAt" 223 + ], 224 + "properties": { 225 + "cid": { 226 + "type": "string", 227 + "format": "cid" 228 + }, 229 + "uri": { 230 + "type": "string", 231 + "format": "at-uri" 232 + }, 233 + "list": { 234 + "ref": "#listViewBasic", 235 + "type": "ref" 236 + }, 237 + "feeds": { 238 + "type": "array", 239 + "items": { 240 + "ref": "app.bsky.feed.defs#generatorView", 241 + "type": "ref" 242 + }, 243 + "maxLength": 3 244 + }, 245 + "labels": { 246 + "type": "array", 247 + "items": { 248 + "ref": "com.atproto.label.defs#label", 249 + "type": "ref" 250 + } 251 + }, 252 + "record": { 253 + "type": "unknown" 254 + }, 255 + "creator": { 256 + "ref": "app.bsky.actor.defs#profileViewBasic", 257 + "type": "ref" 258 + }, 259 + "indexedAt": { 260 + "type": "string", 261 + "format": "datetime" 262 + }, 263 + "joinedWeekCount": { 264 + "type": "integer", 265 + "minimum": 0 266 + }, 267 + "listItemsSample": { 268 + "type": "array", 269 + "items": { 270 + "ref": "#listItemView", 271 + "type": "ref" 272 + }, 273 + "maxLength": 12 274 + }, 275 + "joinedAllTimeCount": { 276 + "type": "integer", 277 + "minimum": 0 278 + } 279 + } 280 + }, 281 + "starterPackViewBasic": { 282 + "type": "object", 283 + "required": [ 284 + "uri", 285 + "cid", 286 + "record", 287 + "creator", 288 + "indexedAt" 289 + ], 290 + "properties": { 291 + "cid": { 292 + "type": "string", 293 + "format": "cid" 294 + }, 295 + "uri": { 296 + "type": "string", 297 + "format": "at-uri" 298 + }, 299 + "labels": { 300 + "type": "array", 301 + "items": { 302 + "ref": "com.atproto.label.defs#label", 303 + "type": "ref" 304 + } 305 + }, 306 + "record": { 307 + "type": "unknown" 308 + }, 309 + "creator": { 310 + "ref": "app.bsky.actor.defs#profileViewBasic", 311 + "type": "ref" 312 + }, 313 + "indexedAt": { 314 + "type": "string", 315 + "format": "datetime" 316 + }, 317 + "listItemCount": { 318 + "type": "integer", 319 + "minimum": 0 320 + }, 321 + "joinedWeekCount": { 322 + "type": "integer", 323 + "minimum": 0 324 + }, 325 + "joinedAllTimeCount": { 326 + "type": "integer", 327 + "minimum": 0 328 + } 329 + } 330 + } 331 + } 332 + }
+28
lexicons/app/bsky/graph/follow.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.graph.follow", 4 + "defs": { 5 + "main": { 6 + "key": "tid", 7 + "type": "record", 8 + "record": { 9 + "type": "object", 10 + "required": [ 11 + "subject", 12 + "createdAt" 13 + ], 14 + "properties": { 15 + "subject": { 16 + "type": "string", 17 + "format": "did" 18 + }, 19 + "createdAt": { 20 + "type": "string", 21 + "format": "datetime" 22 + } 23 + } 24 + }, 25 + "description": "Record declaring a social 'follow' relationship of another account. Duplicate follows will be ignored by the AppView." 26 + } 27 + } 28 + }
+128
lexicons/app/bsky/labeler/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.labeler.defs", 4 + "defs": { 5 + "labelerView": { 6 + "type": "object", 7 + "required": [ 8 + "uri", 9 + "cid", 10 + "creator", 11 + "indexedAt" 12 + ], 13 + "properties": { 14 + "cid": { 15 + "type": "string", 16 + "format": "cid" 17 + }, 18 + "uri": { 19 + "type": "string", 20 + "format": "at-uri" 21 + }, 22 + "labels": { 23 + "type": "array", 24 + "items": { 25 + "ref": "com.atproto.label.defs#label", 26 + "type": "ref" 27 + } 28 + }, 29 + "viewer": { 30 + "ref": "#labelerViewerState", 31 + "type": "ref" 32 + }, 33 + "creator": { 34 + "ref": "app.bsky.actor.defs#profileView", 35 + "type": "ref" 36 + }, 37 + "indexedAt": { 38 + "type": "string", 39 + "format": "datetime" 40 + }, 41 + "likeCount": { 42 + "type": "integer", 43 + "minimum": 0 44 + } 45 + } 46 + }, 47 + "labelerPolicies": { 48 + "type": "object", 49 + "required": [ 50 + "labelValues" 51 + ], 52 + "properties": { 53 + "labelValues": { 54 + "type": "array", 55 + "items": { 56 + "ref": "com.atproto.label.defs#labelValue", 57 + "type": "ref" 58 + }, 59 + "description": "The label values which this labeler publishes. May include global or custom labels." 60 + }, 61 + "labelValueDefinitions": { 62 + "type": "array", 63 + "items": { 64 + "ref": "com.atproto.label.defs#labelValueDefinition", 65 + "type": "ref" 66 + }, 67 + "description": "Label values created by this labeler and scoped exclusively to it. Labels defined here will override global label definitions for this labeler." 68 + } 69 + } 70 + }, 71 + "labelerViewerState": { 72 + "type": "object", 73 + "properties": { 74 + "like": { 75 + "type": "string", 76 + "format": "at-uri" 77 + } 78 + } 79 + }, 80 + "labelerViewDetailed": { 81 + "type": "object", 82 + "required": [ 83 + "uri", 84 + "cid", 85 + "creator", 86 + "policies", 87 + "indexedAt" 88 + ], 89 + "properties": { 90 + "cid": { 91 + "type": "string", 92 + "format": "cid" 93 + }, 94 + "uri": { 95 + "type": "string", 96 + "format": "at-uri" 97 + }, 98 + "labels": { 99 + "type": "array", 100 + "items": { 101 + "ref": "com.atproto.label.defs#label", 102 + "type": "ref" 103 + } 104 + }, 105 + "viewer": { 106 + "ref": "#labelerViewerState", 107 + "type": "ref" 108 + }, 109 + "creator": { 110 + "ref": "app.bsky.actor.defs#profileView", 111 + "type": "ref" 112 + }, 113 + "policies": { 114 + "ref": "app.bsky.labeler.defs#labelerPolicies", 115 + "type": "ref" 116 + }, 117 + "indexedAt": { 118 + "type": "string", 119 + "format": "datetime" 120 + }, 121 + "likeCount": { 122 + "type": "integer", 123 + "minimum": 0 124 + } 125 + } 126 + } 127 + } 128 + }
+89
lexicons/app/bsky/richtext/facet.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.richtext.facet", 4 + "defs": { 5 + "tag": { 6 + "type": "object", 7 + "required": [ 8 + "tag" 9 + ], 10 + "properties": { 11 + "tag": { 12 + "type": "string", 13 + "maxLength": 640, 14 + "maxGraphemes": 64 15 + } 16 + }, 17 + "description": "Facet feature for a hashtag. The text usually includes a '#' prefix, but the facet reference should not (except in the case of 'double hash tags')." 18 + }, 19 + "link": { 20 + "type": "object", 21 + "required": [ 22 + "uri" 23 + ], 24 + "properties": { 25 + "uri": { 26 + "type": "string", 27 + "format": "uri" 28 + } 29 + }, 30 + "description": "Facet feature for a URL. The text URL may have been simplified or truncated, but the facet reference should be a complete URL." 31 + }, 32 + "main": { 33 + "type": "object", 34 + "required": [ 35 + "index", 36 + "features" 37 + ], 38 + "properties": { 39 + "index": { 40 + "ref": "#byteSlice", 41 + "type": "ref" 42 + }, 43 + "features": { 44 + "type": "array", 45 + "items": { 46 + "refs": [ 47 + "#mention", 48 + "#link", 49 + "#tag" 50 + ], 51 + "type": "union" 52 + } 53 + } 54 + }, 55 + "description": "Annotation of a sub-string within rich text." 56 + }, 57 + "mention": { 58 + "type": "object", 59 + "required": [ 60 + "did" 61 + ], 62 + "properties": { 63 + "did": { 64 + "type": "string", 65 + "format": "did" 66 + } 67 + }, 68 + "description": "Facet feature for mention of another account. The text is usually a handle, including a '@' prefix, but the facet reference is a DID." 69 + }, 70 + "byteSlice": { 71 + "type": "object", 72 + "required": [ 73 + "byteStart", 74 + "byteEnd" 75 + ], 76 + "properties": { 77 + "byteEnd": { 78 + "type": "integer", 79 + "minimum": 0 80 + }, 81 + "byteStart": { 82 + "type": "integer", 83 + "minimum": 0 84 + } 85 + }, 86 + "description": "Specifies the sub-string range a facet feature applies to. Start index is inclusive, end index is exclusive. Indices are zero-indexed, counting bytes of the UTF-8 encoded text. NOTE: some languages, like Javascript, use UTF-16 or Unicode codepoints for string slice indexing; in these languages, convert to byte arrays before working with facets." 87 + } 88 + } 89 + }
+192
lexicons/com/atproto/label/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "com.atproto.label.defs", 4 + "defs": { 5 + "label": { 6 + "type": "object", 7 + "required": [ 8 + "src", 9 + "uri", 10 + "val", 11 + "cts" 12 + ], 13 + "properties": { 14 + "cid": { 15 + "type": "string", 16 + "format": "cid", 17 + "description": "Optionally, CID specifying the specific version of 'uri' resource this label applies to." 18 + }, 19 + "cts": { 20 + "type": "string", 21 + "format": "datetime", 22 + "description": "Timestamp when this label was created." 23 + }, 24 + "exp": { 25 + "type": "string", 26 + "format": "datetime", 27 + "description": "Timestamp at which this label expires (no longer applies)." 28 + }, 29 + "neg": { 30 + "type": "boolean", 31 + "description": "If true, this is a negation label, overwriting a previous label." 32 + }, 33 + "sig": { 34 + "type": "bytes", 35 + "description": "Signature of dag-cbor encoded label." 36 + }, 37 + "src": { 38 + "type": "string", 39 + "format": "did", 40 + "description": "DID of the actor who created this label." 41 + }, 42 + "uri": { 43 + "type": "string", 44 + "format": "uri", 45 + "description": "AT URI of the record, repository (account), or other resource that this label applies to." 46 + }, 47 + "val": { 48 + "type": "string", 49 + "maxLength": 128, 50 + "description": "The short string name of the value or type of this label." 51 + }, 52 + "ver": { 53 + "type": "integer", 54 + "description": "The AT Protocol version of the label object." 55 + } 56 + }, 57 + "description": "Metadata tag on an atproto resource (eg, repo or record)." 58 + }, 59 + "selfLabel": { 60 + "type": "object", 61 + "required": [ 62 + "val" 63 + ], 64 + "properties": { 65 + "val": { 66 + "type": "string", 67 + "maxLength": 128, 68 + "description": "The short string name of the value or type of this label." 69 + } 70 + }, 71 + "description": "Metadata tag on an atproto record, published by the author within the record. Note that schemas should use #selfLabels, not #selfLabel." 72 + }, 73 + "labelValue": { 74 + "type": "string", 75 + "knownValues": [ 76 + "!hide", 77 + "!no-promote", 78 + "!warn", 79 + "!no-unauthenticated", 80 + "dmca-violation", 81 + "doxxing", 82 + "porn", 83 + "sexual", 84 + "nudity", 85 + "nsfl", 86 + "gore" 87 + ] 88 + }, 89 + "selfLabels": { 90 + "type": "object", 91 + "required": [ 92 + "values" 93 + ], 94 + "properties": { 95 + "values": { 96 + "type": "array", 97 + "items": { 98 + "ref": "#selfLabel", 99 + "type": "ref" 100 + }, 101 + "maxLength": 10 102 + } 103 + }, 104 + "description": "Metadata tags on an atproto record, published by the author within the record." 105 + }, 106 + "labelValueDefinition": { 107 + "type": "object", 108 + "required": [ 109 + "identifier", 110 + "severity", 111 + "blurs", 112 + "locales" 113 + ], 114 + "properties": { 115 + "blurs": { 116 + "type": "string", 117 + "description": "What should this label hide in the UI, if applied? 'content' hides all of the target; 'media' hides the images/video/audio; 'none' hides nothing.", 118 + "knownValues": [ 119 + "content", 120 + "media", 121 + "none" 122 + ] 123 + }, 124 + "locales": { 125 + "type": "array", 126 + "items": { 127 + "ref": "#labelValueDefinitionStrings", 128 + "type": "ref" 129 + } 130 + }, 131 + "severity": { 132 + "type": "string", 133 + "description": "How should a client visually convey this label? 'inform' means neutral and informational; 'alert' means negative and warning; 'none' means show nothing.", 134 + "knownValues": [ 135 + "inform", 136 + "alert", 137 + "none" 138 + ] 139 + }, 140 + "adultOnly": { 141 + "type": "boolean", 142 + "description": "Does the user need to have adult content enabled in order to configure this label?" 143 + }, 144 + "identifier": { 145 + "type": "string", 146 + "maxLength": 100, 147 + "description": "The value of the label being defined. Must only include lowercase ascii and the '-' character ([a-z-]+).", 148 + "maxGraphemes": 100 149 + }, 150 + "defaultSetting": { 151 + "type": "string", 152 + "default": "warn", 153 + "description": "The default setting for this label.", 154 + "knownValues": [ 155 + "ignore", 156 + "warn", 157 + "hide" 158 + ] 159 + } 160 + }, 161 + "description": "Declares a label value and its expected interpretations and behaviors." 162 + }, 163 + "labelValueDefinitionStrings": { 164 + "type": "object", 165 + "required": [ 166 + "lang", 167 + "name", 168 + "description" 169 + ], 170 + "properties": { 171 + "lang": { 172 + "type": "string", 173 + "format": "language", 174 + "description": "The code of the language these strings are written in." 175 + }, 176 + "name": { 177 + "type": "string", 178 + "maxLength": 640, 179 + "description": "A short human-readable name for the label.", 180 + "maxGraphemes": 64 181 + }, 182 + "description": { 183 + "type": "string", 184 + "maxLength": 100000, 185 + "description": "A longer description of what the label means and why it might be applied.", 186 + "maxGraphemes": 10000 187 + } 188 + }, 189 + "description": "Strings which describe the label in the UI, localized into a specific language." 190 + } 191 + } 192 + }
+55
lexicons/com/atproto/moderation/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "com.atproto.moderation.defs", 4 + "defs": { 5 + "reasonRude": { 6 + "type": "token", 7 + "description": "Rude, harassing, explicit, or otherwise unwelcoming behavior" 8 + }, 9 + "reasonSpam": { 10 + "type": "token", 11 + "description": "Spam: frequent unwanted promotion, replies, mentions" 12 + }, 13 + "reasonType": { 14 + "type": "string", 15 + "knownValues": [ 16 + "com.atproto.moderation.defs#reasonSpam", 17 + "com.atproto.moderation.defs#reasonViolation", 18 + "com.atproto.moderation.defs#reasonMisleading", 19 + "com.atproto.moderation.defs#reasonSexual", 20 + "com.atproto.moderation.defs#reasonRude", 21 + "com.atproto.moderation.defs#reasonOther", 22 + "com.atproto.moderation.defs#reasonAppeal" 23 + ] 24 + }, 25 + "reasonOther": { 26 + "type": "token", 27 + "description": "Other: reports not falling under another report category" 28 + }, 29 + "subjectType": { 30 + "type": "string", 31 + "description": "Tag describing a type of subject that might be reported.", 32 + "knownValues": [ 33 + "account", 34 + "record", 35 + "chat" 36 + ] 37 + }, 38 + "reasonAppeal": { 39 + "type": "token", 40 + "description": "Appeal: appeal a previously taken moderation action" 41 + }, 42 + "reasonSexual": { 43 + "type": "token", 44 + "description": "Unwanted or mislabeled sexual content" 45 + }, 46 + "reasonViolation": { 47 + "type": "token", 48 + "description": "Direct violation of server rules, laws, terms of service" 49 + }, 50 + "reasonMisleading": { 51 + "type": "token", 52 + "description": "Misleading identity, affiliation, or content" 53 + } 54 + } 55 + }
+24
lexicons/com/atproto/repo/strongRef.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "com.atproto.repo.strongRef", 4 + "description": "A URI with a content-hash fingerprint.", 5 + "defs": { 6 + "main": { 7 + "type": "object", 8 + "required": [ 9 + "uri", 10 + "cid" 11 + ], 12 + "properties": { 13 + "cid": { 14 + "type": "string", 15 + "format": "cid" 16 + }, 17 + "uri": { 18 + "type": "string", 19 + "format": "at-uri" 20 + } 21 + } 22 + } 23 + } 24 + }
+71
lexicons/sh/tangled/actor/profile.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "sh.tangled.actor.profile", 4 + "defs": { 5 + "main": { 6 + "type": "record", 7 + "description": "A declaration of a Tangled account profile.", 8 + "key": "literal:self", 9 + "record": { 10 + "type": "object", 11 + "required": [ 12 + "bluesky" 13 + ], 14 + "properties": { 15 + "description": { 16 + "type": "string", 17 + "description": "Free-form profile description text.", 18 + "maxGraphemes": 256, 19 + "maxLength": 2560 20 + }, 21 + "links": { 22 + "type": "array", 23 + "minLength": 0, 24 + "maxLength": 5, 25 + "items": { 26 + "type": "string", 27 + "description": "Any URI, intended for social profiles or websites, can be used to link DIDs/AT-URIs too." 28 + } 29 + }, 30 + "stats": { 31 + "type": "array", 32 + "minLength": 0, 33 + "maxLength": 2, 34 + "items": { 35 + "type": "string", 36 + "description": "Vanity stats.", 37 + "enum": [ 38 + "merged-pull-request-count", 39 + "closed-pull-request-count", 40 + "open-pull-request-count", 41 + "open-issue-count", 42 + "closed-issue-count", 43 + "repository-count" 44 + ] 45 + } 46 + }, 47 + "bluesky": { 48 + "type": "boolean", 49 + "description": "Include link to this account on Bluesky." 50 + }, 51 + "location": { 52 + "type": "string", 53 + "description": "Free-form location text.", 54 + "maxGraphemes": 40, 55 + "maxLength": 400 56 + }, 57 + "pinnedRepositories": { 58 + "type": "array", 59 + "description": "Any ATURI, it is up to appviews to validate these fields.", 60 + "minLength": 0, 61 + "maxLength": 6, 62 + "items": { 63 + "type": "string", 64 + "format": "at-uri" 65 + } 66 + } 67 + } 68 + } 69 + } 70 + } 71 + }
+27
lexicons/sh/tangled/graph/follow.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "sh.tangled.graph.follow", 4 + "defs": { 5 + "main": { 6 + "type": "record", 7 + "key": "tid", 8 + "record": { 9 + "type": "object", 10 + "required": [ 11 + "subject", 12 + "createdAt" 13 + ], 14 + "properties": { 15 + "subject": { 16 + "type": "string", 17 + "format": "did" 18 + }, 19 + "createdAt": { 20 + "type": "string", 21 + "format": "datetime" 22 + } 23 + } 24 + } 25 + } 26 + } 27 + }
+77
lexicons/social/grain/actor/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.actor.defs", 4 + "defs": { 5 + "profileView": { 6 + "type": "object", 7 + "required": ["cid", "did", "handle"], 8 + "properties": { 9 + "cid": { "type": "string", "format": "cid" }, 10 + "did": { "type": "string", "format": "did" }, 11 + "handle": { "type": "string", "format": "handle" }, 12 + "displayName": { 13 + "type": "string", 14 + "maxGraphemes": 64, 15 + "maxLength": 640 16 + }, 17 + "description": { 18 + "type": "string", 19 + "maxLength": 2560, 20 + "maxGraphemes": 256 21 + }, 22 + "labels": { 23 + "type": "array", 24 + "items": { 25 + "ref": "com.atproto.label.defs#label", 26 + "type": "ref" 27 + } 28 + }, 29 + "avatar": { "type": "string", "format": "uri" }, 30 + "createdAt": { "type": "string", "format": "datetime" } 31 + } 32 + }, 33 + "profileViewDetailed": { 34 + "type": "object", 35 + "required": ["cid", "did", "handle"], 36 + "properties": { 37 + "cid": { "type": "string", "format": "cid" }, 38 + "did": { "type": "string", "format": "did" }, 39 + "handle": { "type": "string", "format": "handle" }, 40 + "displayName": { 41 + "type": "string", 42 + "maxGraphemes": 64, 43 + "maxLength": 640 44 + }, 45 + "description": { 46 + "type": "string", 47 + "maxGraphemes": 256, 48 + "maxLength": 2560 49 + }, 50 + "avatar": { "type": "string", "format": "uri" }, 51 + "cameras": { 52 + "type": "array", 53 + "items": { "type": "string" }, 54 + "description": "List of camera make and models used by this actor derived from EXIF data of photos linked to galleries." 55 + }, 56 + "followersCount": { "type": "integer" }, 57 + "followsCount": { "type": "integer" }, 58 + "galleryCount": { "type": "integer" }, 59 + "indexedAt": { "type": "string", "format": "datetime" }, 60 + "createdAt": { "type": "string", "format": "datetime" }, 61 + "viewer": { "type": "ref", "ref": "#viewerState" }, 62 + "labels": { 63 + "type": "array", 64 + "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } 65 + } 66 + } 67 + }, 68 + "viewerState": { 69 + "type": "object", 70 + "description": "Metadata about the requesting account's relationship with the subject account. Only has meaningful content for authed requests.", 71 + "properties": { 72 + "following": { "type": "string", "format": "at-uri" }, 73 + "followedBy": { "type": "string", "format": "at-uri" } 74 + } 75 + } 76 + } 77 + }
+41
lexicons/social/grain/actor/getActorFavs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.actor.getActorFavs", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Get a view of an actor's favorite galleries. Does not require auth.", 8 + "parameters": { 9 + "type": "params", 10 + "required": ["actor"], 11 + "properties": { 12 + "actor": { "type": "string", "format": "at-identifier" }, 13 + "limit": { 14 + "type": "integer", 15 + "minimum": 1, 16 + "maximum": 100, 17 + "default": 50 18 + }, 19 + "cursor": { "type": "string" } 20 + } 21 + }, 22 + "output": { 23 + "encoding": "application/json", 24 + "schema": { 25 + "type": "object", 26 + "required": ["items"], 27 + "properties": { 28 + "cursor": { "type": "string" }, 29 + "items": { 30 + "type": "array", 31 + "items": { 32 + "type": "ref", 33 + "ref": "social.grain.gallery.defs#galleryView" 34 + } 35 + } 36 + } 37 + } 38 + } 39 + } 40 + } 41 + }
+28
lexicons/social/grain/actor/getProfile.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.actor.getProfile", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Get detailed profile view of an actor. Does not require auth, but contains relevant metadata with auth.", 8 + "parameters": { 9 + "type": "params", 10 + "required": ["actor"], 11 + "properties": { 12 + "actor": { 13 + "type": "string", 14 + "format": "at-identifier", 15 + "description": "Handle or DID of account to fetch profile of." 16 + } 17 + } 18 + }, 19 + "output": { 20 + "encoding": "application/json", 21 + "schema": { 22 + "type": "ref", 23 + "ref": "social.grain.actor.defs#profileViewDetailed" 24 + } 25 + } 26 + } 27 + } 28 + }
+34
lexicons/social/grain/actor/profile.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.actor.profile", 4 + "defs": { 5 + "main": { 6 + "type": "record", 7 + "description": "A declaration of a basic account profile.", 8 + "key": "literal:self", 9 + "record": { 10 + "type": "object", 11 + "properties": { 12 + "displayName": { 13 + "type": "string", 14 + "maxGraphemes": 64, 15 + "maxLength": 640 16 + }, 17 + "description": { 18 + "type": "string", 19 + "description": "Free-form profile description text.", 20 + "maxGraphemes": 256, 21 + "maxLength": 2560 22 + }, 23 + "avatar": { 24 + "type": "blob", 25 + "description": "Small image to be displayed next to posts from account. AKA, 'profile picture'", 26 + "accept": ["image/png", "image/jpeg"], 27 + "maxSize": 1000000 28 + }, 29 + "createdAt": { "type": "string", "format": "datetime" } 30 + } 31 + } 32 + } 33 + } 34 + }
+43
lexicons/social/grain/actor/searchActors.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.actor.searchActors", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Find actors (profiles) matching search criteria. Does not require auth.", 8 + "parameters": { 9 + "type": "params", 10 + "properties": { 11 + "q": { 12 + "type": "string", 13 + "description": "Search query string. Syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended." 14 + }, 15 + "limit": { 16 + "type": "integer", 17 + "minimum": 1, 18 + "maximum": 100, 19 + "default": 25 20 + }, 21 + "cursor": { "type": "string" } 22 + } 23 + }, 24 + "output": { 25 + "encoding": "application/json", 26 + "schema": { 27 + "type": "object", 28 + "required": ["actors"], 29 + "properties": { 30 + "cursor": { "type": "string" }, 31 + "actors": { 32 + "type": "array", 33 + "items": { 34 + "type": "ref", 35 + "ref": "social.grain.actor.defs#profileView" 36 + } 37 + } 38 + } 39 + } 40 + } 41 + } 42 + } 43 + }
+25
lexicons/social/grain/actor/updateAvatar.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.actor.updateAvatar", 4 + "defs": { 5 + "main": { 6 + "type": "procedure", 7 + "description": "Update an actor's avatar. Requires auth.", 8 + "input": { 9 + "encoding": "*/*" 10 + }, 11 + "output": { 12 + "encoding": "application/json", 13 + "schema": { 14 + "type": "object", 15 + "properties": { 16 + "success": { 17 + "type": "boolean", 18 + "description": "Indicates whether the avatar update was successful." 19 + } 20 + } 21 + } 22 + } 23 + } 24 + } 25 + }
+41
lexicons/social/grain/actor/updateProfile.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.actor.updateProfile", 4 + "defs": { 5 + "main": { 6 + "type": "procedure", 7 + "description": "Update an actor's profile info. Requires auth.", 8 + "input": { 9 + "encoding": "application/json", 10 + "schema": { 11 + "type": "object", 12 + "properties": { 13 + "displayName": { 14 + "type": "string", 15 + "maxGraphemes": 64, 16 + "maxLength": 640 17 + }, 18 + "description": { 19 + "type": "string", 20 + "description": "Free-form profile description text.", 21 + "maxGraphemes": 256, 22 + "maxLength": 2560 23 + } 24 + } 25 + } 26 + }, 27 + "output": { 28 + "encoding": "application/json", 29 + "schema": { 30 + "type": "object", 31 + "properties": { 32 + "success": { 33 + "type": "boolean", 34 + "description": "Indicates whether the profile update was successful." 35 + } 36 + } 37 + } 38 + } 39 + } 40 + } 41 + }
+42
lexicons/social/grain/comment/comment.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.comment", 4 + "defs": { 5 + "main": { 6 + "type": "record", 7 + "key": "tid", 8 + "record": { 9 + "type": "object", 10 + "required": ["text", "subject", "createdAt"], 11 + "properties": { 12 + "text": { 13 + "type": "string", 14 + "maxLength": 3000, 15 + "maxGraphemes": 300 16 + }, 17 + "facets": { 18 + "type": "array", 19 + "description": "Annotations of description text (mentions and URLs, hashtags, etc)", 20 + "items": { "type": "ref", "ref": "app.bsky.richtext.facet" } 21 + }, 22 + "subject": { 23 + "type": "string", 24 + "format": "at-uri" 25 + }, 26 + "focus": { 27 + "type": "string", 28 + "format": "at-uri" 29 + }, 30 + "replyTo": { 31 + "type": "string", 32 + "format": "at-uri" 33 + }, 34 + "createdAt": { 35 + "type": "string", 36 + "format": "datetime" 37 + } 38 + } 39 + } 40 + } 41 + } 42 + }
+49
lexicons/social/grain/comment/createComment.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.comment.createComment", 4 + "defs": { 5 + "main": { 6 + "type": "procedure", 7 + "description": "Create a comment. Requires auth.", 8 + "input": { 9 + "encoding": "application/json", 10 + "schema": { 11 + "type": "object", 12 + "required": ["text", "subject"], 13 + "properties": { 14 + "text": { 15 + "type": "string", 16 + "maxLength": 3000, 17 + "maxGraphemes": 300 18 + }, 19 + "subject": { 20 + "type": "string", 21 + "format": "at-uri" 22 + }, 23 + "focus": { 24 + "type": "string", 25 + "format": "at-uri" 26 + }, 27 + "replyTo": { 28 + "type": "string", 29 + "format": "at-uri" 30 + } 31 + } 32 + } 33 + }, 34 + "output": { 35 + "encoding": "application/json", 36 + "schema": { 37 + "type": "object", 38 + "properties": { 39 + "commentUri": { 40 + "type": "string", 41 + "format": "at-uri", 42 + "description": "AT URI of the created comment" 43 + } 44 + } 45 + } 46 + } 47 + } 48 + } 49 + }
+52
lexicons/social/grain/comment/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.comment.defs", 4 + "defs": { 5 + "commentView": { 6 + "type": "object", 7 + "required": ["uri", "cid", "author", "text", "createdAt"], 8 + "properties": { 9 + "uri": { "type": "string", "format": "at-uri" }, 10 + "cid": { "type": "string", "format": "cid" }, 11 + "author": { 12 + "type": "ref", 13 + "ref": "social.grain.actor.defs#profileView" 14 + }, 15 + "record": { "type": "unknown" }, 16 + "text": { 17 + "type": "string", 18 + "maxLength": 3000, 19 + "maxGraphemes": 300 20 + }, 21 + "facets": { 22 + "type": "array", 23 + "description": "Annotations of description text (mentions and URLs, hashtags, etc)", 24 + "items": { "type": "ref", "ref": "app.bsky.richtext.facet" } 25 + }, 26 + "subject": { 27 + "type": "union", 28 + "refs": [ 29 + "social.grain.gallery.defs#galleryView" 30 + ], 31 + "description": "The subject of the comment, which can be a gallery or a photo." 32 + }, 33 + "focus": { 34 + "type": "union", 35 + "refs": [ 36 + "social.grain.photo.defs#photoView" 37 + ], 38 + "description": "The photo that the comment is focused on, if applicable." 39 + }, 40 + "replyTo": { 41 + "type": "string", 42 + "format": "at-uri", 43 + "description": "The URI of the comment this comment is replying to, if applicable." 44 + }, 45 + "createdAt": { 46 + "type": "string", 47 + "format": "datetime" 48 + } 49 + } 50 + } 51 + } 52 + }
+36
lexicons/social/grain/comment/deleteComment.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.comment.deleteComment", 4 + "defs": { 5 + "main": { 6 + "type": "procedure", 7 + "description": "Delete a comment. Requires auth.", 8 + "input": { 9 + "encoding": "application/json", 10 + "schema": { 11 + "type": "object", 12 + "required": ["uri"], 13 + "properties": { 14 + "uri": { 15 + "type": "string", 16 + "format": "at-uri", 17 + "description": "AT URI of the comment to delete" 18 + } 19 + } 20 + } 21 + }, 22 + "output": { 23 + "encoding": "application/json", 24 + "schema": { 25 + "type": "object", 26 + "properties": { 27 + "success": { 28 + "type": "boolean", 29 + "description": "True if the comment was deleted" 30 + } 31 + } 32 + } 33 + } 34 + } 35 + } 36 + }
+15
lexicons/social/grain/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.defs", 4 + "defs": { 5 + "aspectRatio": { 6 + "type": "object", 7 + "description": "width:height represents an aspect ratio. It may be approximate, and may not correspond to absolute dimensions in any given unit.", 8 + "required": ["width", "height"], 9 + "properties": { 10 + "width": { "type": "integer", "minimum": 1 }, 11 + "height": { "type": "integer", "minimum": 1 } 12 + } 13 + } 14 + } 15 + }
+38
lexicons/social/grain/favorite/createFavorite.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.favorite.createFavorite", 4 + "defs": { 5 + "main": { 6 + "description": "Create a favorite for a given subject.", 7 + "type": "procedure", 8 + "input": { 9 + "encoding": "application/json", 10 + "schema": { 11 + "type": "object", 12 + "required": ["subject"], 13 + "properties": { 14 + "subject": { 15 + "type": "string", 16 + "format": "at-uri", 17 + "description": "URI of the subject to favorite." 18 + } 19 + } 20 + } 21 + }, 22 + "output": { 23 + "encoding": "application/json", 24 + "schema": { 25 + "type": "object", 26 + "required": ["favoriteUri"], 27 + "properties": { 28 + "favoriteUri": { 29 + "type": "string", 30 + "format": "at-uri", 31 + "description": "AT URI for the created favorite." 32 + } 33 + } 34 + } 35 + } 36 + } 37 + } 38 + }
+37
lexicons/social/grain/favorite/deleteFavorite.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.favorite.deleteFavorite", 4 + "defs": { 5 + "main": { 6 + "type": "procedure", 7 + "description": "Delete a favorite item by its ID.", 8 + "input": { 9 + "encoding": "application/json", 10 + "schema": { 11 + "type": "object", 12 + "required": ["uri"], 13 + "properties": { 14 + "uri": { 15 + "type": "string", 16 + "format": "at-uri", 17 + "description": "The AT URI of the favorite to delete." 18 + } 19 + } 20 + } 21 + }, 22 + "output": { 23 + "encoding": "application/json", 24 + "schema": { 25 + "type": "object", 26 + "required": ["success"], 27 + "properties": { 28 + "success": { 29 + "type": "boolean", 30 + "description": "Indicates if the favorite was successfully deleted." 31 + } 32 + } 33 + } 34 + } 35 + } 36 + } 37 + }
+24
lexicons/social/grain/favorite/favorite.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.favorite", 4 + "defs": { 5 + "main": { 6 + "type": "record", 7 + "key": "tid", 8 + "record": { 9 + "type": "object", 10 + "required": ["createdAt", "subject"], 11 + "properties": { 12 + "createdAt": { 13 + "type": "string", 14 + "format": "datetime" 15 + }, 16 + "subject": { 17 + "type": "string", 18 + "format": "at-uri" 19 + } 20 + } 21 + } 22 + } 23 + } 24 + }
+43
lexicons/social/grain/feed/getTimeline.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.feed.getTimeline", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Get a view of the requesting account's home timeline.", 8 + "parameters": { 9 + "type": "params", 10 + "properties": { 11 + "algorithm": { 12 + "type": "string", 13 + "description": "Variant 'algorithm' for timeline. Implementation-specific." 14 + }, 15 + "limit": { 16 + "type": "integer", 17 + "minimum": 1, 18 + "maximum": 100, 19 + "default": 50 20 + }, 21 + "cursor": { "type": "string" } 22 + } 23 + }, 24 + "output": { 25 + "encoding": "application/json", 26 + "schema": { 27 + "type": "object", 28 + "required": ["feed"], 29 + "properties": { 30 + "cursor": { "type": "string" }, 31 + "feed": { 32 + "type": "array", 33 + "items": { 34 + "type": "ref", 35 + "ref": "social.grain.gallery.defs#galleryView" 36 + } 37 + } 38 + } 39 + } 40 + } 41 + } 42 + } 43 + }
+58
lexicons/social/grain/gallery/applySort.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.gallery.applySort", 4 + "defs": { 5 + "main": { 6 + "type": "procedure", 7 + "description": "Apply sorting to photos in a gallery. Requires auth.", 8 + "input": { 9 + "encoding": "application/json", 10 + "schema": { 11 + "type": "object", 12 + "required": ["galleryUri", "writes"], 13 + "properties": { 14 + "galleryUri": { 15 + "type": "string", 16 + "format": "at-uri", 17 + "description": "The AT-URI of the gallery to update" 18 + }, 19 + "writes": { 20 + "type": "array", 21 + "items": { 22 + "type": "ref", 23 + "ref": "#update" 24 + } 25 + } 26 + } 27 + } 28 + }, 29 + "output": { 30 + "encoding": "application/json", 31 + "schema": { 32 + "type": "object", 33 + "properties": { 34 + "success": { 35 + "type": "boolean", 36 + "description": "True if the writes were successfully applied" 37 + } 38 + } 39 + } 40 + } 41 + }, 42 + "update": { 43 + "type": "object", 44 + "required": ["itemUri", "position"], 45 + "properties": { 46 + "itemUri": { 47 + "type": "string", 48 + "format": "at-uri", 49 + "description": "AT URI of the item to update" 50 + }, 51 + "position": { 52 + "type": "integer", 53 + "description": "The position of the item in the gallery, used for ordering" 54 + } 55 + } 56 + } 57 + } 58 + }
+34
lexicons/social/grain/gallery/createGallery.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.gallery.createGallery", 4 + "defs": { 5 + "main": { 6 + "type": "procedure", 7 + "description": "Create a new gallery", 8 + "input": { 9 + "encoding": "application/json", 10 + "schema": { 11 + "type": "object", 12 + "required": ["title"], 13 + "properties": { 14 + "title": { "type": "string", "maxLength": 100 }, 15 + "description": { "type": "string", "maxLength": 1000 } 16 + } 17 + } 18 + }, 19 + "output": { 20 + "encoding": "application/json", 21 + "schema": { 22 + "type": "object", 23 + "properties": { 24 + "galleryUri": { 25 + "type": "string", 26 + "format": "at-uri", 27 + "description": "AT URI of the created gallery" 28 + } 29 + } 30 + } 31 + } 32 + } 33 + } 34 + }
+46
lexicons/social/grain/gallery/createItem.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.gallery.createItem", 4 + "defs": { 5 + "main": { 6 + "type": "procedure", 7 + "description": "Create a new gallery item", 8 + "input": { 9 + "encoding": "application/json", 10 + "schema": { 11 + "type": "object", 12 + "required": ["galleryUri", "photoUri", "position"], 13 + "properties": { 14 + "galleryUri": { 15 + "type": "string", 16 + "format": "at-uri", 17 + "description": "AT URI of the gallery to create the item in" 18 + }, 19 + "photoUri": { 20 + "type": "string", 21 + "format": "at-uri", 22 + "description": "AT URI of the photo to be added as an item" 23 + }, 24 + "position": { 25 + "type": "integer", 26 + "description": "Position of the item in the gallery, used for ordering" 27 + } 28 + } 29 + } 30 + }, 31 + "output": { 32 + "encoding": "application/json", 33 + "schema": { 34 + "type": "object", 35 + "properties": { 36 + "itemUri": { 37 + "type": "string", 38 + "format": "at-uri", 39 + "description": "AT URI of the created gallery item" 40 + } 41 + } 42 + } 43 + } 44 + } 45 + } 46 + }
+56
lexicons/social/grain/gallery/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.gallery.defs", 4 + "defs": { 5 + "galleryView": { 6 + "type": "object", 7 + "required": ["uri", "cid", "creator", "record", "indexedAt"], 8 + "properties": { 9 + "uri": { "type": "string", "format": "at-uri" }, 10 + "cid": { "type": "string", "format": "cid" }, 11 + "title": { "type": "string" }, 12 + "description": { "type": "string" }, 13 + "cameras": { 14 + "type": "array", 15 + "description": "List of camera make and models used in this gallery derived from EXIF data.", 16 + "items": { "type": "string" } 17 + }, 18 + "facets": { 19 + "type": "array", 20 + "description": "Annotations of description text (mentions, URLs, hashtags, etc)", 21 + "items": { "type": "ref", "ref": "app.bsky.richtext.facet" } 22 + }, 23 + "creator": { 24 + "type": "ref", 25 + "ref": "social.grain.actor.defs#profileView" 26 + }, 27 + "record": { "type": "unknown" }, 28 + "items": { 29 + "type": "array", 30 + "items": { 31 + "type": "union", 32 + "refs": [ 33 + "social.grain.photo.defs#photoView" 34 + ] 35 + } 36 + }, 37 + "favCount": { "type": "integer" }, 38 + "commentCount": { "type": "integer" }, 39 + "labels": { 40 + "type": "array", 41 + "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } 42 + }, 43 + "createdAt": { "type": "string", "format": "datetime" }, 44 + "indexedAt": { "type": "string", "format": "datetime" }, 45 + "viewer": { "type": "ref", "ref": "#viewerState" } 46 + } 47 + }, 48 + "viewerState": { 49 + "type": "object", 50 + "description": "Metadata about the requesting account's relationship with the subject content. Only has meaningful content for authed requests.", 51 + "properties": { 52 + "fav": { "type": "string", "format": "at-uri" } 53 + } 54 + } 55 + } 56 + }
+36
lexicons/social/grain/gallery/deleteGallery.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.gallery.deleteGallery", 4 + "defs": { 5 + "main": { 6 + "type": "procedure", 7 + "description": "Delete a gallery. Does not delete the items in the gallery, just the gallery itself.", 8 + "input": { 9 + "encoding": "application/json", 10 + "schema": { 11 + "type": "object", 12 + "required": ["uri"], 13 + "properties": { 14 + "uri": { 15 + "type": "string", 16 + "format": "at-uri", 17 + "description": "Unique identifier of the gallery to delete" 18 + } 19 + } 20 + } 21 + }, 22 + "output": { 23 + "encoding": "application/json", 24 + "schema": { 25 + "type": "object", 26 + "properties": { 27 + "success": { 28 + "type": "boolean", 29 + "description": "True if the gallery was deleted" 30 + } 31 + } 32 + } 33 + } 34 + } 35 + } 36 + }
+36
lexicons/social/grain/gallery/deleteItem.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.gallery.deleteItem", 4 + "defs": { 5 + "main": { 6 + "type": "procedure", 7 + "description": "Delete a gallery item", 8 + "input": { 9 + "encoding": "application/json", 10 + "schema": { 11 + "type": "object", 12 + "required": ["uri"], 13 + "properties": { 14 + "uri": { 15 + "type": "string", 16 + "format": "at-uri", 17 + "description": "AT URI of the gallery to create the item in" 18 + } 19 + } 20 + } 21 + }, 22 + "output": { 23 + "encoding": "application/json", 24 + "schema": { 25 + "type": "object", 26 + "properties": { 27 + "success": { 28 + "type": "boolean", 29 + "description": "True if the gallery item was deleted" 30 + } 31 + } 32 + } 33 + } 34 + } 35 + } 36 + }
+30
lexicons/social/grain/gallery/gallery.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.gallery", 4 + "defs": { 5 + "main": { 6 + "type": "record", 7 + "key": "tid", 8 + "record": { 9 + "type": "object", 10 + "required": ["title", "createdAt"], 11 + "properties": { 12 + "title": { "type": "string", "maxLength": 100 }, 13 + "description": { "type": "string", "maxLength": 1000 }, 14 + "facets": { 15 + "type": "array", 16 + "description": "Annotations of description text (mentions, URLs, hashtags, etc)", 17 + "items": { "type": "ref", "ref": "app.bsky.richtext.facet" } 18 + }, 19 + "labels": { 20 + "type": "union", 21 + "description": "Self-label values for this post. Effectively content warnings.", 22 + "refs": ["com.atproto.label.defs#selfLabels"] 23 + }, 24 + "updatedAt": { "type": "string", "format": "datetime" }, 25 + "createdAt": { "type": "string", "format": "datetime" } 26 + } 27 + } 28 + } 29 + } 30 + }
+41
lexicons/social/grain/gallery/getActorGalleries.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.gallery.getActorGalleries", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Get a view of an actor's galleries. Does not require auth.", 8 + "parameters": { 9 + "type": "params", 10 + "required": ["actor"], 11 + "properties": { 12 + "actor": { "type": "string", "format": "at-identifier" }, 13 + "limit": { 14 + "type": "integer", 15 + "minimum": 1, 16 + "maximum": 100, 17 + "default": 50 18 + }, 19 + "cursor": { "type": "string" } 20 + } 21 + }, 22 + "output": { 23 + "encoding": "application/json", 24 + "schema": { 25 + "type": "object", 26 + "required": ["items"], 27 + "properties": { 28 + "cursor": { "type": "string" }, 29 + "items": { 30 + "type": "array", 31 + "items": { 32 + "type": "ref", 33 + "ref": "social.grain.gallery.defs#galleryView" 34 + } 35 + } 36 + } 37 + } 38 + } 39 + } 40 + } 41 + }
+28
lexicons/social/grain/gallery/getGallery.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.gallery.getGallery", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Gets a hydrated gallery view for a specified gallery AT-URI.", 8 + "parameters": { 9 + "type": "params", 10 + "required": ["uri"], 11 + "properties": { 12 + "uri": { 13 + "type": "string", 14 + "description": "The AT-URI of the gallery to return a hydrated view for.", 15 + "format": "at-uri" 16 + } 17 + } 18 + }, 19 + "output": { 20 + "encoding": "application/json", 21 + "schema": { 22 + "type": "ref", 23 + "ref": "social.grain.gallery.defs#galleryView" 24 + } 25 + } 26 + } 27 + } 28 + }
+41
lexicons/social/grain/gallery/getGalleryThread.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.gallery.getGalleryThread", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Gets a hydrated gallery view and its comments for a specified gallery AT-URI.", 8 + "parameters": { 9 + "type": "params", 10 + "required": ["uri"], 11 + "properties": { 12 + "uri": { 13 + "type": "string", 14 + "description": "The AT-URI of the gallery to return a hydrated view and comments for.", 15 + "format": "at-uri" 16 + } 17 + } 18 + }, 19 + "output": { 20 + "encoding": "application/json", 21 + "schema": { 22 + "type": "object", 23 + "required": ["gallery", "comments"], 24 + "properties": { 25 + "gallery": { 26 + "type": "ref", 27 + "ref": "social.grain.gallery.defs#galleryView" 28 + }, 29 + "comments": { 30 + "type": "array", 31 + "items": { 32 + "type": "ref", 33 + "ref": "social.grain.comment.defs#commentView" 34 + } 35 + } 36 + } 37 + } 38 + } 39 + } 40 + } 41 + }
+32
lexicons/social/grain/gallery/item.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.gallery.item", 4 + "defs": { 5 + "main": { 6 + "type": "record", 7 + "key": "tid", 8 + "record": { 9 + "type": "object", 10 + "required": ["createdAt", "gallery", "item"], 11 + "properties": { 12 + "createdAt": { 13 + "type": "string", 14 + "format": "datetime" 15 + }, 16 + "gallery": { 17 + "type": "string", 18 + "format": "at-uri" 19 + }, 20 + "item": { 21 + "type": "string", 22 + "format": "at-uri" 23 + }, 24 + "position": { 25 + "type": "integer", 26 + "default": 0 27 + } 28 + } 29 + } 30 + } 31 + } 32 + }
+38
lexicons/social/grain/gallery/updateGallery.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.gallery.updateGallery", 4 + "defs": { 5 + "main": { 6 + "type": "procedure", 7 + "description": "Create a new gallery", 8 + "input": { 9 + "encoding": "application/json", 10 + "schema": { 11 + "type": "object", 12 + "required": ["galleryUri", "title"], 13 + "properties": { 14 + "galleryUri": { 15 + "type": "string", 16 + "format": "at-uri", 17 + "description": "The AT-URI of the gallery to update" 18 + }, 19 + "title": { "type": "string" }, 20 + "description": { "type": "string" } 21 + } 22 + } 23 + }, 24 + "output": { 25 + "encoding": "application/json", 26 + "schema": { 27 + "type": "object", 28 + "properties": { 29 + "success": { 30 + "type": "boolean", 31 + "description": "True if the gallery was updated" 32 + } 33 + } 34 + } 35 + } 36 + } 37 + } 38 + }
+37
lexicons/social/grain/graph/createFollow.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.graph.createFollow", 4 + "defs": { 5 + "main": { 6 + "type": "procedure", 7 + "description": "Create a follow relationship between actors.", 8 + "input": { 9 + "encoding": "application/json", 10 + "schema": { 11 + "type": "object", 12 + "required": ["subject"], 13 + "properties": { 14 + "subject": { 15 + "type": "string", 16 + "format": "at-identifier", 17 + "description": "DID of the actor to follow." 18 + } 19 + } 20 + } 21 + }, 22 + "output": { 23 + "encoding": "application/json", 24 + "schema": { 25 + "type": "object", 26 + "properties": { 27 + "followUri": { 28 + "type": "string", 29 + "format": "at-uri", 30 + "description": "AT URI of the created follow record." 31 + } 32 + } 33 + } 34 + } 35 + } 36 + } 37 + }
+36
lexicons/social/grain/graph/deleteFollow.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.graph.deleteFollow", 4 + "defs": { 5 + "main": { 6 + "type": "procedure", 7 + "description": "Delete a follow relationship. Requires auth.", 8 + "input": { 9 + "encoding": "application/json", 10 + "schema": { 11 + "type": "object", 12 + "required": ["uri"], 13 + "properties": { 14 + "uri": { 15 + "type": "string", 16 + "format": "at-uri", 17 + "description": "AT URI of the follow record to delete" 18 + } 19 + } 20 + } 21 + }, 22 + "output": { 23 + "encoding": "application/json", 24 + "schema": { 25 + "type": "object", 26 + "properties": { 27 + "success": { 28 + "type": "boolean", 29 + "description": "True if the follow was deleted" 30 + } 31 + } 32 + } 33 + } 34 + } 35 + } 36 + }
+27
lexicons/social/grain/graph/follow.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.graph.follow", 4 + "defs": { 5 + "main": { 6 + "key": "tid", 7 + "type": "record", 8 + "record": { 9 + "type": "object", 10 + "required": [ 11 + "subject", 12 + "createdAt" 13 + ], 14 + "properties": { 15 + "subject": { 16 + "type": "string", 17 + "format": "did" 18 + }, 19 + "createdAt": { 20 + "type": "string", 21 + "format": "datetime" 22 + } 23 + } 24 + } 25 + } 26 + } 27 + }
+45
lexicons/social/grain/graph/getFollowers.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.graph.getFollowers", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Enumerates accounts which follow a specified account (actor).", 8 + "parameters": { 9 + "type": "params", 10 + "required": ["actor"], 11 + "properties": { 12 + "actor": { "type": "string", "format": "at-identifier" }, 13 + "limit": { 14 + "type": "integer", 15 + "minimum": 1, 16 + "maximum": 100, 17 + "default": 50 18 + }, 19 + "cursor": { "type": "string" } 20 + } 21 + }, 22 + "output": { 23 + "encoding": "application/json", 24 + "schema": { 25 + "type": "object", 26 + "required": ["subject", "followers"], 27 + "properties": { 28 + "subject": { 29 + "type": "ref", 30 + "ref": "social.grain.actor.defs#profileView" 31 + }, 32 + "cursor": { "type": "string" }, 33 + "followers": { 34 + "type": "array", 35 + "items": { 36 + "type": "ref", 37 + "ref": "social.grain.actor.defs#profileView" 38 + } 39 + } 40 + } 41 + } 42 + } 43 + } 44 + } 45 + }
+45
lexicons/social/grain/graph/getFollows.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.graph.getFollows", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Enumerates accounts which a specified account (actor) follows.", 8 + "parameters": { 9 + "type": "params", 10 + "required": ["actor"], 11 + "properties": { 12 + "actor": { "type": "string", "format": "at-identifier" }, 13 + "limit": { 14 + "type": "integer", 15 + "minimum": 1, 16 + "maximum": 100, 17 + "default": 50 18 + }, 19 + "cursor": { "type": "string" } 20 + } 21 + }, 22 + "output": { 23 + "encoding": "application/json", 24 + "schema": { 25 + "type": "object", 26 + "required": ["subject", "follows"], 27 + "properties": { 28 + "subject": { 29 + "type": "ref", 30 + "ref": "social.grain.actor.defs#profileView" 31 + }, 32 + "cursor": { "type": "string" }, 33 + "follows": { 34 + "type": "array", 35 + "items": { 36 + "type": "ref", 37 + "ref": "social.grain.actor.defs#profileView" 38 + } 39 + } 40 + } 41 + } 42 + } 43 + } 44 + } 45 + }
+94
lexicons/social/grain/labelers/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.labeler.defs", 4 + "defs": { 5 + "labelerView": { 6 + "type": "object", 7 + "required": ["uri", "cid", "creator", "indexedAt"], 8 + "properties": { 9 + "uri": { "type": "string", "format": "at-uri" }, 10 + "cid": { "type": "string", "format": "cid" }, 11 + "creator": { 12 + "type": "ref", 13 + "ref": "social.grain.actor.defs#profileView" 14 + }, 15 + "favoriteCount": { "type": "integer", "minimum": 0 }, 16 + "viewer": { "type": "ref", "ref": "#labelerViewerState" }, 17 + "indexedAt": { "type": "string", "format": "datetime" }, 18 + "labels": { 19 + "type": "array", 20 + "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } 21 + } 22 + } 23 + }, 24 + "labelerViewDetailed": { 25 + "type": "object", 26 + "required": ["uri", "cid", "creator", "policies", "indexedAt"], 27 + "properties": { 28 + "uri": { "type": "string", "format": "at-uri" }, 29 + "cid": { "type": "string", "format": "cid" }, 30 + "creator": { "type": "ref", "ref": "app.bsky.actor.defs#profileView" }, 31 + "policies": { 32 + "type": "ref", 33 + "ref": "social.grain.actor.defs#labelerPolicies" 34 + }, 35 + "favoriteCount": { "type": "integer", "minimum": 0 }, 36 + "viewer": { "type": "ref", "ref": "#labelerViewerState" }, 37 + "indexedAt": { "type": "string", "format": "datetime" }, 38 + "labels": { 39 + "type": "array", 40 + "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } 41 + }, 42 + "reasonTypes": { 43 + "description": "The set of report reason 'codes' which are in-scope for this service to review and action. These usually align to policy categories. If not defined (distinct from empty array), all reason types are allowed.", 44 + "type": "array", 45 + "items": { 46 + "type": "ref", 47 + "ref": "com.atproto.moderation.defs#reasonType" 48 + } 49 + }, 50 + "subjectTypes": { 51 + "description": "The set of subject types (account, record, etc) this service accepts reports on.", 52 + "type": "array", 53 + "items": { 54 + "type": "ref", 55 + "ref": "com.atproto.moderation.defs#subjectType" 56 + } 57 + }, 58 + "subjectCollections": { 59 + "type": "array", 60 + "description": "Set of record types (collection NSIDs) which can be reported to this service. If not defined (distinct from empty array), default is any record type.", 61 + "items": { "type": "string", "format": "nsid" } 62 + } 63 + } 64 + }, 65 + "labelerViewerState": { 66 + "type": "object", 67 + "properties": { 68 + "like": { "type": "string", "format": "at-uri" } 69 + } 70 + }, 71 + "labelerPolicies": { 72 + "type": "object", 73 + "required": ["labelValues"], 74 + "properties": { 75 + "labelValues": { 76 + "type": "array", 77 + "description": "The label values which this labeler publishes. May include global or custom labels.", 78 + "items": { 79 + "type": "ref", 80 + "ref": "com.atproto.label.defs#labelValue" 81 + } 82 + }, 83 + "labelValueDefinitions": { 84 + "type": "array", 85 + "description": "Label values created by this labeler and scoped exclusively to it. Labels defined here will override global label definitions for this labeler.", 86 + "items": { 87 + "type": "ref", 88 + "ref": "com.atproto.label.defs#labelValueDefinition" 89 + } 90 + } 91 + } 92 + } 93 + } 94 + }
+47
lexicons/social/grain/labelers/service.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.labeler.service", 4 + "defs": { 5 + "main": { 6 + "type": "record", 7 + "description": "A declaration of the existence of labeler service.", 8 + "key": "literal:self", 9 + "record": { 10 + "type": "object", 11 + "required": ["policies", "createdAt"], 12 + "properties": { 13 + "policies": { 14 + "type": "ref", 15 + "ref": "app.bsky.labeler.defs#labelerPolicies" 16 + }, 17 + "labels": { 18 + "type": "union", 19 + "refs": ["com.atproto.label.defs#selfLabels"] 20 + }, 21 + "createdAt": { "type": "string", "format": "datetime" }, 22 + "reasonTypes": { 23 + "description": "The set of report reason 'codes' which are in-scope for this service to review and action. These usually align to policy categories. If not defined (distinct from empty array), all reason types are allowed.", 24 + "type": "array", 25 + "items": { 26 + "type": "ref", 27 + "ref": "com.atproto.moderation.defs#reasonType" 28 + } 29 + }, 30 + "subjectTypes": { 31 + "description": "The set of subject types (account, record, etc) this service accepts reports on.", 32 + "type": "array", 33 + "items": { 34 + "type": "ref", 35 + "ref": "com.atproto.moderation.defs#subjectType" 36 + } 37 + }, 38 + "subjectCollections": { 39 + "type": "array", 40 + "description": "Set of record types (collection NSIDs) which can be reported to this service. If not defined (distinct from empty array), default is any record type.", 41 + "items": { "type": "string", "format": "nsid" } 42 + } 43 + } 44 + } 45 + } 46 + } 47 + }
+87
lexicons/social/grain/notification/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.notification.defs", 4 + "defs": { 5 + "notificationView": { 6 + "type": "object", 7 + "required": [ 8 + "uri", 9 + "cid", 10 + "author", 11 + "reason", 12 + "record", 13 + "isRead", 14 + "indexedAt" 15 + ], 16 + "properties": { 17 + "uri": { "type": "string", "format": "at-uri" }, 18 + "cid": { "type": "string", "format": "cid" }, 19 + "author": { 20 + "type": "ref", 21 + "ref": "social.grain.actor.defs#profileView" 22 + }, 23 + "reasonSubject": { "type": "string", "format": "at-uri" }, 24 + "reason": { 25 + "type": "string", 26 + "description": "The reason why this notification was delivered - e.g. your gallery was favd, or you received a new follower.", 27 + "knownValues": [ 28 + "follow", 29 + "gallery-favorite", 30 + "gallery-comment", 31 + "reply", 32 + "gallery-mention", 33 + "gallery-comment-mention", 34 + "unknown" 35 + ] 36 + }, 37 + "record": { "type": "unknown" }, 38 + "isRead": { "type": "boolean" }, 39 + "indexedAt": { "type": "string", "format": "datetime" } 40 + } 41 + }, 42 + "notificationViewDetailed": { 43 + "type": "object", 44 + "required": [ 45 + "uri", 46 + "cid", 47 + "author", 48 + "reason", 49 + "record", 50 + "isRead", 51 + "indexedAt" 52 + ], 53 + "properties": { 54 + "uri": { "type": "string", "format": "at-uri" }, 55 + "cid": { "type": "string", "format": "cid" }, 56 + "author": { 57 + "type": "ref", 58 + "ref": "social.grain.actor.defs#profileView" 59 + }, 60 + "reason": { 61 + "type": "string", 62 + "description": "The reason why this notification was delivered - e.g. your gallery was favd, or you received a new follower.", 63 + "knownValues": [ 64 + "follow", 65 + "gallery-favorite", 66 + "gallery-comment", 67 + "reply", 68 + "gallery-mention", 69 + "gallery-comment-mention", 70 + "unknown" 71 + ] 72 + }, 73 + "reasonSubject": { 74 + "type": "union", 75 + "refs": [ 76 + "social.grain.actor.defs#profileView", 77 + "social.grain.comment.defs#commentView", 78 + "social.grain.gallery.defs#galleryView" 79 + ] 80 + }, 81 + "record": { "type": "unknown" }, 82 + "isRead": { "type": "boolean" }, 83 + "indexedAt": { "type": "string", "format": "datetime" } 84 + } 85 + } 86 + } 87 + }
+40
lexicons/social/grain/notification/getNotifications.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.notification.getNotifications", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Enumerate notifications for the requesting account. Requires auth.", 8 + "parameters": { 9 + "type": "params", 10 + "properties": { 11 + "limit": { 12 + "type": "integer", 13 + "minimum": 1, 14 + "maximum": 100, 15 + "default": 50 16 + }, 17 + "cursor": { "type": "string" } 18 + } 19 + }, 20 + "output": { 21 + "encoding": "application/json", 22 + "schema": { 23 + "type": "object", 24 + "required": ["notifications"], 25 + "properties": { 26 + "cursor": { "type": "string" }, 27 + "notifications": { 28 + "type": "array", 29 + "items": { 30 + "type": "ref", 31 + "ref": "social.grain.notification.defs#notificationViewDetailed" 32 + } 33 + }, 34 + "seenAt": { "type": "string", "format": "datetime" } 35 + } 36 + } 37 + } 38 + } 39 + } 40 + }
+20
lexicons/social/grain/notification/updateSeen.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.notification.updateSeen", 4 + "defs": { 5 + "main": { 6 + "type": "procedure", 7 + "description": "Notify server that the requesting account has seen notifications. Requires auth.", 8 + "input": { 9 + "encoding": "application/json", 10 + "schema": { 11 + "type": "object", 12 + "required": ["seenAt"], 13 + "properties": { 14 + "seenAt": { "type": "string", "format": "datetime" } 15 + } 16 + } 17 + } 18 + } 19 + } 20 + }
+54
lexicons/social/grain/photo/applyAlts.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.photo.applyAlts", 4 + "defs": { 5 + "main": { 6 + "type": "procedure", 7 + "description": "Apply alt texts to photos in a gallery. Requires auth.", 8 + "input": { 9 + "encoding": "application/json", 10 + "schema": { 11 + "type": "object", 12 + "required": ["writes"], 13 + "properties": { 14 + "writes": { 15 + "type": "array", 16 + "items": { 17 + "type": "ref", 18 + "ref": "#update" 19 + } 20 + } 21 + } 22 + } 23 + }, 24 + "output": { 25 + "encoding": "application/json", 26 + "schema": { 27 + "type": "object", 28 + "properties": { 29 + "success": { 30 + "type": "boolean", 31 + "description": "True if the writes were successfully applied" 32 + } 33 + } 34 + } 35 + } 36 + }, 37 + "update": { 38 + "type": "object", 39 + "required": ["photoUri", "alt"], 40 + "properties": { 41 + "photoUri": { 42 + "type": "string", 43 + "format": "at-uri", 44 + "description": "AT URI of the item to update" 45 + }, 46 + "alt": { 47 + "type": "string", 48 + "maxLength": 1000, 49 + "description": "The alt text to apply to the photo" 50 + } 51 + } 52 + } 53 + } 54 + }
+44
lexicons/social/grain/photo/createExif.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.photo.createExif", 4 + "defs": { 5 + "main": { 6 + "type": "procedure", 7 + "description": "Create a new Exif record for a photo", 8 + "input": { 9 + "encoding": "application/json", 10 + "schema": { 11 + "type": "object", 12 + "required": ["photo", "createdAt"], 13 + "properties": { 14 + "photo": { "type": "string", "format": "at-uri" }, 15 + "createdAt": { "type": "string", "format": "datetime" }, 16 + "dateTimeOriginal": { "type": "string", "format": "datetime" }, 17 + "exposureTime": { "type": "integer" }, 18 + "fNumber": { "type": "integer" }, 19 + "flash": { "type": "string" }, 20 + "focalLengthIn35mmFormat": { "type": "integer" }, 21 + "iSO": { "type": "integer" }, 22 + "lensMake": { "type": "string" }, 23 + "lensModel": { "type": "string" }, 24 + "make": { "type": "string" }, 25 + "model": { "type": "string" } 26 + } 27 + } 28 + }, 29 + "output": { 30 + "encoding": "application/json", 31 + "schema": { 32 + "type": "object", 33 + "properties": { 34 + "exifUri": { 35 + "type": "string", 36 + "format": "at-uri", 37 + "description": "AT URI of the created gallery" 38 + } 39 + } 40 + } 41 + } 42 + } 43 + } 44 + }
+26
lexicons/social/grain/photo/createPhoto.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.photo.createPhoto", 4 + "defs": { 5 + "main": { 6 + "type": "procedure", 7 + "description": "Create a photo. Requires auth.", 8 + "input": { 9 + "encoding": "*/*" 10 + }, 11 + "output": { 12 + "encoding": "application/json", 13 + "schema": { 14 + "type": "object", 15 + "properties": { 16 + "photoUri": { 17 + "type": "string", 18 + "format": "at-uri", 19 + "description": "AT URI of the created photo" 20 + } 21 + } 22 + } 23 + } 24 + } 25 + } 26 + }
+68
lexicons/social/grain/photo/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.photo.defs", 4 + "defs": { 5 + "photoView": { 6 + "type": "object", 7 + "required": ["uri", "cid", "thumb", "fullsize", "alt"], 8 + "properties": { 9 + "uri": { "type": "string", "format": "at-uri" }, 10 + "cid": { "type": "string", "format": "cid" }, 11 + "thumb": { 12 + "type": "string", 13 + "format": "uri", 14 + "description": "Fully-qualified URL where a thumbnail of the image can be fetched. For example, CDN location provided by the App View." 15 + }, 16 + "fullsize": { 17 + "type": "string", 18 + "format": "uri", 19 + "description": "Fully-qualified URL where a large version of the image can be fetched. May or may not be the exact original blob. For example, CDN location provided by the App View." 20 + }, 21 + "alt": { 22 + "type": "string", 23 + "description": "Alt text description of the image, for accessibility." 24 + }, 25 + "aspectRatio": { 26 + "type": "ref", 27 + "ref": "social.grain.defs#aspectRatio" 28 + }, 29 + "exif": { 30 + "type": "ref", 31 + "ref": "social.grain.photo.defs#exifView", 32 + "description": "EXIF metadata for the photo, if available." 33 + }, 34 + "gallery": { "type": "ref", "ref": "#galleryState" } 35 + } 36 + }, 37 + "exifView": { 38 + "type": "object", 39 + "required": ["photo", "createdAt"], 40 + "properties": { 41 + "uri": { "type": "string", "format": "at-uri" }, 42 + "cid": { "type": "string", "format": "cid" }, 43 + "photo": { "type": "string", "format": "at-uri" }, 44 + "createdAt": { "type": "string", "format": "datetime" }, 45 + "dateTimeOriginal": { "type": "string" }, 46 + "exposureTime": { "type": "string" }, 47 + "fNumber": { "type": "string" }, 48 + "flash": { "type": "string" }, 49 + "focalLengthIn35mmFormat": { "type": "string" }, 50 + "iSO": { "type": "integer" }, 51 + "lensMake": { "type": "string" }, 52 + "lensModel": { "type": "string" }, 53 + "make": { "type": "string" }, 54 + "model": { "type": "string" } 55 + } 56 + }, 57 + "galleryState": { 58 + "type": "object", 59 + "required": ["item", "itemCreatedAt", "itemPosition"], 60 + "description": "Metadata about the photo's relationship with the subject content. Only has meaningful content when photo is attached to a gallery.", 61 + "properties": { 62 + "item": { "type": "string", "format": "at-uri" }, 63 + "itemCreatedAt": { "type": "string", "format": "datetime" }, 64 + "itemPosition": { "type": "integer" } 65 + } 66 + } 67 + } 68 + }
+37
lexicons/social/grain/photo/deletePhoto.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.photo.deletePhoto", 4 + "defs": { 5 + "main": { 6 + "type": "procedure", 7 + "description": "Delete a favorite photo by its unique at-uri.", 8 + "input": { 9 + "encoding": "application/json", 10 + "schema": { 11 + "type": "object", 12 + "required": ["uri"], 13 + "properties": { 14 + "uri": { 15 + "type": "string", 16 + "format": "at-uri", 17 + "description": "AT URI of the photo to delete." 18 + } 19 + } 20 + } 21 + }, 22 + "output": { 23 + "encoding": "application/json", 24 + "schema": { 25 + "type": "object", 26 + "required": ["success"], 27 + "properties": { 28 + "success": { 29 + "type": "boolean", 30 + "description": "Indicates if the photo was successfully deleted." 31 + } 32 + } 33 + } 34 + } 35 + } 36 + } 37 + }
+32
lexicons/social/grain/photo/exif.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.photo.exif", 4 + "defs": { 5 + "main": { 6 + "type": "record", 7 + "description": "Basic EXIF metadata for a photo. Integers are scaled by 1000000 to accommodate decimal values and potentially other tags in the future.", 8 + "key": "tid", 9 + "record": { 10 + "type": "object", 11 + "required": [ 12 + "photo", 13 + "createdAt" 14 + ], 15 + "properties": { 16 + "photo": { "type": "string", "format": "at-uri" }, 17 + "createdAt": { "type": "string", "format": "datetime" }, 18 + "dateTimeOriginal": { "type": "string", "format": "datetime" }, 19 + "exposureTime": { "type": "integer" }, 20 + "fNumber": { "type": "integer" }, 21 + "flash": { "type": "string" }, 22 + "focalLengthIn35mmFormat": { "type": "integer" }, 23 + "iSO": { "type": "integer" }, 24 + "lensMake": { "type": "string" }, 25 + "lensModel": { "type": "string" }, 26 + "make": { "type": "string" }, 27 + "model": { "type": "string" } 28 + } 29 + } 30 + } 31 + } 32 + }
+41
lexicons/social/grain/photo/getActorPhotos.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.photo.getActorPhotos", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Get a view of an actor's photos. Does not require auth.", 8 + "parameters": { 9 + "type": "params", 10 + "required": ["actor"], 11 + "properties": { 12 + "actor": { "type": "string", "format": "at-identifier" }, 13 + "limit": { 14 + "type": "integer", 15 + "minimum": 1, 16 + "maximum": 100, 17 + "default": 50 18 + }, 19 + "cursor": { "type": "string" } 20 + } 21 + }, 22 + "output": { 23 + "encoding": "application/json", 24 + "schema": { 25 + "type": "object", 26 + "required": ["items"], 27 + "properties": { 28 + "cursor": { "type": "string" }, 29 + "items": { 30 + "type": "array", 31 + "items": { 32 + "type": "ref", 33 + "ref": "social.grain.photo.defs#photoView" 34 + } 35 + } 36 + } 37 + } 38 + } 39 + } 40 + } 41 + }
+30
lexicons/social/grain/photo/photo.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.photo", 4 + "defs": { 5 + "main": { 6 + "type": "record", 7 + "key": "tid", 8 + "record": { 9 + "type": "object", 10 + "required": ["photo", "alt"], 11 + "properties": { 12 + "photo": { 13 + "type": "blob", 14 + "accept": ["image/*"], 15 + "maxSize": 1000000 16 + }, 17 + "alt": { 18 + "type": "string", 19 + "description": "Alt text description of the image, for accessibility." 20 + }, 21 + "aspectRatio": { 22 + "type": "ref", 23 + "ref": "social.grain.defs#aspectRatio" 24 + }, 25 + "createdAt": { "type": "string", "format": "datetime" } 26 + } 27 + } 28 + } 29 + } 30 + }
+323 -682
lib/api.dart
··· 1 1 import 'dart:convert'; 2 2 import 'dart:io'; 3 3 4 - import 'package:at_uri/at_uri.dart'; 5 4 import 'package:grain/app_logger.dart'; 6 - import 'package:grain/dpop_client.dart'; 7 5 import 'package:grain/main.dart'; 8 6 import 'package:grain/models/session.dart'; 9 - import 'package:grain/photo_manip.dart'; 10 7 import 'package:http/http.dart' as http; 11 8 import 'package:mime/mime.dart'; 12 9 ··· 14 11 import 'models/followers_result.dart'; 15 12 import 'models/follows_result.dart'; 16 13 import 'models/gallery.dart'; 17 - import 'models/gallery_item.dart'; 18 14 import 'models/gallery_photo.dart'; 19 15 import 'models/gallery_thread.dart'; 20 16 import 'models/notification.dart' as grain; 17 + import 'models/procedures/procedures.dart'; 21 18 import 'models/profile.dart'; 22 19 23 20 class ApiService { ··· 27 24 28 25 String get _apiUrl => AppConfig.apiUrl; 29 26 30 - Future<Session?> fetchSession([String? initialToken]) async { 31 - String? token = initialToken; 32 - if (token == null) { 33 - final session = await auth.getValidSession(); 34 - token = session?.token; 35 - if (token == null) return null; 27 + Future<Session?> refreshSession(Session session) async { 28 + final url = Uri.parse('$_apiUrl/api/token/refresh'); 29 + final headers = { 30 + 'Authorization': 'Bearer ${session.token}', 31 + 'Content-Type': 'application/json', 32 + }; 33 + try { 34 + final response = await http.post( 35 + url, 36 + headers: headers, 37 + body: jsonEncode({'refreshToken': session.refreshToken}), 38 + ); 39 + if (response.statusCode == 200) { 40 + appLogger.i('Session refreshed successfully'); 41 + return Session.fromJson(jsonDecode(response.body)); 42 + } else { 43 + appLogger.w('Failed to refresh session: ${response.statusCode} ${response.body}'); 44 + return null; 45 + } 46 + } catch (e) { 47 + appLogger.e('Error refreshing session: $e'); 48 + return null; 36 49 } 37 - 38 - final response = await http.get( 39 - Uri.parse('$_apiUrl/oauth/session'), 40 - headers: {'Authorization': 'Bearer $token', 'Content-Type': 'application/json'}, 41 - ); 42 - 43 - if (response.statusCode != 200) { 44 - throw Exception('Failed to fetch session'); 45 - } 46 - 47 - return Session.fromJson(jsonDecode(response.body)); 48 50 } 49 51 50 - Future<bool> revokeSession() async { 51 - final session = await auth.getValidSession(); 52 - final token = session?.token; 53 - if (token == null) { 54 - appLogger.w('No access token for revokeSession'); 55 - return false; 56 - } 57 - final url = Uri.parse('$_apiUrl/oauth/revoke'); 58 - final headers = {'Authorization': 'Bearer $token', 'Content-Type': 'application/json'}; 52 + Future<bool> revokeSession(Session session) async { 53 + final url = Uri.parse('$_apiUrl/api/token/revoke'); 54 + final headers = { 55 + 'Authorization': 'Bearer ${session.token}', 56 + 'Content-Type': 'application/json', 57 + }; 59 58 try { 60 - final response = await http.post(url, headers: headers); 59 + final response = await http.post( 60 + url, 61 + headers: headers, 62 + body: jsonEncode({'refreshToken': session.refreshToken}), 63 + ); 61 64 if (response.statusCode == 200) { 62 65 appLogger.i('Session revoked successfully'); 63 66 return true; ··· 74 77 Future<Profile?> fetchCurrentUser() async { 75 78 final session = await auth.getValidSession(); 76 79 77 - if (session == null || session.session.subject.isEmpty) { 80 + if (session == null || session.did.isEmpty) { 78 81 return null; 79 82 } 80 83 81 - final user = await fetchProfile(did: session.session.subject); 84 + final user = await fetchProfile(did: session.did); 82 85 83 86 currentUser = user; 84 87 ··· 289 292 return (json['items'] as List<dynamic>?)?.map((item) => Gallery.fromJson(item)).toList() ?? []; 290 293 } 291 294 292 - Future<String?> createGallery({ 293 - required String title, 294 - required String description, 295 - List<Map<String, dynamic>>? facets, 295 + /// Fetch followers for a given actor DID 296 + Future<FollowersResult> getFollowers({ 297 + required String actor, 298 + String? cursor, 299 + int limit = 50, 296 300 }) async { 297 - final session = await auth.getValidSession(); 298 - if (session == null) { 299 - appLogger.w('No valid session for createGallery'); 300 - return null; 301 - } 302 - final dpopClient = DpopHttpClient(dpopKey: session.session.dpopJwk); 303 - final did = session.session.subject; 304 - final url = Uri.parse('${session.pds}/xrpc/com.atproto.repo.createRecord'); 305 - final record = { 306 - 'collection': 'social.grain.gallery', 307 - 'repo': did, 308 - 'record': { 309 - 'title': title, 310 - 'description': description, 311 - if (facets != null) 'facets': facets, 312 - 'updatedAt': DateTime.now().toUtc().toIso8601String(), 313 - 'createdAt': DateTime.now().toUtc().toIso8601String(), 314 - }, 315 - }; 316 - appLogger.i('Creating gallery: $record'); 317 - final response = await dpopClient.send( 318 - method: 'POST', 319 - url: url, 320 - accessToken: session.session.accessToken, 321 - headers: {'Content-Type': 'application/json'}, 322 - body: jsonEncode(record), 301 + final uri = Uri.parse( 302 + '$_apiUrl/xrpc/social.grain.graph.getFollowers?actor=$actor&limit=$limit${cursor != null ? '&cursor=$cursor' : ''}', 323 303 ); 324 - if (response.statusCode != 200 && response.statusCode != 201) { 325 - appLogger.w('Failed to create gallery: \\${response.statusCode} \\${response.body}'); 326 - throw Exception('Failed to create gallery: \\${response.statusCode}'); 304 + final response = await http.get(uri, headers: {'Content-Type': 'application/json'}); 305 + if (response.statusCode != 200) { 306 + throw Exception('Failed to fetch followers: \\${response.statusCode} \\${response.body}'); 327 307 } 328 - final result = jsonDecode(response.body) as Map<String, dynamic>; 329 - appLogger.i('Created gallery result: $result'); 330 - final uri = result['uri'] as String?; 331 - return uri; 308 + final json = jsonDecode(response.body); 309 + return FollowersResult.fromJson(json); 332 310 } 333 311 334 - /// Polls the gallery until the number of items matches [expectedCount] or timeout. 335 - /// Returns the Gallery if successful, or null if timeout. 336 - Future<Gallery?> pollGalleryItems({ 337 - required String galleryUri, 338 - required int expectedCount, 339 - Duration pollDelay = const Duration(seconds: 2), 340 - int maxAttempts = 20, 341 - }) async { 342 - int attempts = 0; 343 - Gallery? gallery; 344 - while (attempts < maxAttempts) { 345 - gallery = await getGallery(uri: galleryUri); 346 - if (gallery != null && gallery.items.length == expectedCount) { 347 - appLogger.i('Gallery $galleryUri has expected number of items: $expectedCount'); 348 - return gallery; 349 - } 350 - await Future.delayed(pollDelay); 351 - attempts++; 352 - } 353 - appLogger.w( 354 - 'Gallery $galleryUri did not reach expected items count ($expectedCount) after polling.', 312 + /// Fetch follows for a given actor DID 313 + Future<FollowsResult> getFollows({required String actor, String? cursor, int limit = 50}) async { 314 + final uri = Uri.parse( 315 + '$_apiUrl/xrpc/social.grain.graph.getFollows?actor=$actor&limit=$limit${cursor != null ? '&cursor=$cursor' : ''}', 355 316 ); 356 - return null; 317 + final response = await http.get(uri, headers: {'Content-Type': 'application/json'}); 318 + if (response.statusCode != 200) { 319 + throw Exception('Failed to fetch follows: \\${response.statusCode} \\${response.body}'); 320 + } 321 + final json = jsonDecode(response.body); 322 + return FollowsResult.fromJson(json); 357 323 } 358 324 359 - /// Polls the gallery thread until the number of comments matches [expectedCount] or timeout. 360 - /// Returns the thread map if successful, or null if timeout. 361 - Future<GalleryThread?> pollGalleryThreadComments({ 362 - required String galleryUri, 363 - required int expectedCount, 364 - Duration pollDelay = const Duration(seconds: 2), 365 - int maxAttempts = 20, 366 - }) async { 367 - int attempts = 0; 368 - GalleryThread? thread; 369 - while (attempts < maxAttempts) { 370 - thread = await getGalleryThread(uri: galleryUri); 371 - if (thread != null && thread.comments.length == expectedCount) { 372 - appLogger.i('Gallery thread $galleryUri has expected number of comments: $expectedCount'); 373 - return thread; 374 - } 375 - await Future.delayed(pollDelay); 376 - attempts++; 325 + // Procedures 326 + 327 + Future<UpdateProfileResponse> updateProfile({required UpdateProfileRequest request}) async { 328 + final session = await auth.getValidSession(); 329 + final token = session?.token; 330 + if (token == null) { 331 + throw Exception('No access token for updateProfile'); 377 332 } 378 - appLogger.w( 379 - 'Gallery thread $galleryUri did not reach expected comments count ($expectedCount) after polling.', 333 + final uri = Uri.parse('$_apiUrl/xrpc/social.grain.actor.updateProfile'); 334 + final response = await http.post( 335 + uri, 336 + headers: {'Authorization': "Bearer $token", 'Content-Type': 'application/json'}, 337 + body: jsonEncode(request.toJson()), 380 338 ); 381 - return null; 339 + if (response.statusCode != 200) { 340 + throw Exception('Failed to update profile: ${response.statusCode} ${response.body}'); 341 + } 342 + final json = jsonDecode(response.body); 343 + return UpdateProfileResponse.fromJson(json); 382 344 } 383 345 384 - /// Uploads a blob (file) to the atproto uploadBlob endpoint using DPoP authentication. 385 - /// Returns the blob reference map on success, or null on failure. 386 - Future<Map<String, dynamic>?> uploadBlob(File file) async { 346 + Future<UpdateAvatarResponse> updateAvatar({required File avatarFile}) async { 387 347 final session = await auth.getValidSession(); 388 - if (session == null) { 389 - appLogger.w('No valid session for uploadBlob'); 390 - return null; 348 + final token = session?.token; 349 + if (token == null) { 350 + throw Exception('No access token for updateAvatar'); 391 351 } 392 - final dpopClient = DpopHttpClient(dpopKey: session.session.dpopJwk); 393 - final url = Uri.parse('${session.pds}/xrpc/com.atproto.repo.uploadBlob'); 394 - 395 - // Detect MIME type, fallback to application/octet-stream if unknown 396 - String? mimeType = lookupMimeType(file.path); 352 + final uri = Uri.parse('$_apiUrl/xrpc/social.grain.actor.updateAvatar'); 353 + String? mimeType = lookupMimeType(avatarFile.path); 397 354 final contentType = mimeType ?? 'application/octet-stream'; 398 - 399 - appLogger.i('Uploading blob: ${file.path} (MIME: $mimeType)'); 400 - 401 - final bytes = await file.readAsBytes(); 402 - 403 - final response = await dpopClient.send( 404 - method: 'POST', 405 - url: url, 406 - accessToken: session.session.accessToken, 407 - headers: {'Content-Type': contentType}, 355 + final bytes = await avatarFile.readAsBytes(); 356 + final response = await http.post( 357 + uri, 358 + headers: {'Authorization': "Bearer $token", 'Content-Type': contentType}, 408 359 body: bytes, 409 360 ); 410 - 411 - if (response.statusCode != 200 && response.statusCode != 201) { 412 - appLogger.w( 413 - 'Failed to upload blob: \\${response.statusCode} \\${response.body} (File: \\${file.path}, MIME: \\${mimeType})', 414 - ); 415 - return null; 361 + if (response.statusCode != 200) { 362 + throw Exception('Failed to update avatar: ${response.statusCode} ${response.body}'); 416 363 } 417 - 418 - try { 419 - final result = jsonDecode(response.body) as Map<String, dynamic>; 420 - appLogger.i('Uploaded blob result: $result'); 421 - return result; 422 - } catch (e, st) { 423 - appLogger.e('Failed to parse uploadBlob response: $e', stackTrace: st); 424 - return null; 425 - } 364 + final json = jsonDecode(response.body); 365 + return UpdateAvatarResponse.fromJson(json); 426 366 } 427 367 428 - Future<String?> createPhoto({ 429 - required Map<String, dynamic> blob, 430 - required int width, 431 - required int height, 432 - String alt = '', 433 - }) async { 368 + Future<ApplySortResponse> applySort({required ApplySortRequest request}) async { 434 369 final session = await auth.getValidSession(); 435 - if (session == null) { 436 - appLogger.w('No valid session for createPhotoRecord'); 437 - return null; 370 + final token = session?.token; 371 + if (token == null) { 372 + throw Exception('No access token for applySort'); 438 373 } 439 - final dpopClient = DpopHttpClient(dpopKey: session.session.dpopJwk); 440 - final did = session.session.subject; 441 - final url = Uri.parse('${session.pds}/xrpc/com.atproto.repo.createRecord'); 442 - final record = { 443 - 'collection': 'social.grain.photo', 444 - 'repo': did, 445 - 'record': { 446 - 'photo': blob['blob'], 447 - 'aspectRatio': {'width': width, 'height': height}, 448 - 'alt': "", 449 - 'createdAt': DateTime.now().toUtc().toIso8601String(), 450 - }, 451 - }; 452 - appLogger.i('Creating photo record: $record'); 453 - final response = await dpopClient.send( 454 - method: 'POST', 455 - url: url, 456 - accessToken: session.session.accessToken, 457 - headers: {'Content-Type': 'application/json'}, 458 - body: jsonEncode(record), 374 + final uri = Uri.parse('$_apiUrl/xrpc/social.grain.gallery.applySort'); 375 + final response = await http.post( 376 + uri, 377 + headers: {'Authorization': "Bearer $token", 'Content-Type': 'application/json'}, 378 + body: jsonEncode(request.toJson()), 459 379 ); 460 - if (response.statusCode != 200 && response.statusCode != 201) { 461 - appLogger.w('Failed to create photo record: \\${response.statusCode} \\${response.body}'); 462 - return null; 380 + if (response.statusCode != 200) { 381 + throw Exception('Failed to apply sort: ${response.statusCode} ${response.body}'); 463 382 } 464 - final result = jsonDecode(response.body) as Map<String, dynamic>; 465 - appLogger.i('Created photo record result: $result'); 466 - return result['uri'] as String?; 383 + final json = jsonDecode(response.body); 384 + return ApplySortResponse.fromJson(json); 467 385 } 468 386 469 - Future<String?> createGalleryItem({ 470 - required String galleryUri, 471 - required String photoUri, 472 - required int position, 473 - }) async { 387 + Future<ApplyAltsResponse> applyAlts({required ApplyAltsRequest request}) async { 474 388 final session = await auth.getValidSession(); 475 - if (session == null) { 476 - appLogger.w('No valid session for createGalleryItem'); 477 - return null; 389 + final token = session?.token; 390 + if (token == null) { 391 + throw Exception('No access token for applyAlts'); 478 392 } 479 - final dpopClient = DpopHttpClient(dpopKey: session.session.dpopJwk); 480 - final did = session.session.subject; 481 - final url = Uri.parse('${session.pds}/xrpc/com.atproto.repo.createRecord'); 482 - final record = { 483 - 'collection': 'social.grain.gallery.item', 484 - 'repo': did, 485 - 'record': { 486 - 'gallery': galleryUri, 487 - 'item': photoUri, 488 - 'position': position, 489 - 'createdAt': DateTime.now().toUtc().toIso8601String(), 490 - }, 491 - }; 492 - appLogger.i('Creating gallery item: $record'); 493 - final response = await dpopClient.send( 494 - method: 'POST', 495 - url: url, 496 - accessToken: session.session.accessToken, 497 - headers: {'Content-Type': 'application/json'}, 498 - body: jsonEncode(record), 393 + final uri = Uri.parse('$_apiUrl/xrpc/social.grain.photo.applyAlts'); 394 + final response = await http.post( 395 + uri, 396 + headers: {'Authorization': "Bearer $token", 'Content-Type': 'application/json'}, 397 + body: jsonEncode(request.toJson()), 499 398 ); 500 - if (response.statusCode != 200 && response.statusCode != 201) { 501 - appLogger.w('Failed to create gallery item: \\${response.statusCode} \\${response.body}'); 502 - return null; 399 + if (response.statusCode != 200) { 400 + throw Exception('Failed to apply alts: ${response.statusCode} ${response.body}'); 503 401 } 504 - final result = jsonDecode(response.body) as Map<String, dynamic>; 505 - appLogger.i('Created gallery item result: $result'); 506 - return result['uri'] as String?; 402 + final json = jsonDecode(response.body); 403 + return ApplyAltsResponse.fromJson(json); 507 404 } 508 405 509 - Future<String?> createComment({ 510 - required String text, 511 - List<Map<String, dynamic>>? facets, 512 - required String subject, 513 - String? focus, // Now a String (photo URI) 514 - String? replyTo, 515 - }) async { 406 + Future<CreateExifResponse> createExif({required CreateExifRequest request}) async { 516 407 final session = await auth.getValidSession(); 517 - if (session == null) { 518 - appLogger.w('No valid session for createComment'); 519 - return null; 408 + final token = session?.token; 409 + if (token == null) { 410 + throw Exception('No access token for createExif'); 520 411 } 521 - final dpopClient = DpopHttpClient(dpopKey: session.session.dpopJwk); 522 - final did = session.session.subject; 523 - final url = Uri.parse('${session.pds}/xrpc/com.atproto.repo.createRecord'); 524 - final record = { 525 - 'collection': 'social.grain.comment', 526 - 'repo': did, 527 - 'record': { 528 - 'text': text, 529 - if (facets != null) 'facets': facets, 530 - 'subject': subject, 531 - if (focus != null) 'focus': focus, // focus is now a String 532 - if (replyTo != null) 'replyTo': replyTo, 533 - 'createdAt': DateTime.now().toUtc().toIso8601String(), 534 - }, 535 - }; 536 - appLogger.i('Creating comment: $record'); 537 - final response = await dpopClient.send( 538 - method: 'POST', 539 - url: url, 540 - accessToken: session.session.accessToken, 541 - headers: {'Content-Type': 'application/json'}, 542 - body: jsonEncode(record), 412 + final uri = Uri.parse('$_apiUrl/xrpc/social.grain.photo.createExif'); 413 + final response = await http.post( 414 + uri, 415 + headers: {'Authorization': "Bearer $token", 'Content-Type': 'application/json'}, 416 + body: jsonEncode(request.toJson()), 543 417 ); 544 - if (response.statusCode != 200 && response.statusCode != 201) { 545 - appLogger.w('Failed to create comment: \\${response.statusCode} \\${response.body}'); 546 - return null; 418 + if (response.statusCode != 200) { 419 + throw Exception('Failed to create exif: ${response.statusCode} ${response.body}'); 547 420 } 548 - final result = jsonDecode(response.body) as Map<String, dynamic>; 549 - appLogger.i('Created comment result: $result'); 550 - return result['uri'] as String?; 421 + final json = jsonDecode(response.body); 422 + return CreateExifResponse.fromJson(json); 551 423 } 552 424 553 - Future<String?> createFavorite({required String galleryUri}) async { 425 + Future<CreateFollowResponse> createFollow({required CreateFollowRequest request}) async { 554 426 final session = await auth.getValidSession(); 555 - if (session == null) { 556 - appLogger.w('No valid session for createFavorite'); 557 - return null; 427 + final token = session?.token; 428 + if (token == null) { 429 + throw Exception('No access token for createFollow'); 558 430 } 559 - final dpopClient = DpopHttpClient(dpopKey: session.session.dpopJwk); 560 - final did = session.session.subject; 561 - final url = Uri.parse('${session.pds}/xrpc/com.atproto.repo.createRecord'); 562 - final record = { 563 - 'collection': 'social.grain.favorite', 564 - 'repo': did, 565 - 'record': {'subject': galleryUri, 'createdAt': DateTime.now().toUtc().toIso8601String()}, 566 - }; 567 - appLogger.i('Creating favorite: $record'); 568 - final response = await dpopClient.send( 569 - method: 'POST', 570 - url: url, 571 - accessToken: session.session.accessToken, 572 - headers: {'Content-Type': 'application/json'}, 573 - body: jsonEncode(record), 431 + final uri = Uri.parse('$_apiUrl/xrpc/social.grain.graph.createFollow'); 432 + final response = await http.post( 433 + uri, 434 + headers: {'Authorization': "Bearer $token", 'Content-Type': 'application/json'}, 435 + body: jsonEncode(request.toJson()), 574 436 ); 575 - if (response.statusCode != 200 && response.statusCode != 201) { 576 - appLogger.w('Failed to create favorite: \\${response.statusCode} \\${response.body}'); 577 - return null; 437 + if (response.statusCode != 200) { 438 + throw Exception('Failed to create follow: ${response.statusCode} ${response.body}'); 578 439 } 579 - final result = jsonDecode(response.body) as Map<String, dynamic>; 580 - appLogger.i('Created favorite result: $result'); 581 - return result['uri'] as String?; 440 + final json = jsonDecode(response.body); 441 + return CreateFollowResponse.fromJson(json); 582 442 } 583 443 584 - Future<String?> createFollow({required String followeeDid}) async { 444 + Future<DeleteFollowResponse> deleteFollow({required DeleteFollowRequest request}) async { 585 445 final session = await auth.getValidSession(); 586 - if (session == null) { 587 - appLogger.w('No valid session for createFollow'); 588 - return null; 446 + final token = session?.token; 447 + if (token == null) { 448 + throw Exception('No access token for deleteFollow'); 589 449 } 590 - final dpopClient = DpopHttpClient(dpopKey: session.session.dpopJwk); 591 - final did = session.session.subject; 592 - final url = Uri.parse('${session.pds}/xrpc/com.atproto.repo.createRecord'); 593 - final record = { 594 - 'collection': 'social.grain.graph.follow', 595 - 'repo': did, 596 - 'record': {'subject': followeeDid, 'createdAt': DateTime.now().toUtc().toIso8601String()}, 597 - }; 598 - appLogger.i('Creating follow: $record'); 599 - final response = await dpopClient.send( 600 - method: 'POST', 601 - url: url, 602 - accessToken: session.session.accessToken, 603 - headers: {'Content-Type': 'application/json'}, 604 - body: jsonEncode(record), 450 + final uri = Uri.parse('$_apiUrl/xrpc/social.grain.graph.deleteFollow'); 451 + final response = await http.post( 452 + uri, 453 + headers: {'Authorization': "Bearer $token", 'Content-Type': 'application/json'}, 454 + body: jsonEncode(request.toJson()), 605 455 ); 606 - if (response.statusCode != 200 && response.statusCode != 201) { 607 - appLogger.w('Failed to create follow: \\${response.statusCode} \\${response.body}'); 608 - return null; 456 + if (response.statusCode != 200) { 457 + throw Exception('Failed to delete follow: {response.statusCode} {response.body}'); 609 458 } 610 - final result = jsonDecode(response.body) as Map<String, dynamic>; 611 - appLogger.i('Created follow result: $result'); 612 - return result['uri'] as String?; 459 + final json = jsonDecode(response.body); 460 + return DeleteFollowResponse.fromJson(json); 613 461 } 614 462 615 - /// Deletes a record by its URI using DPoP authentication. 616 - /// Returns true on success, false on failure. 617 - Future<bool> deleteRecord(String uri) async { 463 + Future<DeletePhotoResponse> deletePhoto({required DeletePhotoRequest request}) async { 618 464 final session = await auth.getValidSession(); 619 - if (session == null) { 620 - appLogger.w('No valid session for deleteRecord'); 621 - return false; 622 - } 623 - final dpopClient = DpopHttpClient(dpopKey: session.session.dpopJwk); 624 - final url = Uri.parse('${session.pds}/xrpc/com.atproto.repo.deleteRecord'); 625 - final repo = session.session.subject; 626 - if (repo.isEmpty) { 627 - appLogger.w('No repo (DID) available from session for deleteRecord'); 628 - return false; 465 + final token = session?.token; 466 + if (token == null) { 467 + throw Exception('No access token for deletePhoto'); 629 468 } 630 - String? collection; 631 - String? rkey; 632 - try { 633 - final atUri = AtUri.parse(uri); 634 - collection = atUri.collection.toString(); 635 - rkey = atUri.rkey; 636 - } catch (e) { 637 - appLogger.w('Failed to parse collection from uri: $uri'); 638 - } 639 - if (collection == null || collection.isEmpty) { 640 - appLogger.w('No collection found in uri: $uri'); 641 - return false; 642 - } 643 - final payload = {'uri': uri, 'repo': repo, 'collection': collection, 'rkey': rkey}; 644 - appLogger.i('Deleting record: $payload'); 645 - final response = await dpopClient.send( 646 - method: 'POST', 647 - url: url, 648 - accessToken: session.session.accessToken, 649 - headers: {'Content-Type': 'application/json'}, 650 - body: jsonEncode(payload), 469 + final uri = Uri.parse('$_apiUrl/xrpc/social.grain.photo.deletePhoto'); 470 + final response = await http.post( 471 + uri, 472 + headers: {'Authorization': "Bearer $token", 'Content-Type': 'application/json'}, 473 + body: jsonEncode(request.toJson()), 651 474 ); 652 - if (response.statusCode != 200 && response.statusCode != 204) { 653 - appLogger.w('Failed to delete record: \\${response.statusCode} \\${response.body}'); 654 - return false; 475 + if (response.statusCode != 200) { 476 + throw Exception('Failed to delete photo: ${response.statusCode} ${response.body}'); 655 477 } 656 - appLogger.i('Deleted record $uri'); 657 - return true; 478 + final json = jsonDecode(response.body); 479 + return DeletePhotoResponse.fromJson(json); 658 480 } 659 481 660 - /// Updates the current user's profile (displayName, description, avatar). 661 - /// If avatarFile is provided, uploads it as a blob and sets avatar. 662 - /// Returns true on success, false on failure. 663 - Future<bool> updateProfile({ 664 - required String displayName, 665 - required String description, 666 - File? avatarFile, 667 - }) async { 482 + Future<UploadPhotoResponse> uploadPhoto(File file) async { 668 483 final session = await auth.getValidSession(); 669 484 if (session == null) { 670 - appLogger.w('No valid session for updateProfile'); 671 - return false; 485 + appLogger.w('No valid session for uploadPhoto'); 486 + throw Exception('No valid session for uploadPhoto'); 672 487 } 673 - final dpopClient = DpopHttpClient(dpopKey: session.session.dpopJwk); 674 - final did = session.session.subject; 675 - // Fetch the raw profile record from atproto getRecord endpoint 676 - final getUrl = Uri.parse( 677 - '${session.pds}/xrpc/com.atproto.repo.getRecord?repo=$did&collection=social.grain.actor.profile&rkey=self', 488 + final token = session.token; 489 + final uri = Uri.parse('${AppConfig.apiUrl}/xrpc/social.grain.photo.uploadPhoto'); 490 + 491 + // Detect MIME type, fallback to application/octet-stream if unknown 492 + String? mimeType = lookupMimeType(file.path); 493 + final contentType = mimeType ?? 'application/octet-stream'; 494 + 495 + appLogger.i('Uploading photo: ${file.path} (MIME: $mimeType)'); 496 + final bytes = await file.readAsBytes(); 497 + 498 + final response = await http.post( 499 + uri, 500 + headers: {'Authorization': 'Bearer $token', 'Content-Type': contentType}, 501 + body: bytes, 678 502 ); 679 - final getResp = await dpopClient.send( 680 - method: 'GET', 681 - url: getUrl, 682 - accessToken: session.session.accessToken, 683 - headers: {'Content-Type': 'application/json'}, 684 - ); 685 - if (getResp.statusCode != 200) { 503 + 504 + if (response.statusCode != 200 && response.statusCode != 201) { 686 505 appLogger.w( 687 - 'Failed to fetch raw profile record for update: \\${getResp.statusCode} \\${getResp.body}', 506 + 'Failed to upload photo: ${response.statusCode} ${response.body} (File: ${file.path}, MIME: $mimeType)', 688 507 ); 689 - return false; 690 - } 691 - final recordJson = jsonDecode(getResp.body) as Map<String, dynamic>; 692 - var avatar = recordJson['value']?['avatar']; 693 - // If avatarFile is provided, upload it and set avatar 694 - if (avatarFile != null) { 695 - try { 696 - // Resize avatar before upload using photo_manip 697 - final resizeResult = await resizeImage(file: avatarFile); 698 - final blobResult = await uploadBlob(resizeResult.file); 699 - if (blobResult != null && blobResult['blob'] != null) { 700 - avatar = blobResult['blob']; 701 - } 702 - } catch (e) { 703 - appLogger.w('Failed to upload avatar: $e'); 704 - } 508 + throw Exception('Failed to upload photo: ${response.statusCode} ${response.body}'); 705 509 } 706 - // Update the profile record 707 - final url = Uri.parse('${session.pds}/xrpc/com.atproto.repo.putRecord'); 708 - final record = { 709 - 'collection': 'social.grain.actor.profile', 710 - 'repo': did, 711 - 'rkey': 'self', 712 - 'record': {'displayName': displayName, 'description': description, 'avatar': avatar}, 713 - }; 714 - appLogger.i('Updating profile: $record'); 715 - final response = await dpopClient.send( 716 - method: 'POST', 717 - url: url, 718 - accessToken: session.session.accessToken, 719 - headers: {'Content-Type': 'application/json'}, 720 - body: jsonEncode(record), 721 - ); 722 - if (response.statusCode != 200 && response.statusCode != 201) { 723 - appLogger.w('Failed to update profile: \\${response.statusCode} \\${response.body}'); 724 - return false; 510 + 511 + try { 512 + final json = jsonDecode(response.body); 513 + appLogger.i('Uploaded photo result: $json'); 514 + return UploadPhotoResponse.fromJson(json); 515 + } catch (e, st) { 516 + appLogger.e('Failed to parse createPhoto response: $e', stackTrace: st); 517 + throw Exception('Failed to parse createPhoto response: $e'); 725 518 } 726 - appLogger.i('Profile updated successfully'); 727 - return true; 728 519 } 729 520 730 - /// Fetch followers for a given actor DID 731 - Future<FollowersResult> getFollowers({ 732 - required String actor, 733 - String? cursor, 734 - int limit = 50, 521 + Future<DeleteGalleryItemResponse> deleteGalleryItem({ 522 + required DeleteGalleryItemRequest request, 735 523 }) async { 736 - final uri = Uri.parse( 737 - '$_apiUrl/xrpc/social.grain.graph.getFollowers?actor=$actor&limit=$limit${cursor != null ? '&cursor=$cursor' : ''}', 524 + final session = await auth.getValidSession(); 525 + final token = session?.token; 526 + if (token == null) { 527 + throw Exception('No access token for deleteGalleryItem'); 528 + } 529 + final uri = Uri.parse('$_apiUrl/xrpc/social.grain.gallery.deleteItem'); 530 + final response = await http.post( 531 + uri, 532 + headers: {'Authorization': "Bearer $token", 'Content-Type': 'application/json'}, 533 + body: jsonEncode(request.toJson()), 738 534 ); 739 - final response = await http.get(uri, headers: {'Content-Type': 'application/json'}); 740 535 if (response.statusCode != 200) { 741 - throw Exception('Failed to fetch followers: \\${response.statusCode} \\${response.body}'); 536 + throw Exception('Failed to delete gallery item: ${response.statusCode} ${response.body}'); 742 537 } 743 538 final json = jsonDecode(response.body); 744 - return FollowersResult.fromJson(json); 539 + return DeleteGalleryItemResponse.fromJson(json); 745 540 } 746 541 747 - /// Fetch follows for a given actor DID 748 - Future<FollowsResult> getFollows({required String actor, String? cursor, int limit = 50}) async { 749 - final uri = Uri.parse( 750 - '$_apiUrl/xrpc/social.grain.graph.getFollows?actor=$actor&limit=$limit${cursor != null ? '&cursor=$cursor' : ''}', 542 + Future<CreateGalleryItemResponse> createGalleryItem({ 543 + required CreateGalleryItemRequest request, 544 + }) async { 545 + final session = await auth.getValidSession(); 546 + final token = session?.token; 547 + if (token == null) { 548 + throw Exception('No access token for createGalleryItem'); 549 + } 550 + final uri = Uri.parse('$_apiUrl/xrpc/social.grain.gallery.createItem'); 551 + final response = await http.post( 552 + uri, 553 + headers: {'Authorization': "Bearer $token", 'Content-Type': 'application/json'}, 554 + body: jsonEncode(request.toJson()), 751 555 ); 752 - final response = await http.get(uri, headers: {'Content-Type': 'application/json'}); 753 556 if (response.statusCode != 200) { 754 - throw Exception('Failed to fetch follows: \\${response.statusCode} \\${response.body}'); 557 + throw Exception('Failed to create gallery item: ${response.statusCode} ${response.body}'); 755 558 } 756 559 final json = jsonDecode(response.body); 757 - return FollowsResult.fromJson(json); 560 + return CreateGalleryItemResponse.fromJson(json); 758 561 } 759 562 760 - /// Updates the sort order of gallery items using com.atproto.repo.applyWrites 761 - /// [galleryUri]: The URI of the gallery (at://did/social.grain.gallery/rkey) 762 - /// [sortedItemUris]: List of item URIs in the desired order 763 - /// [itemsMeta]: List of GalleryItem meta objects (must include gallery, item, createdAt, uri) 764 - /// Returns true on success, false on failure 765 - Future<bool> updateGallerySortOrder({ 766 - required String galleryUri, 767 - required List<GalleryItem> orderedItems, 768 - }) async { 563 + Future<UpdateGalleryResponse> updateGallery({required UpdateGalleryRequest request}) async { 769 564 final session = await auth.getValidSession(); 770 - if (session == null) { 771 - appLogger.w('No valid session for updateGallerySortOrder'); 772 - return false; 565 + final token = session?.token; 566 + if (token == null) { 567 + throw Exception('No access token for updateGallery'); 773 568 } 774 - final dpopClient = DpopHttpClient(dpopKey: session.session.dpopJwk); 775 - final did = session.session.subject; 776 - final url = Uri.parse('${session.pds}/xrpc/com.atproto.repo.applyWrites'); 777 - 778 - final updates = <Map<String, dynamic>>[]; 779 - int position = 0; 780 - for (final item in orderedItems) { 781 - String rkey = ''; 782 - try { 783 - rkey = AtUri.parse(item.uri).rkey; 784 - } catch (_) {} 785 - updates.add({ 786 - '\$type': 'com.atproto.repo.applyWrites#update', 787 - 'collection': 'social.grain.gallery.item', 788 - 'rkey': rkey, 789 - 'value': { 790 - 'gallery': item.gallery, 791 - 'item': item.item, 792 - 'createdAt': item.createdAt, 793 - 'position': position, 794 - }, 795 - }); 796 - position++; 797 - } 798 - if (updates.isEmpty) { 799 - appLogger.w('No updates to apply for gallery sort order'); 800 - return false; 801 - } 802 - final payload = {'repo': did, 'validate': false, 'writes': updates}; 803 - appLogger.i('Applying gallery sort order updates: $payload'); 804 - final response = await dpopClient.send( 805 - method: 'POST', 806 - url: url, 807 - accessToken: session.session.accessToken, 808 - headers: {'Content-Type': 'application/json'}, 809 - body: jsonEncode(payload), 569 + final uri = Uri.parse('$_apiUrl/xrpc/social.grain.gallery.updateGallery'); 570 + final response = await http.post( 571 + uri, 572 + headers: {'Authorization': "Bearer $token", 'Content-Type': 'application/json'}, 573 + body: jsonEncode(request.toJson()), 810 574 ); 811 - if (response.statusCode != 200 && response.statusCode != 201) { 812 - appLogger.w( 813 - 'Failed to apply gallery sort order: \\${response.statusCode} \\${response.body}', 814 - ); 815 - return false; 575 + if (response.statusCode != 200) { 576 + throw Exception('Failed to update gallery: ${response.statusCode} ${response.body}'); 816 577 } 817 - appLogger.i('Gallery sort order updated successfully'); 818 - return true; 578 + final json = jsonDecode(response.body); 579 + return UpdateGalleryResponse.fromJson(json); 819 580 } 820 581 821 - /// Updates a gallery's title and description. 822 - /// Returns true on success, false on failure. 823 - Future<bool> updateGallery({ 824 - required String galleryUri, 825 - required String title, 826 - required String description, 827 - required String createdAt, 828 - List<Map<String, dynamic>>? facets, 829 - }) async { 582 + Future<DeleteGalleryResponse> deleteGallery({required DeleteGalleryRequest request}) async { 830 583 final session = await auth.getValidSession(); 831 - if (session == null) { 832 - appLogger.w('No valid session for updateGallery'); 833 - return false; 584 + final token = session?.token; 585 + if (token == null) { 586 + throw Exception('No access token for deleteGallery'); 834 587 } 835 - final dpopClient = DpopHttpClient(dpopKey: session.session.dpopJwk); 836 - final did = session.session.subject; 837 - final url = Uri.parse('${session.pds}/xrpc/com.atproto.repo.putRecord'); 838 - // Extract rkey from galleryUri 839 - String rkey = ''; 840 - try { 841 - rkey = AtUri.parse(galleryUri).rkey; 842 - } catch (_) {} 843 - if (rkey.isEmpty) { 844 - appLogger.w('No rkey found in galleryUri: $galleryUri'); 845 - return false; 846 - } 847 - final record = { 848 - 'collection': 'social.grain.gallery', 849 - 'repo': did, 850 - 'rkey': rkey, 851 - 'record': { 852 - 'title': title, 853 - 'description': description, 854 - if (facets != null) 'facets': facets, 855 - 'updatedAt': DateTime.now().toUtc().toIso8601String(), 856 - 'createdAt': createdAt, 857 - }, 858 - }; 859 - appLogger.i('Updating gallery: $record'); 860 - final response = await dpopClient.send( 861 - method: 'POST', 862 - url: url, 863 - accessToken: session.session.accessToken, 864 - headers: {'Content-Type': 'application/json'}, 865 - body: jsonEncode(record), 588 + final uri = Uri.parse('$_apiUrl/xrpc/social.grain.gallery.deleteGallery'); 589 + final response = await http.post( 590 + uri, 591 + headers: {'Authorization': "Bearer $token", 'Content-Type': 'application/json'}, 592 + body: jsonEncode(request.toJson()), 866 593 ); 867 - if (response.statusCode != 200 && response.statusCode != 201) { 868 - appLogger.w('Failed to update gallery: ${response.statusCode} ${response.body}'); 869 - return false; 594 + if (response.statusCode != 200) { 595 + throw Exception('Failed to delete gallery: ${response.statusCode} ${response.body}'); 870 596 } 871 - appLogger.i('Gallery updated successfully'); 872 - return true; 597 + final json = jsonDecode(response.body); 598 + return DeleteGalleryResponse.fromJson(json); 873 599 } 874 600 875 - /// Creates a photo EXIF record in the social.grain.photo.exif collection. 876 - /// Returns the record URI on success, or null on failure. 877 - Future<String?> createPhotoExif({ 878 - required String photo, 879 - String? createdAt, 880 - String? dateTimeOriginal, 881 - int? exposureTime, 882 - int? fNumber, 883 - String? flash, 884 - int? focalLengthIn35mmFormat, 885 - int? iSO, 886 - String? lensMake, 887 - String? lensModel, 888 - String? make, 889 - String? model, 890 - }) async { 601 + Future<CreateGalleryResponse> createGallery({required CreateGalleryRequest request}) async { 891 602 final session = await auth.getValidSession(); 892 - if (session == null) { 893 - appLogger.w('No valid session for createPhotoExif'); 894 - return null; 603 + final token = session?.token; 604 + if (token == null) { 605 + throw Exception('No access token for createGallery'); 895 606 } 896 - final dpopClient = DpopHttpClient(dpopKey: session.session.dpopJwk); 897 - final did = session.session.subject; 898 - final url = Uri.parse('${session.pds}/xrpc/com.atproto.repo.createRecord'); 899 - final record = { 900 - 'collection': 'social.grain.photo.exif', 901 - 'repo': did, 902 - 'record': { 903 - 'photo': photo, 904 - 'createdAt': createdAt ?? DateTime.now().toUtc().toIso8601String(), 905 - if (dateTimeOriginal != null) 'dateTimeOriginal': dateTimeOriginal, 906 - if (exposureTime != null) 'exposureTime': exposureTime, 907 - if (fNumber != null) 'fNumber': fNumber, 908 - if (flash != null) 'flash': flash, 909 - if (focalLengthIn35mmFormat != null) 'focalLengthIn35mmFormat': focalLengthIn35mmFormat, 910 - if (iSO != null) 'iSO': iSO, 911 - if (lensMake != null) 'lensMake': lensMake, 912 - if (lensModel != null) 'lensModel': lensModel, 913 - if (make != null) 'make': make, 914 - if (model != null) 'model': model, 915 - }, 916 - }; 917 - appLogger.i('Creating photo exif record: $record'); 918 - final response = await dpopClient.send( 919 - method: 'POST', 920 - url: url, 921 - accessToken: session.session.accessToken, 922 - headers: {'Content-Type': 'application/json'}, 923 - body: jsonEncode(record), 607 + final uri = Uri.parse('$_apiUrl/xrpc/social.grain.gallery.createGallery'); 608 + final response = await http.post( 609 + uri, 610 + headers: {'Authorization': "Bearer $token", 'Content-Type': 'application/json'}, 611 + body: jsonEncode(request.toJson()), 924 612 ); 925 - if (response.statusCode != 200 && response.statusCode != 201) { 926 - appLogger.w( 927 - 'Failed to create photo exif record: \\${response.statusCode} \\${response.body}', 928 - ); 929 - return null; 613 + if (response.statusCode != 200) { 614 + throw Exception('Failed to create gallery: ${response.statusCode} ${response.body}'); 930 615 } 931 - final result = jsonDecode(response.body) as Map<String, dynamic>; 932 - appLogger.i('Created photo exif record result: $result'); 933 - return result['uri'] as String?; 616 + final json = jsonDecode(response.body); 617 + return CreateGalleryResponse.fromJson(json); 934 618 } 935 619 936 - /// Updates multiple photo records in the social.grain.photo collection using applyWrites. 937 - /// Each photo in [updates] should have: photoUri, photo, aspectRatio, alt, createdAt 938 - /// Returns true on success, false on failure. 939 - Future<bool> updatePhotos(List<Map<String, dynamic>> updates) async { 620 + Future<DeleteFavoriteResponse> deleteFavorite({required DeleteFavoriteRequest request}) async { 940 621 final session = await auth.getValidSession(); 941 - if (session == null) { 942 - appLogger.w('No valid session for updatePhotosBatch'); 943 - return false; 622 + final token = session?.token; 623 + if (token == null) { 624 + throw Exception('No access token for deleteFavorite'); 944 625 } 945 - final dpopClient = DpopHttpClient(dpopKey: session.session.dpopJwk); 946 - final did = session.session.subject; 947 - final url = Uri.parse('${session.pds}/xrpc/com.atproto.repo.applyWrites'); 626 + final uri = Uri.parse('$_apiUrl/xrpc/social.grain.favorite.deleteFavorite'); 627 + final response = await http.post( 628 + uri, 629 + headers: {'Authorization': "Bearer $token", 'Content-Type': 'application/json'}, 630 + body: jsonEncode(request.toJson()), 631 + ); 632 + if (response.statusCode != 200) { 633 + throw Exception('Failed to delete favorite: ${response.statusCode} ${response.body}'); 634 + } 635 + final json = jsonDecode(response.body); 636 + return DeleteFavoriteResponse.fromJson(json); 637 + } 948 638 949 - // Fetch current photo records for all photos 950 - final photoRecords = await fetchPhotoRecords(); 951 - 952 - final writes = <Map<String, dynamic>>[]; 953 - for (final update in updates) { 954 - String rkey = ''; 955 - try { 956 - rkey = AtUri.parse(update['photoUri'] as String).rkey; 957 - } catch (_) {} 958 - if (rkey.isEmpty) { 959 - appLogger.w('No rkey found in photoUri: ${update['photoUri']}'); 960 - continue; 961 - } 962 - 963 - // Get the full photo record for this photoUri 964 - final record = photoRecords[update['photoUri']]; 965 - if (record == null) { 966 - appLogger.w('No photo record found for photoUri: ${update['photoUri']}'); 967 - continue; 968 - } 969 - 970 - // Use provided values or fallback to the record's values 971 - final photoBlobRef = update['photo'] ?? record['photo']; 972 - final aspectRatio = update['aspectRatio'] ?? record['aspectRatio']; 973 - final createdAt = update['createdAt'] ?? record['createdAt']; 974 - 975 - if (photoBlobRef == null) { 976 - appLogger.w('No blobRef found for photoUri: ${update['photoUri']}'); 977 - continue; 978 - } 979 - 980 - writes.add({ 981 - '\$type': 'com.atproto.repo.applyWrites#update', 982 - 'collection': 'social.grain.photo', 983 - 'rkey': rkey, 984 - 'value': { 985 - 'photo': photoBlobRef, 986 - 'aspectRatio': aspectRatio, 987 - 'alt': update['alt'] ?? '', 988 - 'createdAt': createdAt, 989 - }, 990 - }); 639 + Future<CreateFavoriteResponse> createFavorite({required CreateFavoriteRequest request}) async { 640 + final session = await auth.getValidSession(); 641 + final token = session?.token; 642 + if (token == null) { 643 + throw Exception('No access token for createFavorite'); 991 644 } 992 - if (writes.isEmpty) { 993 - appLogger.w('No valid photo updates to apply'); 994 - return false; 995 - } 996 - final payload = {'repo': did, 'validate': false, 'writes': writes}; 997 - appLogger.i('Applying batch photo updates: $payload'); 998 - final response = await dpopClient.send( 999 - method: 'POST', 1000 - url: url, 1001 - accessToken: session.session.accessToken, 1002 - headers: {'Content-Type': 'application/json'}, 1003 - body: jsonEncode(payload), 645 + final uri = Uri.parse('$_apiUrl/xrpc/social.grain.favorite.createFavorite'); 646 + final response = await http.post( 647 + uri, 648 + headers: {'Authorization': "Bearer $token", 'Content-Type': 'application/json'}, 649 + body: jsonEncode(request.toJson()), 1004 650 ); 1005 - if (response.statusCode != 200 && response.statusCode != 201) { 1006 - appLogger.w('Failed to apply batch photo updates: ${response.statusCode} ${response.body}'); 1007 - return false; 651 + if (response.statusCode != 200) { 652 + throw Exception('Failed to create favorite: ${response.statusCode} ${response.body}'); 1008 653 } 1009 - appLogger.i('Batch photo updates applied successfully'); 1010 - return true; 654 + final json = jsonDecode(response.body); 655 + return CreateFavoriteResponse.fromJson(json); 1011 656 } 1012 657 1013 - /// Fetches the full photo record for each photo in social.grain.photo. 1014 - /// Returns a map of photoUri -> photo record (Map`<`String, dynamic`>`). 1015 - Future<Map<String, dynamic>> fetchPhotoRecords() async { 658 + Future<DeleteCommentResponse> deleteComment({required DeleteCommentRequest request}) async { 1016 659 final session = await auth.getValidSession(); 1017 - if (session == null) { 1018 - appLogger.w('No valid session for fetchPhotoRecords'); 1019 - return {}; 660 + final token = session?.token; 661 + if (token == null) { 662 + throw Exception('No access token for deleteComment'); 1020 663 } 1021 - final dpopClient = DpopHttpClient(dpopKey: session.session.dpopJwk); 1022 - final did = session.session.subject; 1023 - final url = Uri.parse( 1024 - '${session.pds}/xrpc/com.atproto.repo.listRecords?repo=$did&collection=social.grain.photo', 664 + final uri = Uri.parse('$_apiUrl/xrpc/social.grain.comment.deleteComment'); 665 + final response = await http.post( 666 + uri, 667 + headers: {'Authorization': "Bearer $token", 'Content-Type': 'application/json'}, 668 + body: jsonEncode(request.toJson()), 1025 669 ); 1026 - 1027 - final response = await dpopClient.send( 1028 - method: 'GET', 1029 - url: url, 1030 - accessToken: session.session.accessToken, 1031 - headers: {'Content-Type': 'application/json'}, 1032 - ); 1033 - 1034 670 if (response.statusCode != 200) { 1035 - appLogger.w('Failed to list photo records: ${response.statusCode} ${response.body}'); 1036 - return {}; 671 + throw Exception('Failed to delete comment: ${response.statusCode} ${response.body}'); 1037 672 } 1038 - 1039 - final json = jsonDecode(response.body) as Map<String, dynamic>; 1040 - final records = json['records'] as List<dynamic>? ?? []; 1041 - final photoRecords = <String, dynamic>{}; 673 + final json = jsonDecode(response.body); 674 + return DeleteCommentResponse.fromJson(json); 675 + } 1042 676 1043 - for (final record in records) { 1044 - final uri = record['uri'] as String?; 1045 - final value = record['value'] as Map<String, dynamic>?; 1046 - if (uri != null && value != null) { 1047 - photoRecords[uri] = value; 1048 - } 677 + Future<CreateCommentResponse> createComment({required CreateCommentRequest request}) async { 678 + final session = await auth.getValidSession(); 679 + final token = session?.token; 680 + if (token == null) { 681 + throw Exception('No access token for createComment'); 682 + } 683 + final uri = Uri.parse('$_apiUrl/xrpc/social.grain.comment.createComment'); 684 + final response = await http.post( 685 + uri, 686 + headers: {'Authorization': "Bearer $token", 'Content-Type': 'application/json'}, 687 + body: jsonEncode(request.toJson()), 688 + ); 689 + if (response.statusCode != 200) { 690 + throw Exception('Failed to create comment: ${response.statusCode} ${response.body}'); 1049 691 } 1050 - return photoRecords; 692 + final json = jsonDecode(response.body); 693 + return CreateCommentResponse.fromJson(json); 1051 694 } 1052 695 1053 - /// Notifies the server that the requesting account has seen notifications. 1054 - /// Sends a POST request with the current ISO timestamp as seenAt. 1055 696 Future<bool> updateSeen() async { 1056 697 final session = await auth.getValidSession(); 1057 698 final token = session?.token;
+70 -21
lib/auth.dart
··· 5 5 import 'package:grain/api.dart'; 6 6 import 'package:grain/app_logger.dart'; 7 7 import 'package:grain/main.dart'; 8 - import 'package:grain/models/atproto_session.dart'; 9 8 import 'package:grain/models/session.dart'; 10 9 11 10 class Auth { ··· 14 13 15 14 Future<bool> hasToken() async { 16 15 final session = await _loadSession(); 17 - return session != null && session.token.isNotEmpty && !isSessionExpired(session.session); 16 + return session != null && session.token.isNotEmpty && !isSessionExpired(session); 18 17 } 19 18 20 19 Future<void> login(String handle) async { 21 20 final apiUrl = AppConfig.apiUrl; 22 - final redirectedUrl = await FlutterWebAuth2.authenticate( 23 - url: '$apiUrl/oauth/login?client=native&handle=${Uri.encodeComponent(handle)}', 24 - callbackUrlScheme: 'grainflutter', 25 - ); 26 - final uri = Uri.parse(redirectedUrl); 27 - final token = uri.queryParameters['token']; 21 + String? token; 22 + String? refreshToken; 23 + String? expiresAtStr; 24 + String? did; 25 + 26 + try { 27 + final redirectUrl = await FlutterWebAuth2.authenticate( 28 + url: '$apiUrl/oauth/login?client=native&handle=${Uri.encodeComponent(handle)}', 29 + callbackUrlScheme: 'grainflutter', 30 + ); 31 + 32 + appLogger.i('Redirected URL: $redirectUrl'); 28 33 29 - appLogger.i('Redirected URL: $redirectedUrl'); 34 + final uri = Uri.parse(redirectUrl); 35 + token = uri.queryParameters['token']; 36 + refreshToken = uri.queryParameters['refreshToken']; 37 + expiresAtStr = uri.queryParameters['expiresAt']; 38 + did = uri.queryParameters['did']; 39 + } catch (e) { 40 + appLogger.e('Error during authentication: $e'); 41 + throw Exception('Authentication failed'); 42 + } 43 + 30 44 appLogger.i('User signed in with handle: $handle'); 31 45 32 - final session = await apiService.fetchSession(token); 33 - if (session == null) { 34 - throw Exception('Failed to fetch session after login'); 46 + if (token == null || token.isEmpty) { 47 + throw Exception('No token found in redirect URL'); 48 + } 49 + if (refreshToken == null || refreshToken.isEmpty) { 50 + throw Exception('No refreshToken found in redirect URL'); 51 + } 52 + if (expiresAtStr == null || expiresAtStr.isEmpty) { 53 + throw Exception('No expiresAt found in redirect URL'); 54 + } 55 + if (did == null || did.isEmpty) { 56 + throw Exception('No did found in redirect URL'); 57 + } 58 + 59 + DateTime expiresAt; 60 + try { 61 + expiresAt = DateTime.parse(expiresAtStr); 62 + } catch (e) { 63 + throw Exception('Invalid expiresAt format'); 35 64 } 65 + 66 + final session = Session( 67 + token: token, 68 + refreshToken: refreshToken, 69 + expiresAt: expiresAt, 70 + did: did, 71 + ); 36 72 await _saveSession(session); 37 73 } 38 74 ··· 54 90 } 55 91 } 56 92 57 - bool isSessionExpired( 58 - AtprotoSession session, { 59 - Duration tolerance = const Duration(seconds: 30), 60 - }) { 93 + bool isSessionExpired(Session session, {Duration tolerance = const Duration(seconds: 30)}) { 61 94 final now = DateTime.now().toUtc(); 62 95 return session.expiresAt.subtract(tolerance).isBefore(now); 63 96 } ··· 68 101 // No session at all, do not attempt refresh 69 102 return null; 70 103 } 71 - if (isSessionExpired(session.session)) { 104 + if (isSessionExpired(session)) { 72 105 appLogger.w('Session is expired, attempting refresh'); 73 106 try { 74 - final refreshed = await apiService.fetchSession(); 75 - if (refreshed != null && !isSessionExpired(refreshed.session)) { 107 + final refreshed = await apiService.refreshSession(session); 108 + if (refreshed != null && !isSessionExpired(refreshed)) { 76 109 await _saveSession(refreshed); 77 110 appLogger.i('Session refreshed and saved'); 78 111 return refreshed; ··· 91 124 } 92 125 93 126 Future<void> clearSession() async { 94 - // Revoke session on the server 95 - await apiService.revokeSession(); 96 127 // Remove session from secure storage 97 128 await _storage.delete(key: 'session'); 129 + } 130 + 131 + Future<void> logout() async { 132 + final session = await _loadSession(); 133 + 134 + appLogger.i('Logging out user with session: $session'); 135 + 98 136 // Clear any in-memory session/user data 99 137 apiService.currentUser = null; 138 + 139 + if (session == null) { 140 + appLogger.w('No session to revoke'); 141 + return; 142 + } 143 + 144 + await apiService.revokeSession(session); 145 + 146 + await clearSession(); 147 + 148 + appLogger.i('User logged out and session cleared'); 100 149 } 101 150 } 102 151
+1 -1
lib/main.dart
··· 129 129 } 130 130 131 131 void _handleSignOut(BuildContext context) async { 132 - await auth.clearSession(); 132 + await auth.logout(); 133 133 setState(() { 134 134 isSignedIn = false; 135 135 });
-19
lib/models/atproto_session.dart
··· 1 - import 'package:freezed_annotation/freezed_annotation.dart'; 2 - import 'package:jose/jose.dart'; 3 - 4 - part 'atproto_session.freezed.dart'; 5 - part 'atproto_session.g.dart'; 6 - 7 - @freezed 8 - class AtprotoSession with _$AtprotoSession { 9 - const factory AtprotoSession({ 10 - required String accessToken, 11 - required String tokenType, 12 - required DateTime expiresAt, 13 - required JsonWebKey dpopJwk, 14 - required String issuer, 15 - required String subject, 16 - }) = _AtprotoSession; 17 - 18 - factory AtprotoSession.fromJson(Map<String, dynamic> json) => _$AtprotoSessionFromJson(json); 19 - }
-293
lib/models/atproto_session.freezed.dart
··· 1 - // coverage:ignore-file 2 - // GENERATED CODE - DO NOT MODIFY BY HAND 3 - // ignore_for_file: type=lint 4 - // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark 5 - 6 - part of 'atproto_session.dart'; 7 - 8 - // ************************************************************************** 9 - // FreezedGenerator 10 - // ************************************************************************** 11 - 12 - T _$identity<T>(T value) => value; 13 - 14 - final _privateConstructorUsedError = UnsupportedError( 15 - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', 16 - ); 17 - 18 - AtprotoSession _$AtprotoSessionFromJson(Map<String, dynamic> json) { 19 - return _AtprotoSession.fromJson(json); 20 - } 21 - 22 - /// @nodoc 23 - mixin _$AtprotoSession { 24 - String get accessToken => throw _privateConstructorUsedError; 25 - String get tokenType => throw _privateConstructorUsedError; 26 - DateTime get expiresAt => throw _privateConstructorUsedError; 27 - JsonWebKey get dpopJwk => throw _privateConstructorUsedError; 28 - String get issuer => throw _privateConstructorUsedError; 29 - String get subject => throw _privateConstructorUsedError; 30 - 31 - /// Serializes this AtprotoSession to a JSON map. 32 - Map<String, dynamic> toJson() => throw _privateConstructorUsedError; 33 - 34 - /// Create a copy of AtprotoSession 35 - /// with the given fields replaced by the non-null parameter values. 36 - @JsonKey(includeFromJson: false, includeToJson: false) 37 - $AtprotoSessionCopyWith<AtprotoSession> get copyWith => 38 - throw _privateConstructorUsedError; 39 - } 40 - 41 - /// @nodoc 42 - abstract class $AtprotoSessionCopyWith<$Res> { 43 - factory $AtprotoSessionCopyWith( 44 - AtprotoSession value, 45 - $Res Function(AtprotoSession) then, 46 - ) = _$AtprotoSessionCopyWithImpl<$Res, AtprotoSession>; 47 - @useResult 48 - $Res call({ 49 - String accessToken, 50 - String tokenType, 51 - DateTime expiresAt, 52 - JsonWebKey dpopJwk, 53 - String issuer, 54 - String subject, 55 - }); 56 - } 57 - 58 - /// @nodoc 59 - class _$AtprotoSessionCopyWithImpl<$Res, $Val extends AtprotoSession> 60 - implements $AtprotoSessionCopyWith<$Res> { 61 - _$AtprotoSessionCopyWithImpl(this._value, this._then); 62 - 63 - // ignore: unused_field 64 - final $Val _value; 65 - // ignore: unused_field 66 - final $Res Function($Val) _then; 67 - 68 - /// Create a copy of AtprotoSession 69 - /// with the given fields replaced by the non-null parameter values. 70 - @pragma('vm:prefer-inline') 71 - @override 72 - $Res call({ 73 - Object? accessToken = null, 74 - Object? tokenType = null, 75 - Object? expiresAt = null, 76 - Object? dpopJwk = null, 77 - Object? issuer = null, 78 - Object? subject = null, 79 - }) { 80 - return _then( 81 - _value.copyWith( 82 - accessToken: null == accessToken 83 - ? _value.accessToken 84 - : accessToken // ignore: cast_nullable_to_non_nullable 85 - as String, 86 - tokenType: null == tokenType 87 - ? _value.tokenType 88 - : tokenType // ignore: cast_nullable_to_non_nullable 89 - as String, 90 - expiresAt: null == expiresAt 91 - ? _value.expiresAt 92 - : expiresAt // ignore: cast_nullable_to_non_nullable 93 - as DateTime, 94 - dpopJwk: null == dpopJwk 95 - ? _value.dpopJwk 96 - : dpopJwk // ignore: cast_nullable_to_non_nullable 97 - as JsonWebKey, 98 - issuer: null == issuer 99 - ? _value.issuer 100 - : issuer // ignore: cast_nullable_to_non_nullable 101 - as String, 102 - subject: null == subject 103 - ? _value.subject 104 - : subject // ignore: cast_nullable_to_non_nullable 105 - as String, 106 - ) 107 - as $Val, 108 - ); 109 - } 110 - } 111 - 112 - /// @nodoc 113 - abstract class _$$AtprotoSessionImplCopyWith<$Res> 114 - implements $AtprotoSessionCopyWith<$Res> { 115 - factory _$$AtprotoSessionImplCopyWith( 116 - _$AtprotoSessionImpl value, 117 - $Res Function(_$AtprotoSessionImpl) then, 118 - ) = __$$AtprotoSessionImplCopyWithImpl<$Res>; 119 - @override 120 - @useResult 121 - $Res call({ 122 - String accessToken, 123 - String tokenType, 124 - DateTime expiresAt, 125 - JsonWebKey dpopJwk, 126 - String issuer, 127 - String subject, 128 - }); 129 - } 130 - 131 - /// @nodoc 132 - class __$$AtprotoSessionImplCopyWithImpl<$Res> 133 - extends _$AtprotoSessionCopyWithImpl<$Res, _$AtprotoSessionImpl> 134 - implements _$$AtprotoSessionImplCopyWith<$Res> { 135 - __$$AtprotoSessionImplCopyWithImpl( 136 - _$AtprotoSessionImpl _value, 137 - $Res Function(_$AtprotoSessionImpl) _then, 138 - ) : super(_value, _then); 139 - 140 - /// Create a copy of AtprotoSession 141 - /// with the given fields replaced by the non-null parameter values. 142 - @pragma('vm:prefer-inline') 143 - @override 144 - $Res call({ 145 - Object? accessToken = null, 146 - Object? tokenType = null, 147 - Object? expiresAt = null, 148 - Object? dpopJwk = null, 149 - Object? issuer = null, 150 - Object? subject = null, 151 - }) { 152 - return _then( 153 - _$AtprotoSessionImpl( 154 - accessToken: null == accessToken 155 - ? _value.accessToken 156 - : accessToken // ignore: cast_nullable_to_non_nullable 157 - as String, 158 - tokenType: null == tokenType 159 - ? _value.tokenType 160 - : tokenType // ignore: cast_nullable_to_non_nullable 161 - as String, 162 - expiresAt: null == expiresAt 163 - ? _value.expiresAt 164 - : expiresAt // ignore: cast_nullable_to_non_nullable 165 - as DateTime, 166 - dpopJwk: null == dpopJwk 167 - ? _value.dpopJwk 168 - : dpopJwk // ignore: cast_nullable_to_non_nullable 169 - as JsonWebKey, 170 - issuer: null == issuer 171 - ? _value.issuer 172 - : issuer // ignore: cast_nullable_to_non_nullable 173 - as String, 174 - subject: null == subject 175 - ? _value.subject 176 - : subject // ignore: cast_nullable_to_non_nullable 177 - as String, 178 - ), 179 - ); 180 - } 181 - } 182 - 183 - /// @nodoc 184 - @JsonSerializable() 185 - class _$AtprotoSessionImpl implements _AtprotoSession { 186 - const _$AtprotoSessionImpl({ 187 - required this.accessToken, 188 - required this.tokenType, 189 - required this.expiresAt, 190 - required this.dpopJwk, 191 - required this.issuer, 192 - required this.subject, 193 - }); 194 - 195 - factory _$AtprotoSessionImpl.fromJson(Map<String, dynamic> json) => 196 - _$$AtprotoSessionImplFromJson(json); 197 - 198 - @override 199 - final String accessToken; 200 - @override 201 - final String tokenType; 202 - @override 203 - final DateTime expiresAt; 204 - @override 205 - final JsonWebKey dpopJwk; 206 - @override 207 - final String issuer; 208 - @override 209 - final String subject; 210 - 211 - @override 212 - String toString() { 213 - return 'AtprotoSession(accessToken: $accessToken, tokenType: $tokenType, expiresAt: $expiresAt, dpopJwk: $dpopJwk, issuer: $issuer, subject: $subject)'; 214 - } 215 - 216 - @override 217 - bool operator ==(Object other) { 218 - return identical(this, other) || 219 - (other.runtimeType == runtimeType && 220 - other is _$AtprotoSessionImpl && 221 - (identical(other.accessToken, accessToken) || 222 - other.accessToken == accessToken) && 223 - (identical(other.tokenType, tokenType) || 224 - other.tokenType == tokenType) && 225 - (identical(other.expiresAt, expiresAt) || 226 - other.expiresAt == expiresAt) && 227 - (identical(other.dpopJwk, dpopJwk) || other.dpopJwk == dpopJwk) && 228 - (identical(other.issuer, issuer) || other.issuer == issuer) && 229 - (identical(other.subject, subject) || other.subject == subject)); 230 - } 231 - 232 - @JsonKey(includeFromJson: false, includeToJson: false) 233 - @override 234 - int get hashCode => Object.hash( 235 - runtimeType, 236 - accessToken, 237 - tokenType, 238 - expiresAt, 239 - dpopJwk, 240 - issuer, 241 - subject, 242 - ); 243 - 244 - /// Create a copy of AtprotoSession 245 - /// with the given fields replaced by the non-null parameter values. 246 - @JsonKey(includeFromJson: false, includeToJson: false) 247 - @override 248 - @pragma('vm:prefer-inline') 249 - _$$AtprotoSessionImplCopyWith<_$AtprotoSessionImpl> get copyWith => 250 - __$$AtprotoSessionImplCopyWithImpl<_$AtprotoSessionImpl>( 251 - this, 252 - _$identity, 253 - ); 254 - 255 - @override 256 - Map<String, dynamic> toJson() { 257 - return _$$AtprotoSessionImplToJson(this); 258 - } 259 - } 260 - 261 - abstract class _AtprotoSession implements AtprotoSession { 262 - const factory _AtprotoSession({ 263 - required final String accessToken, 264 - required final String tokenType, 265 - required final DateTime expiresAt, 266 - required final JsonWebKey dpopJwk, 267 - required final String issuer, 268 - required final String subject, 269 - }) = _$AtprotoSessionImpl; 270 - 271 - factory _AtprotoSession.fromJson(Map<String, dynamic> json) = 272 - _$AtprotoSessionImpl.fromJson; 273 - 274 - @override 275 - String get accessToken; 276 - @override 277 - String get tokenType; 278 - @override 279 - DateTime get expiresAt; 280 - @override 281 - JsonWebKey get dpopJwk; 282 - @override 283 - String get issuer; 284 - @override 285 - String get subject; 286 - 287 - /// Create a copy of AtprotoSession 288 - /// with the given fields replaced by the non-null parameter values. 289 - @override 290 - @JsonKey(includeFromJson: false, includeToJson: false) 291 - _$$AtprotoSessionImplCopyWith<_$AtprotoSessionImpl> get copyWith => 292 - throw _privateConstructorUsedError; 293 - }
-28
lib/models/atproto_session.g.dart
··· 1 - // GENERATED CODE - DO NOT MODIFY BY HAND 2 - 3 - part of 'atproto_session.dart'; 4 - 5 - // ************************************************************************** 6 - // JsonSerializableGenerator 7 - // ************************************************************************** 8 - 9 - _$AtprotoSessionImpl _$$AtprotoSessionImplFromJson(Map<String, dynamic> json) => 10 - _$AtprotoSessionImpl( 11 - accessToken: json['accessToken'] as String, 12 - tokenType: json['tokenType'] as String, 13 - expiresAt: DateTime.parse(json['expiresAt'] as String), 14 - dpopJwk: JsonWebKey.fromJson(json['dpopJwk'] as Map<String, dynamic>), 15 - issuer: json['issuer'] as String, 16 - subject: json['subject'] as String, 17 - ); 18 - 19 - Map<String, dynamic> _$$AtprotoSessionImplToJson( 20 - _$AtprotoSessionImpl instance, 21 - ) => <String, dynamic>{ 22 - 'accessToken': instance.accessToken, 23 - 'tokenType': instance.tokenType, 24 - 'expiresAt': instance.expiresAt.toIso8601String(), 25 - 'dpopJwk': instance.dpopJwk, 26 - 'issuer': instance.issuer, 27 - 'subject': instance.subject, 28 - };
+15
lib/models/procedures/apply_alts_request.dart
··· 1 + import 'package:freezed_annotation/freezed_annotation.dart'; 2 + 3 + import 'apply_alts_update.dart'; 4 + 5 + part 'apply_alts_request.freezed.dart'; 6 + part 'apply_alts_request.g.dart'; 7 + 8 + /// Request to apply alt texts to photos in a gallery. 9 + /// Requires auth. 10 + @freezed 11 + class ApplyAltsRequest with _$ApplyAltsRequest { 12 + const factory ApplyAltsRequest({required List<ApplyAltsUpdate> writes}) = _ApplyAltsRequest; 13 + 14 + factory ApplyAltsRequest.fromJson(Map<String, dynamic> json) => _$ApplyAltsRequestFromJson(json); 15 + }
+179
lib/models/procedures/apply_alts_request.freezed.dart
··· 1 + // coverage:ignore-file 2 + // GENERATED CODE - DO NOT MODIFY BY HAND 3 + // ignore_for_file: type=lint 4 + // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark 5 + 6 + part of 'apply_alts_request.dart'; 7 + 8 + // ************************************************************************** 9 + // FreezedGenerator 10 + // ************************************************************************** 11 + 12 + T _$identity<T>(T value) => value; 13 + 14 + final _privateConstructorUsedError = UnsupportedError( 15 + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', 16 + ); 17 + 18 + ApplyAltsRequest _$ApplyAltsRequestFromJson(Map<String, dynamic> json) { 19 + return _ApplyAltsRequest.fromJson(json); 20 + } 21 + 22 + /// @nodoc 23 + mixin _$ApplyAltsRequest { 24 + List<ApplyAltsUpdate> get writes => throw _privateConstructorUsedError; 25 + 26 + /// Serializes this ApplyAltsRequest to a JSON map. 27 + Map<String, dynamic> toJson() => throw _privateConstructorUsedError; 28 + 29 + /// Create a copy of ApplyAltsRequest 30 + /// with the given fields replaced by the non-null parameter values. 31 + @JsonKey(includeFromJson: false, includeToJson: false) 32 + $ApplyAltsRequestCopyWith<ApplyAltsRequest> get copyWith => 33 + throw _privateConstructorUsedError; 34 + } 35 + 36 + /// @nodoc 37 + abstract class $ApplyAltsRequestCopyWith<$Res> { 38 + factory $ApplyAltsRequestCopyWith( 39 + ApplyAltsRequest value, 40 + $Res Function(ApplyAltsRequest) then, 41 + ) = _$ApplyAltsRequestCopyWithImpl<$Res, ApplyAltsRequest>; 42 + @useResult 43 + $Res call({List<ApplyAltsUpdate> writes}); 44 + } 45 + 46 + /// @nodoc 47 + class _$ApplyAltsRequestCopyWithImpl<$Res, $Val extends ApplyAltsRequest> 48 + implements $ApplyAltsRequestCopyWith<$Res> { 49 + _$ApplyAltsRequestCopyWithImpl(this._value, this._then); 50 + 51 + // ignore: unused_field 52 + final $Val _value; 53 + // ignore: unused_field 54 + final $Res Function($Val) _then; 55 + 56 + /// Create a copy of ApplyAltsRequest 57 + /// with the given fields replaced by the non-null parameter values. 58 + @pragma('vm:prefer-inline') 59 + @override 60 + $Res call({Object? writes = null}) { 61 + return _then( 62 + _value.copyWith( 63 + writes: null == writes 64 + ? _value.writes 65 + : writes // ignore: cast_nullable_to_non_nullable 66 + as List<ApplyAltsUpdate>, 67 + ) 68 + as $Val, 69 + ); 70 + } 71 + } 72 + 73 + /// @nodoc 74 + abstract class _$$ApplyAltsRequestImplCopyWith<$Res> 75 + implements $ApplyAltsRequestCopyWith<$Res> { 76 + factory _$$ApplyAltsRequestImplCopyWith( 77 + _$ApplyAltsRequestImpl value, 78 + $Res Function(_$ApplyAltsRequestImpl) then, 79 + ) = __$$ApplyAltsRequestImplCopyWithImpl<$Res>; 80 + @override 81 + @useResult 82 + $Res call({List<ApplyAltsUpdate> writes}); 83 + } 84 + 85 + /// @nodoc 86 + class __$$ApplyAltsRequestImplCopyWithImpl<$Res> 87 + extends _$ApplyAltsRequestCopyWithImpl<$Res, _$ApplyAltsRequestImpl> 88 + implements _$$ApplyAltsRequestImplCopyWith<$Res> { 89 + __$$ApplyAltsRequestImplCopyWithImpl( 90 + _$ApplyAltsRequestImpl _value, 91 + $Res Function(_$ApplyAltsRequestImpl) _then, 92 + ) : super(_value, _then); 93 + 94 + /// Create a copy of ApplyAltsRequest 95 + /// with the given fields replaced by the non-null parameter values. 96 + @pragma('vm:prefer-inline') 97 + @override 98 + $Res call({Object? writes = null}) { 99 + return _then( 100 + _$ApplyAltsRequestImpl( 101 + writes: null == writes 102 + ? _value._writes 103 + : writes // ignore: cast_nullable_to_non_nullable 104 + as List<ApplyAltsUpdate>, 105 + ), 106 + ); 107 + } 108 + } 109 + 110 + /// @nodoc 111 + @JsonSerializable() 112 + class _$ApplyAltsRequestImpl implements _ApplyAltsRequest { 113 + const _$ApplyAltsRequestImpl({required final List<ApplyAltsUpdate> writes}) 114 + : _writes = writes; 115 + 116 + factory _$ApplyAltsRequestImpl.fromJson(Map<String, dynamic> json) => 117 + _$$ApplyAltsRequestImplFromJson(json); 118 + 119 + final List<ApplyAltsUpdate> _writes; 120 + @override 121 + List<ApplyAltsUpdate> get writes { 122 + if (_writes is EqualUnmodifiableListView) return _writes; 123 + // ignore: implicit_dynamic_type 124 + return EqualUnmodifiableListView(_writes); 125 + } 126 + 127 + @override 128 + String toString() { 129 + return 'ApplyAltsRequest(writes: $writes)'; 130 + } 131 + 132 + @override 133 + bool operator ==(Object other) { 134 + return identical(this, other) || 135 + (other.runtimeType == runtimeType && 136 + other is _$ApplyAltsRequestImpl && 137 + const DeepCollectionEquality().equals(other._writes, _writes)); 138 + } 139 + 140 + @JsonKey(includeFromJson: false, includeToJson: false) 141 + @override 142 + int get hashCode => 143 + Object.hash(runtimeType, const DeepCollectionEquality().hash(_writes)); 144 + 145 + /// Create a copy of ApplyAltsRequest 146 + /// with the given fields replaced by the non-null parameter values. 147 + @JsonKey(includeFromJson: false, includeToJson: false) 148 + @override 149 + @pragma('vm:prefer-inline') 150 + _$$ApplyAltsRequestImplCopyWith<_$ApplyAltsRequestImpl> get copyWith => 151 + __$$ApplyAltsRequestImplCopyWithImpl<_$ApplyAltsRequestImpl>( 152 + this, 153 + _$identity, 154 + ); 155 + 156 + @override 157 + Map<String, dynamic> toJson() { 158 + return _$$ApplyAltsRequestImplToJson(this); 159 + } 160 + } 161 + 162 + abstract class _ApplyAltsRequest implements ApplyAltsRequest { 163 + const factory _ApplyAltsRequest({ 164 + required final List<ApplyAltsUpdate> writes, 165 + }) = _$ApplyAltsRequestImpl; 166 + 167 + factory _ApplyAltsRequest.fromJson(Map<String, dynamic> json) = 168 + _$ApplyAltsRequestImpl.fromJson; 169 + 170 + @override 171 + List<ApplyAltsUpdate> get writes; 172 + 173 + /// Create a copy of ApplyAltsRequest 174 + /// with the given fields replaced by the non-null parameter values. 175 + @override 176 + @JsonKey(includeFromJson: false, includeToJson: false) 177 + _$$ApplyAltsRequestImplCopyWith<_$ApplyAltsRequestImpl> get copyWith => 178 + throw _privateConstructorUsedError; 179 + }
+19
lib/models/procedures/apply_alts_request.g.dart
··· 1 + // GENERATED CODE - DO NOT MODIFY BY HAND 2 + 3 + part of 'apply_alts_request.dart'; 4 + 5 + // ************************************************************************** 6 + // JsonSerializableGenerator 7 + // ************************************************************************** 8 + 9 + _$ApplyAltsRequestImpl _$$ApplyAltsRequestImplFromJson( 10 + Map<String, dynamic> json, 11 + ) => _$ApplyAltsRequestImpl( 12 + writes: (json['writes'] as List<dynamic>) 13 + .map((e) => ApplyAltsUpdate.fromJson(e as Map<String, dynamic>)) 14 + .toList(), 15 + ); 16 + 17 + Map<String, dynamic> _$$ApplyAltsRequestImplToJson( 18 + _$ApplyAltsRequestImpl instance, 19 + ) => <String, dynamic>{'writes': instance.writes};
+14
lib/models/procedures/apply_alts_response.dart
··· 1 + import 'package:freezed_annotation/freezed_annotation.dart'; 2 + 3 + part 'apply_alts_response.freezed.dart'; 4 + part 'apply_alts_response.g.dart'; 5 + 6 + /// Response for applyAlts API. 7 + /// True if the writes were successfully applied. 8 + @freezed 9 + class ApplyAltsResponse with _$ApplyAltsResponse { 10 + const factory ApplyAltsResponse({required bool success}) = _ApplyAltsResponse; 11 + 12 + factory ApplyAltsResponse.fromJson(Map<String, dynamic> json) => 13 + _$ApplyAltsResponseFromJson(json); 14 + }
+171
lib/models/procedures/apply_alts_response.freezed.dart
··· 1 + // coverage:ignore-file 2 + // GENERATED CODE - DO NOT MODIFY BY HAND 3 + // ignore_for_file: type=lint 4 + // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark 5 + 6 + part of 'apply_alts_response.dart'; 7 + 8 + // ************************************************************************** 9 + // FreezedGenerator 10 + // ************************************************************************** 11 + 12 + T _$identity<T>(T value) => value; 13 + 14 + final _privateConstructorUsedError = UnsupportedError( 15 + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', 16 + ); 17 + 18 + ApplyAltsResponse _$ApplyAltsResponseFromJson(Map<String, dynamic> json) { 19 + return _ApplyAltsResponse.fromJson(json); 20 + } 21 + 22 + /// @nodoc 23 + mixin _$ApplyAltsResponse { 24 + bool get success => throw _privateConstructorUsedError; 25 + 26 + /// Serializes this ApplyAltsResponse to a JSON map. 27 + Map<String, dynamic> toJson() => throw _privateConstructorUsedError; 28 + 29 + /// Create a copy of ApplyAltsResponse 30 + /// with the given fields replaced by the non-null parameter values. 31 + @JsonKey(includeFromJson: false, includeToJson: false) 32 + $ApplyAltsResponseCopyWith<ApplyAltsResponse> get copyWith => 33 + throw _privateConstructorUsedError; 34 + } 35 + 36 + /// @nodoc 37 + abstract class $ApplyAltsResponseCopyWith<$Res> { 38 + factory $ApplyAltsResponseCopyWith( 39 + ApplyAltsResponse value, 40 + $Res Function(ApplyAltsResponse) then, 41 + ) = _$ApplyAltsResponseCopyWithImpl<$Res, ApplyAltsResponse>; 42 + @useResult 43 + $Res call({bool success}); 44 + } 45 + 46 + /// @nodoc 47 + class _$ApplyAltsResponseCopyWithImpl<$Res, $Val extends ApplyAltsResponse> 48 + implements $ApplyAltsResponseCopyWith<$Res> { 49 + _$ApplyAltsResponseCopyWithImpl(this._value, this._then); 50 + 51 + // ignore: unused_field 52 + final $Val _value; 53 + // ignore: unused_field 54 + final $Res Function($Val) _then; 55 + 56 + /// Create a copy of ApplyAltsResponse 57 + /// with the given fields replaced by the non-null parameter values. 58 + @pragma('vm:prefer-inline') 59 + @override 60 + $Res call({Object? success = null}) { 61 + return _then( 62 + _value.copyWith( 63 + success: null == success 64 + ? _value.success 65 + : success // ignore: cast_nullable_to_non_nullable 66 + as bool, 67 + ) 68 + as $Val, 69 + ); 70 + } 71 + } 72 + 73 + /// @nodoc 74 + abstract class _$$ApplyAltsResponseImplCopyWith<$Res> 75 + implements $ApplyAltsResponseCopyWith<$Res> { 76 + factory _$$ApplyAltsResponseImplCopyWith( 77 + _$ApplyAltsResponseImpl value, 78 + $Res Function(_$ApplyAltsResponseImpl) then, 79 + ) = __$$ApplyAltsResponseImplCopyWithImpl<$Res>; 80 + @override 81 + @useResult 82 + $Res call({bool success}); 83 + } 84 + 85 + /// @nodoc 86 + class __$$ApplyAltsResponseImplCopyWithImpl<$Res> 87 + extends _$ApplyAltsResponseCopyWithImpl<$Res, _$ApplyAltsResponseImpl> 88 + implements _$$ApplyAltsResponseImplCopyWith<$Res> { 89 + __$$ApplyAltsResponseImplCopyWithImpl( 90 + _$ApplyAltsResponseImpl _value, 91 + $Res Function(_$ApplyAltsResponseImpl) _then, 92 + ) : super(_value, _then); 93 + 94 + /// Create a copy of ApplyAltsResponse 95 + /// with the given fields replaced by the non-null parameter values. 96 + @pragma('vm:prefer-inline') 97 + @override 98 + $Res call({Object? success = null}) { 99 + return _then( 100 + _$ApplyAltsResponseImpl( 101 + success: null == success 102 + ? _value.success 103 + : success // ignore: cast_nullable_to_non_nullable 104 + as bool, 105 + ), 106 + ); 107 + } 108 + } 109 + 110 + /// @nodoc 111 + @JsonSerializable() 112 + class _$ApplyAltsResponseImpl implements _ApplyAltsResponse { 113 + const _$ApplyAltsResponseImpl({required this.success}); 114 + 115 + factory _$ApplyAltsResponseImpl.fromJson(Map<String, dynamic> json) => 116 + _$$ApplyAltsResponseImplFromJson(json); 117 + 118 + @override 119 + final bool success; 120 + 121 + @override 122 + String toString() { 123 + return 'ApplyAltsResponse(success: $success)'; 124 + } 125 + 126 + @override 127 + bool operator ==(Object other) { 128 + return identical(this, other) || 129 + (other.runtimeType == runtimeType && 130 + other is _$ApplyAltsResponseImpl && 131 + (identical(other.success, success) || other.success == success)); 132 + } 133 + 134 + @JsonKey(includeFromJson: false, includeToJson: false) 135 + @override 136 + int get hashCode => Object.hash(runtimeType, success); 137 + 138 + /// Create a copy of ApplyAltsResponse 139 + /// with the given fields replaced by the non-null parameter values. 140 + @JsonKey(includeFromJson: false, includeToJson: false) 141 + @override 142 + @pragma('vm:prefer-inline') 143 + _$$ApplyAltsResponseImplCopyWith<_$ApplyAltsResponseImpl> get copyWith => 144 + __$$ApplyAltsResponseImplCopyWithImpl<_$ApplyAltsResponseImpl>( 145 + this, 146 + _$identity, 147 + ); 148 + 149 + @override 150 + Map<String, dynamic> toJson() { 151 + return _$$ApplyAltsResponseImplToJson(this); 152 + } 153 + } 154 + 155 + abstract class _ApplyAltsResponse implements ApplyAltsResponse { 156 + const factory _ApplyAltsResponse({required final bool success}) = 157 + _$ApplyAltsResponseImpl; 158 + 159 + factory _ApplyAltsResponse.fromJson(Map<String, dynamic> json) = 160 + _$ApplyAltsResponseImpl.fromJson; 161 + 162 + @override 163 + bool get success; 164 + 165 + /// Create a copy of ApplyAltsResponse 166 + /// with the given fields replaced by the non-null parameter values. 167 + @override 168 + @JsonKey(includeFromJson: false, includeToJson: false) 169 + _$$ApplyAltsResponseImplCopyWith<_$ApplyAltsResponseImpl> get copyWith => 170 + throw _privateConstructorUsedError; 171 + }
+15
lib/models/procedures/apply_alts_response.g.dart
··· 1 + // GENERATED CODE - DO NOT MODIFY BY HAND 2 + 3 + part of 'apply_alts_response.dart'; 4 + 5 + // ************************************************************************** 6 + // JsonSerializableGenerator 7 + // ************************************************************************** 8 + 9 + _$ApplyAltsResponseImpl _$$ApplyAltsResponseImplFromJson( 10 + Map<String, dynamic> json, 11 + ) => _$ApplyAltsResponseImpl(success: json['success'] as bool); 12 + 13 + Map<String, dynamic> _$$ApplyAltsResponseImplToJson( 14 + _$ApplyAltsResponseImpl instance, 15 + ) => <String, dynamic>{'success': instance.success};
+13
lib/models/procedures/apply_alts_update.dart
··· 1 + import 'package:freezed_annotation/freezed_annotation.dart'; 2 + 3 + part 'apply_alts_update.freezed.dart'; 4 + part 'apply_alts_update.g.dart'; 5 + 6 + /// Update alt text for a photo in a gallery. 7 + /// AT URI of the item to update and the alt text to apply. 8 + @freezed 9 + class ApplyAltsUpdate with _$ApplyAltsUpdate { 10 + const factory ApplyAltsUpdate({required String photoUri, required String alt}) = _ApplyAltsUpdate; 11 + 12 + factory ApplyAltsUpdate.fromJson(Map<String, dynamic> json) => _$ApplyAltsUpdateFromJson(json); 13 + }
+188
lib/models/procedures/apply_alts_update.freezed.dart
··· 1 + // coverage:ignore-file 2 + // GENERATED CODE - DO NOT MODIFY BY HAND 3 + // ignore_for_file: type=lint 4 + // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark 5 + 6 + part of 'apply_alts_update.dart'; 7 + 8 + // ************************************************************************** 9 + // FreezedGenerator 10 + // ************************************************************************** 11 + 12 + T _$identity<T>(T value) => value; 13 + 14 + final _privateConstructorUsedError = UnsupportedError( 15 + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', 16 + ); 17 + 18 + ApplyAltsUpdate _$ApplyAltsUpdateFromJson(Map<String, dynamic> json) { 19 + return _ApplyAltsUpdate.fromJson(json); 20 + } 21 + 22 + /// @nodoc 23 + mixin _$ApplyAltsUpdate { 24 + String get photoUri => throw _privateConstructorUsedError; 25 + String get alt => throw _privateConstructorUsedError; 26 + 27 + /// Serializes this ApplyAltsUpdate to a JSON map. 28 + Map<String, dynamic> toJson() => throw _privateConstructorUsedError; 29 + 30 + /// Create a copy of ApplyAltsUpdate 31 + /// with the given fields replaced by the non-null parameter values. 32 + @JsonKey(includeFromJson: false, includeToJson: false) 33 + $ApplyAltsUpdateCopyWith<ApplyAltsUpdate> get copyWith => 34 + throw _privateConstructorUsedError; 35 + } 36 + 37 + /// @nodoc 38 + abstract class $ApplyAltsUpdateCopyWith<$Res> { 39 + factory $ApplyAltsUpdateCopyWith( 40 + ApplyAltsUpdate value, 41 + $Res Function(ApplyAltsUpdate) then, 42 + ) = _$ApplyAltsUpdateCopyWithImpl<$Res, ApplyAltsUpdate>; 43 + @useResult 44 + $Res call({String photoUri, String alt}); 45 + } 46 + 47 + /// @nodoc 48 + class _$ApplyAltsUpdateCopyWithImpl<$Res, $Val extends ApplyAltsUpdate> 49 + implements $ApplyAltsUpdateCopyWith<$Res> { 50 + _$ApplyAltsUpdateCopyWithImpl(this._value, this._then); 51 + 52 + // ignore: unused_field 53 + final $Val _value; 54 + // ignore: unused_field 55 + final $Res Function($Val) _then; 56 + 57 + /// Create a copy of ApplyAltsUpdate 58 + /// with the given fields replaced by the non-null parameter values. 59 + @pragma('vm:prefer-inline') 60 + @override 61 + $Res call({Object? photoUri = null, Object? alt = null}) { 62 + return _then( 63 + _value.copyWith( 64 + photoUri: null == photoUri 65 + ? _value.photoUri 66 + : photoUri // ignore: cast_nullable_to_non_nullable 67 + as String, 68 + alt: null == alt 69 + ? _value.alt 70 + : alt // ignore: cast_nullable_to_non_nullable 71 + as String, 72 + ) 73 + as $Val, 74 + ); 75 + } 76 + } 77 + 78 + /// @nodoc 79 + abstract class _$$ApplyAltsUpdateImplCopyWith<$Res> 80 + implements $ApplyAltsUpdateCopyWith<$Res> { 81 + factory _$$ApplyAltsUpdateImplCopyWith( 82 + _$ApplyAltsUpdateImpl value, 83 + $Res Function(_$ApplyAltsUpdateImpl) then, 84 + ) = __$$ApplyAltsUpdateImplCopyWithImpl<$Res>; 85 + @override 86 + @useResult 87 + $Res call({String photoUri, String alt}); 88 + } 89 + 90 + /// @nodoc 91 + class __$$ApplyAltsUpdateImplCopyWithImpl<$Res> 92 + extends _$ApplyAltsUpdateCopyWithImpl<$Res, _$ApplyAltsUpdateImpl> 93 + implements _$$ApplyAltsUpdateImplCopyWith<$Res> { 94 + __$$ApplyAltsUpdateImplCopyWithImpl( 95 + _$ApplyAltsUpdateImpl _value, 96 + $Res Function(_$ApplyAltsUpdateImpl) _then, 97 + ) : super(_value, _then); 98 + 99 + /// Create a copy of ApplyAltsUpdate 100 + /// with the given fields replaced by the non-null parameter values. 101 + @pragma('vm:prefer-inline') 102 + @override 103 + $Res call({Object? photoUri = null, Object? alt = null}) { 104 + return _then( 105 + _$ApplyAltsUpdateImpl( 106 + photoUri: null == photoUri 107 + ? _value.photoUri 108 + : photoUri // ignore: cast_nullable_to_non_nullable 109 + as String, 110 + alt: null == alt 111 + ? _value.alt 112 + : alt // ignore: cast_nullable_to_non_nullable 113 + as String, 114 + ), 115 + ); 116 + } 117 + } 118 + 119 + /// @nodoc 120 + @JsonSerializable() 121 + class _$ApplyAltsUpdateImpl implements _ApplyAltsUpdate { 122 + const _$ApplyAltsUpdateImpl({required this.photoUri, required this.alt}); 123 + 124 + factory _$ApplyAltsUpdateImpl.fromJson(Map<String, dynamic> json) => 125 + _$$ApplyAltsUpdateImplFromJson(json); 126 + 127 + @override 128 + final String photoUri; 129 + @override 130 + final String alt; 131 + 132 + @override 133 + String toString() { 134 + return 'ApplyAltsUpdate(photoUri: $photoUri, alt: $alt)'; 135 + } 136 + 137 + @override 138 + bool operator ==(Object other) { 139 + return identical(this, other) || 140 + (other.runtimeType == runtimeType && 141 + other is _$ApplyAltsUpdateImpl && 142 + (identical(other.photoUri, photoUri) || 143 + other.photoUri == photoUri) && 144 + (identical(other.alt, alt) || other.alt == alt)); 145 + } 146 + 147 + @JsonKey(includeFromJson: false, includeToJson: false) 148 + @override 149 + int get hashCode => Object.hash(runtimeType, photoUri, alt); 150 + 151 + /// Create a copy of ApplyAltsUpdate 152 + /// with the given fields replaced by the non-null parameter values. 153 + @JsonKey(includeFromJson: false, includeToJson: false) 154 + @override 155 + @pragma('vm:prefer-inline') 156 + _$$ApplyAltsUpdateImplCopyWith<_$ApplyAltsUpdateImpl> get copyWith => 157 + __$$ApplyAltsUpdateImplCopyWithImpl<_$ApplyAltsUpdateImpl>( 158 + this, 159 + _$identity, 160 + ); 161 + 162 + @override 163 + Map<String, dynamic> toJson() { 164 + return _$$ApplyAltsUpdateImplToJson(this); 165 + } 166 + } 167 + 168 + abstract class _ApplyAltsUpdate implements ApplyAltsUpdate { 169 + const factory _ApplyAltsUpdate({ 170 + required final String photoUri, 171 + required final String alt, 172 + }) = _$ApplyAltsUpdateImpl; 173 + 174 + factory _ApplyAltsUpdate.fromJson(Map<String, dynamic> json) = 175 + _$ApplyAltsUpdateImpl.fromJson; 176 + 177 + @override 178 + String get photoUri; 179 + @override 180 + String get alt; 181 + 182 + /// Create a copy of ApplyAltsUpdate 183 + /// with the given fields replaced by the non-null parameter values. 184 + @override 185 + @JsonKey(includeFromJson: false, includeToJson: false) 186 + _$$ApplyAltsUpdateImplCopyWith<_$ApplyAltsUpdateImpl> get copyWith => 187 + throw _privateConstructorUsedError; 188 + }
+18
lib/models/procedures/apply_alts_update.g.dart
··· 1 + // GENERATED CODE - DO NOT MODIFY BY HAND 2 + 3 + part of 'apply_alts_update.dart'; 4 + 5 + // ************************************************************************** 6 + // JsonSerializableGenerator 7 + // ************************************************************************** 8 + 9 + _$ApplyAltsUpdateImpl _$$ApplyAltsUpdateImplFromJson( 10 + Map<String, dynamic> json, 11 + ) => _$ApplyAltsUpdateImpl( 12 + photoUri: json['photoUri'] as String, 13 + alt: json['alt'] as String, 14 + ); 15 + 16 + Map<String, dynamic> _$$ApplyAltsUpdateImplToJson( 17 + _$ApplyAltsUpdateImpl instance, 18 + ) => <String, dynamic>{'photoUri': instance.photoUri, 'alt': instance.alt};
+24
lib/models/procedures/apply_sort_request.dart
··· 1 + import 'package:json_annotation/json_annotation.dart'; 2 + 3 + part 'apply_sort_request.g.dart'; 4 + 5 + @JsonSerializable() 6 + class ApplySortRequest { 7 + final List<ApplySortUpdate> writes; 8 + 9 + ApplySortRequest({required this.writes}); 10 + 11 + factory ApplySortRequest.fromJson(Map<String, dynamic> json) => _$ApplySortRequestFromJson(json); 12 + Map<String, dynamic> toJson() => _$ApplySortRequestToJson(this); 13 + } 14 + 15 + @JsonSerializable() 16 + class ApplySortUpdate { 17 + final String itemUri; 18 + final int position; 19 + 20 + ApplySortUpdate({required this.itemUri, required this.position}); 21 + 22 + factory ApplySortUpdate.fromJson(Map<String, dynamic> json) => _$ApplySortUpdateFromJson(json); 23 + Map<String, dynamic> toJson() => _$ApplySortUpdateToJson(this); 24 + }
+29
lib/models/procedures/apply_sort_request.g.dart
··· 1 + // GENERATED CODE - DO NOT MODIFY BY HAND 2 + 3 + part of 'apply_sort_request.dart'; 4 + 5 + // ************************************************************************** 6 + // JsonSerializableGenerator 7 + // ************************************************************************** 8 + 9 + ApplySortRequest _$ApplySortRequestFromJson(Map<String, dynamic> json) => 10 + ApplySortRequest( 11 + writes: (json['writes'] as List<dynamic>) 12 + .map((e) => ApplySortUpdate.fromJson(e as Map<String, dynamic>)) 13 + .toList(), 14 + ); 15 + 16 + Map<String, dynamic> _$ApplySortRequestToJson(ApplySortRequest instance) => 17 + <String, dynamic>{'writes': instance.writes}; 18 + 19 + ApplySortUpdate _$ApplySortUpdateFromJson(Map<String, dynamic> json) => 20 + ApplySortUpdate( 21 + itemUri: json['itemUri'] as String, 22 + position: (json['position'] as num).toInt(), 23 + ); 24 + 25 + Map<String, dynamic> _$ApplySortUpdateToJson(ApplySortUpdate instance) => 26 + <String, dynamic>{ 27 + 'itemUri': instance.itemUri, 28 + 'position': instance.position, 29 + };
+14
lib/models/procedures/apply_sort_response.dart
··· 1 + import 'package:json_annotation/json_annotation.dart'; 2 + 3 + part 'apply_sort_response.g.dart'; 4 + 5 + @JsonSerializable() 6 + class ApplySortResponse { 7 + final bool success; 8 + 9 + ApplySortResponse({required this.success}); 10 + 11 + factory ApplySortResponse.fromJson(Map<String, dynamic> json) => 12 + _$ApplySortResponseFromJson(json); 13 + Map<String, dynamic> toJson() => _$ApplySortResponseToJson(this); 14 + }
+13
lib/models/procedures/apply_sort_response.g.dart
··· 1 + // GENERATED CODE - DO NOT MODIFY BY HAND 2 + 3 + part of 'apply_sort_response.dart'; 4 + 5 + // ************************************************************************** 6 + // JsonSerializableGenerator 7 + // ************************************************************************** 8 + 9 + ApplySortResponse _$ApplySortResponseFromJson(Map<String, dynamic> json) => 10 + ApplySortResponse(success: json['success'] as bool); 11 + 12 + Map<String, dynamic> _$ApplySortResponseToJson(ApplySortResponse instance) => 13 + <String, dynamic>{'success': instance.success};
+19
lib/models/procedures/create_comment_request.dart
··· 1 + import 'package:freezed_annotation/freezed_annotation.dart'; 2 + 3 + part 'create_comment_request.freezed.dart'; 4 + part 'create_comment_request.g.dart'; 5 + 6 + /// Request model for creating a comment. 7 + /// See lexicon: social.grain.comment.createComment 8 + @freezed 9 + class CreateCommentRequest with _$CreateCommentRequest { 10 + const factory CreateCommentRequest({ 11 + required String text, 12 + required String subject, 13 + String? focus, 14 + String? replyTo, 15 + }) = _CreateCommentRequest; 16 + 17 + factory CreateCommentRequest.fromJson(Map<String, dynamic> json) => 18 + _$CreateCommentRequestFromJson(json); 19 + }
+236
lib/models/procedures/create_comment_request.freezed.dart
··· 1 + // coverage:ignore-file 2 + // GENERATED CODE - DO NOT MODIFY BY HAND 3 + // ignore_for_file: type=lint 4 + // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark 5 + 6 + part of 'create_comment_request.dart'; 7 + 8 + // ************************************************************************** 9 + // FreezedGenerator 10 + // ************************************************************************** 11 + 12 + T _$identity<T>(T value) => value; 13 + 14 + final _privateConstructorUsedError = UnsupportedError( 15 + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', 16 + ); 17 + 18 + CreateCommentRequest _$CreateCommentRequestFromJson(Map<String, dynamic> json) { 19 + return _CreateCommentRequest.fromJson(json); 20 + } 21 + 22 + /// @nodoc 23 + mixin _$CreateCommentRequest { 24 + String get text => throw _privateConstructorUsedError; 25 + String get subject => throw _privateConstructorUsedError; 26 + String? get focus => throw _privateConstructorUsedError; 27 + String? get replyTo => throw _privateConstructorUsedError; 28 + 29 + /// Serializes this CreateCommentRequest to a JSON map. 30 + Map<String, dynamic> toJson() => throw _privateConstructorUsedError; 31 + 32 + /// Create a copy of CreateCommentRequest 33 + /// with the given fields replaced by the non-null parameter values. 34 + @JsonKey(includeFromJson: false, includeToJson: false) 35 + $CreateCommentRequestCopyWith<CreateCommentRequest> get copyWith => 36 + throw _privateConstructorUsedError; 37 + } 38 + 39 + /// @nodoc 40 + abstract class $CreateCommentRequestCopyWith<$Res> { 41 + factory $CreateCommentRequestCopyWith( 42 + CreateCommentRequest value, 43 + $Res Function(CreateCommentRequest) then, 44 + ) = _$CreateCommentRequestCopyWithImpl<$Res, CreateCommentRequest>; 45 + @useResult 46 + $Res call({String text, String subject, String? focus, String? replyTo}); 47 + } 48 + 49 + /// @nodoc 50 + class _$CreateCommentRequestCopyWithImpl< 51 + $Res, 52 + $Val extends CreateCommentRequest 53 + > 54 + implements $CreateCommentRequestCopyWith<$Res> { 55 + _$CreateCommentRequestCopyWithImpl(this._value, this._then); 56 + 57 + // ignore: unused_field 58 + final $Val _value; 59 + // ignore: unused_field 60 + final $Res Function($Val) _then; 61 + 62 + /// Create a copy of CreateCommentRequest 63 + /// with the given fields replaced by the non-null parameter values. 64 + @pragma('vm:prefer-inline') 65 + @override 66 + $Res call({ 67 + Object? text = null, 68 + Object? subject = null, 69 + Object? focus = freezed, 70 + Object? replyTo = freezed, 71 + }) { 72 + return _then( 73 + _value.copyWith( 74 + text: null == text 75 + ? _value.text 76 + : text // ignore: cast_nullable_to_non_nullable 77 + as String, 78 + subject: null == subject 79 + ? _value.subject 80 + : subject // ignore: cast_nullable_to_non_nullable 81 + as String, 82 + focus: freezed == focus 83 + ? _value.focus 84 + : focus // ignore: cast_nullable_to_non_nullable 85 + as String?, 86 + replyTo: freezed == replyTo 87 + ? _value.replyTo 88 + : replyTo // ignore: cast_nullable_to_non_nullable 89 + as String?, 90 + ) 91 + as $Val, 92 + ); 93 + } 94 + } 95 + 96 + /// @nodoc 97 + abstract class _$$CreateCommentRequestImplCopyWith<$Res> 98 + implements $CreateCommentRequestCopyWith<$Res> { 99 + factory _$$CreateCommentRequestImplCopyWith( 100 + _$CreateCommentRequestImpl value, 101 + $Res Function(_$CreateCommentRequestImpl) then, 102 + ) = __$$CreateCommentRequestImplCopyWithImpl<$Res>; 103 + @override 104 + @useResult 105 + $Res call({String text, String subject, String? focus, String? replyTo}); 106 + } 107 + 108 + /// @nodoc 109 + class __$$CreateCommentRequestImplCopyWithImpl<$Res> 110 + extends _$CreateCommentRequestCopyWithImpl<$Res, _$CreateCommentRequestImpl> 111 + implements _$$CreateCommentRequestImplCopyWith<$Res> { 112 + __$$CreateCommentRequestImplCopyWithImpl( 113 + _$CreateCommentRequestImpl _value, 114 + $Res Function(_$CreateCommentRequestImpl) _then, 115 + ) : super(_value, _then); 116 + 117 + /// Create a copy of CreateCommentRequest 118 + /// with the given fields replaced by the non-null parameter values. 119 + @pragma('vm:prefer-inline') 120 + @override 121 + $Res call({ 122 + Object? text = null, 123 + Object? subject = null, 124 + Object? focus = freezed, 125 + Object? replyTo = freezed, 126 + }) { 127 + return _then( 128 + _$CreateCommentRequestImpl( 129 + text: null == text 130 + ? _value.text 131 + : text // ignore: cast_nullable_to_non_nullable 132 + as String, 133 + subject: null == subject 134 + ? _value.subject 135 + : subject // ignore: cast_nullable_to_non_nullable 136 + as String, 137 + focus: freezed == focus 138 + ? _value.focus 139 + : focus // ignore: cast_nullable_to_non_nullable 140 + as String?, 141 + replyTo: freezed == replyTo 142 + ? _value.replyTo 143 + : replyTo // ignore: cast_nullable_to_non_nullable 144 + as String?, 145 + ), 146 + ); 147 + } 148 + } 149 + 150 + /// @nodoc 151 + @JsonSerializable() 152 + class _$CreateCommentRequestImpl implements _CreateCommentRequest { 153 + const _$CreateCommentRequestImpl({ 154 + required this.text, 155 + required this.subject, 156 + this.focus, 157 + this.replyTo, 158 + }); 159 + 160 + factory _$CreateCommentRequestImpl.fromJson(Map<String, dynamic> json) => 161 + _$$CreateCommentRequestImplFromJson(json); 162 + 163 + @override 164 + final String text; 165 + @override 166 + final String subject; 167 + @override 168 + final String? focus; 169 + @override 170 + final String? replyTo; 171 + 172 + @override 173 + String toString() { 174 + return 'CreateCommentRequest(text: $text, subject: $subject, focus: $focus, replyTo: $replyTo)'; 175 + } 176 + 177 + @override 178 + bool operator ==(Object other) { 179 + return identical(this, other) || 180 + (other.runtimeType == runtimeType && 181 + other is _$CreateCommentRequestImpl && 182 + (identical(other.text, text) || other.text == text) && 183 + (identical(other.subject, subject) || other.subject == subject) && 184 + (identical(other.focus, focus) || other.focus == focus) && 185 + (identical(other.replyTo, replyTo) || other.replyTo == replyTo)); 186 + } 187 + 188 + @JsonKey(includeFromJson: false, includeToJson: false) 189 + @override 190 + int get hashCode => Object.hash(runtimeType, text, subject, focus, replyTo); 191 + 192 + /// Create a copy of CreateCommentRequest 193 + /// with the given fields replaced by the non-null parameter values. 194 + @JsonKey(includeFromJson: false, includeToJson: false) 195 + @override 196 + @pragma('vm:prefer-inline') 197 + _$$CreateCommentRequestImplCopyWith<_$CreateCommentRequestImpl> 198 + get copyWith => 199 + __$$CreateCommentRequestImplCopyWithImpl<_$CreateCommentRequestImpl>( 200 + this, 201 + _$identity, 202 + ); 203 + 204 + @override 205 + Map<String, dynamic> toJson() { 206 + return _$$CreateCommentRequestImplToJson(this); 207 + } 208 + } 209 + 210 + abstract class _CreateCommentRequest implements CreateCommentRequest { 211 + const factory _CreateCommentRequest({ 212 + required final String text, 213 + required final String subject, 214 + final String? focus, 215 + final String? replyTo, 216 + }) = _$CreateCommentRequestImpl; 217 + 218 + factory _CreateCommentRequest.fromJson(Map<String, dynamic> json) = 219 + _$CreateCommentRequestImpl.fromJson; 220 + 221 + @override 222 + String get text; 223 + @override 224 + String get subject; 225 + @override 226 + String? get focus; 227 + @override 228 + String? get replyTo; 229 + 230 + /// Create a copy of CreateCommentRequest 231 + /// with the given fields replaced by the non-null parameter values. 232 + @override 233 + @JsonKey(includeFromJson: false, includeToJson: false) 234 + _$$CreateCommentRequestImplCopyWith<_$CreateCommentRequestImpl> 235 + get copyWith => throw _privateConstructorUsedError; 236 + }
+25
lib/models/procedures/create_comment_request.g.dart
··· 1 + // GENERATED CODE - DO NOT MODIFY BY HAND 2 + 3 + part of 'create_comment_request.dart'; 4 + 5 + // ************************************************************************** 6 + // JsonSerializableGenerator 7 + // ************************************************************************** 8 + 9 + _$CreateCommentRequestImpl _$$CreateCommentRequestImplFromJson( 10 + Map<String, dynamic> json, 11 + ) => _$CreateCommentRequestImpl( 12 + text: json['text'] as String, 13 + subject: json['subject'] as String, 14 + focus: json['focus'] as String?, 15 + replyTo: json['replyTo'] as String?, 16 + ); 17 + 18 + Map<String, dynamic> _$$CreateCommentRequestImplToJson( 19 + _$CreateCommentRequestImpl instance, 20 + ) => <String, dynamic>{ 21 + 'text': instance.text, 22 + 'subject': instance.subject, 23 + 'focus': instance.focus, 24 + 'replyTo': instance.replyTo, 25 + };
+14
lib/models/procedures/create_comment_response.dart
··· 1 + import 'package:freezed_annotation/freezed_annotation.dart'; 2 + 3 + part 'create_comment_response.freezed.dart'; 4 + part 'create_comment_response.g.dart'; 5 + 6 + /// Response model for creating a comment. 7 + /// See lexicon: social.grain.comment.createComment 8 + @freezed 9 + class CreateCommentResponse with _$CreateCommentResponse { 10 + const factory CreateCommentResponse({required String commentUri}) = _CreateCommentResponse; 11 + 12 + factory CreateCommentResponse.fromJson(Map<String, dynamic> json) => 13 + _$CreateCommentResponseFromJson(json); 14 + }
+179
lib/models/procedures/create_comment_response.freezed.dart
··· 1 + // coverage:ignore-file 2 + // GENERATED CODE - DO NOT MODIFY BY HAND 3 + // ignore_for_file: type=lint 4 + // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark 5 + 6 + part of 'create_comment_response.dart'; 7 + 8 + // ************************************************************************** 9 + // FreezedGenerator 10 + // ************************************************************************** 11 + 12 + T _$identity<T>(T value) => value; 13 + 14 + final _privateConstructorUsedError = UnsupportedError( 15 + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', 16 + ); 17 + 18 + CreateCommentResponse _$CreateCommentResponseFromJson( 19 + Map<String, dynamic> json, 20 + ) { 21 + return _CreateCommentResponse.fromJson(json); 22 + } 23 + 24 + /// @nodoc 25 + mixin _$CreateCommentResponse { 26 + String get commentUri => throw _privateConstructorUsedError; 27 + 28 + /// Serializes this CreateCommentResponse to a JSON map. 29 + Map<String, dynamic> toJson() => throw _privateConstructorUsedError; 30 + 31 + /// Create a copy of CreateCommentResponse 32 + /// with the given fields replaced by the non-null parameter values. 33 + @JsonKey(includeFromJson: false, includeToJson: false) 34 + $CreateCommentResponseCopyWith<CreateCommentResponse> get copyWith => 35 + throw _privateConstructorUsedError; 36 + } 37 + 38 + /// @nodoc 39 + abstract class $CreateCommentResponseCopyWith<$Res> { 40 + factory $CreateCommentResponseCopyWith( 41 + CreateCommentResponse value, 42 + $Res Function(CreateCommentResponse) then, 43 + ) = _$CreateCommentResponseCopyWithImpl<$Res, CreateCommentResponse>; 44 + @useResult 45 + $Res call({String commentUri}); 46 + } 47 + 48 + /// @nodoc 49 + class _$CreateCommentResponseCopyWithImpl< 50 + $Res, 51 + $Val extends CreateCommentResponse 52 + > 53 + implements $CreateCommentResponseCopyWith<$Res> { 54 + _$CreateCommentResponseCopyWithImpl(this._value, this._then); 55 + 56 + // ignore: unused_field 57 + final $Val _value; 58 + // ignore: unused_field 59 + final $Res Function($Val) _then; 60 + 61 + /// Create a copy of CreateCommentResponse 62 + /// with the given fields replaced by the non-null parameter values. 63 + @pragma('vm:prefer-inline') 64 + @override 65 + $Res call({Object? commentUri = null}) { 66 + return _then( 67 + _value.copyWith( 68 + commentUri: null == commentUri 69 + ? _value.commentUri 70 + : commentUri // ignore: cast_nullable_to_non_nullable 71 + as String, 72 + ) 73 + as $Val, 74 + ); 75 + } 76 + } 77 + 78 + /// @nodoc 79 + abstract class _$$CreateCommentResponseImplCopyWith<$Res> 80 + implements $CreateCommentResponseCopyWith<$Res> { 81 + factory _$$CreateCommentResponseImplCopyWith( 82 + _$CreateCommentResponseImpl value, 83 + $Res Function(_$CreateCommentResponseImpl) then, 84 + ) = __$$CreateCommentResponseImplCopyWithImpl<$Res>; 85 + @override 86 + @useResult 87 + $Res call({String commentUri}); 88 + } 89 + 90 + /// @nodoc 91 + class __$$CreateCommentResponseImplCopyWithImpl<$Res> 92 + extends 93 + _$CreateCommentResponseCopyWithImpl<$Res, _$CreateCommentResponseImpl> 94 + implements _$$CreateCommentResponseImplCopyWith<$Res> { 95 + __$$CreateCommentResponseImplCopyWithImpl( 96 + _$CreateCommentResponseImpl _value, 97 + $Res Function(_$CreateCommentResponseImpl) _then, 98 + ) : super(_value, _then); 99 + 100 + /// Create a copy of CreateCommentResponse 101 + /// with the given fields replaced by the non-null parameter values. 102 + @pragma('vm:prefer-inline') 103 + @override 104 + $Res call({Object? commentUri = null}) { 105 + return _then( 106 + _$CreateCommentResponseImpl( 107 + commentUri: null == commentUri 108 + ? _value.commentUri 109 + : commentUri // ignore: cast_nullable_to_non_nullable 110 + as String, 111 + ), 112 + ); 113 + } 114 + } 115 + 116 + /// @nodoc 117 + @JsonSerializable() 118 + class _$CreateCommentResponseImpl implements _CreateCommentResponse { 119 + const _$CreateCommentResponseImpl({required this.commentUri}); 120 + 121 + factory _$CreateCommentResponseImpl.fromJson(Map<String, dynamic> json) => 122 + _$$CreateCommentResponseImplFromJson(json); 123 + 124 + @override 125 + final String commentUri; 126 + 127 + @override 128 + String toString() { 129 + return 'CreateCommentResponse(commentUri: $commentUri)'; 130 + } 131 + 132 + @override 133 + bool operator ==(Object other) { 134 + return identical(this, other) || 135 + (other.runtimeType == runtimeType && 136 + other is _$CreateCommentResponseImpl && 137 + (identical(other.commentUri, commentUri) || 138 + other.commentUri == commentUri)); 139 + } 140 + 141 + @JsonKey(includeFromJson: false, includeToJson: false) 142 + @override 143 + int get hashCode => Object.hash(runtimeType, commentUri); 144 + 145 + /// Create a copy of CreateCommentResponse 146 + /// with the given fields replaced by the non-null parameter values. 147 + @JsonKey(includeFromJson: false, includeToJson: false) 148 + @override 149 + @pragma('vm:prefer-inline') 150 + _$$CreateCommentResponseImplCopyWith<_$CreateCommentResponseImpl> 151 + get copyWith => 152 + __$$CreateCommentResponseImplCopyWithImpl<_$CreateCommentResponseImpl>( 153 + this, 154 + _$identity, 155 + ); 156 + 157 + @override 158 + Map<String, dynamic> toJson() { 159 + return _$$CreateCommentResponseImplToJson(this); 160 + } 161 + } 162 + 163 + abstract class _CreateCommentResponse implements CreateCommentResponse { 164 + const factory _CreateCommentResponse({required final String commentUri}) = 165 + _$CreateCommentResponseImpl; 166 + 167 + factory _CreateCommentResponse.fromJson(Map<String, dynamic> json) = 168 + _$CreateCommentResponseImpl.fromJson; 169 + 170 + @override 171 + String get commentUri; 172 + 173 + /// Create a copy of CreateCommentResponse 174 + /// with the given fields replaced by the non-null parameter values. 175 + @override 176 + @JsonKey(includeFromJson: false, includeToJson: false) 177 + _$$CreateCommentResponseImplCopyWith<_$CreateCommentResponseImpl> 178 + get copyWith => throw _privateConstructorUsedError; 179 + }
+15
lib/models/procedures/create_comment_response.g.dart
··· 1 + // GENERATED CODE - DO NOT MODIFY BY HAND 2 + 3 + part of 'create_comment_response.dart'; 4 + 5 + // ************************************************************************** 6 + // JsonSerializableGenerator 7 + // ************************************************************************** 8 + 9 + _$CreateCommentResponseImpl _$$CreateCommentResponseImplFromJson( 10 + Map<String, dynamic> json, 11 + ) => _$CreateCommentResponseImpl(commentUri: json['commentUri'] as String); 12 + 13 + Map<String, dynamic> _$$CreateCommentResponseImplToJson( 14 + _$CreateCommentResponseImpl instance, 15 + ) => <String, dynamic>{'commentUri': instance.commentUri};
+25
lib/models/procedures/create_exif_request.dart
··· 1 + import 'package:freezed_annotation/freezed_annotation.dart'; 2 + 3 + part 'create_exif_request.freezed.dart'; 4 + part 'create_exif_request.g.dart'; 5 + 6 + /// Request model for creating a new Exif record for a photo. 7 + @freezed 8 + class CreateExifRequest with _$CreateExifRequest { 9 + const factory CreateExifRequest({ 10 + required String photo, 11 + String? dateTimeOriginal, 12 + int? exposureTime, 13 + int? fNumber, 14 + String? flash, 15 + int? focalLengthIn35mmFormat, 16 + int? iSO, 17 + String? lensMake, 18 + String? lensModel, 19 + String? make, 20 + String? model, 21 + }) = _CreateExifRequest; 22 + 23 + factory CreateExifRequest.fromJson(Map<String, dynamic> json) => 24 + _$CreateExifRequestFromJson(json); 25 + }
+403
lib/models/procedures/create_exif_request.freezed.dart
··· 1 + // coverage:ignore-file 2 + // GENERATED CODE - DO NOT MODIFY BY HAND 3 + // ignore_for_file: type=lint 4 + // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark 5 + 6 + part of 'create_exif_request.dart'; 7 + 8 + // ************************************************************************** 9 + // FreezedGenerator 10 + // ************************************************************************** 11 + 12 + T _$identity<T>(T value) => value; 13 + 14 + final _privateConstructorUsedError = UnsupportedError( 15 + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', 16 + ); 17 + 18 + CreateExifRequest _$CreateExifRequestFromJson(Map<String, dynamic> json) { 19 + return _CreateExifRequest.fromJson(json); 20 + } 21 + 22 + /// @nodoc 23 + mixin _$CreateExifRequest { 24 + String get photo => throw _privateConstructorUsedError; 25 + String? get dateTimeOriginal => throw _privateConstructorUsedError; 26 + int? get exposureTime => throw _privateConstructorUsedError; 27 + int? get fNumber => throw _privateConstructorUsedError; 28 + String? get flash => throw _privateConstructorUsedError; 29 + int? get focalLengthIn35mmFormat => throw _privateConstructorUsedError; 30 + int? get iSO => throw _privateConstructorUsedError; 31 + String? get lensMake => throw _privateConstructorUsedError; 32 + String? get lensModel => throw _privateConstructorUsedError; 33 + String? get make => throw _privateConstructorUsedError; 34 + String? get model => throw _privateConstructorUsedError; 35 + 36 + /// Serializes this CreateExifRequest to a JSON map. 37 + Map<String, dynamic> toJson() => throw _privateConstructorUsedError; 38 + 39 + /// Create a copy of CreateExifRequest 40 + /// with the given fields replaced by the non-null parameter values. 41 + @JsonKey(includeFromJson: false, includeToJson: false) 42 + $CreateExifRequestCopyWith<CreateExifRequest> get copyWith => 43 + throw _privateConstructorUsedError; 44 + } 45 + 46 + /// @nodoc 47 + abstract class $CreateExifRequestCopyWith<$Res> { 48 + factory $CreateExifRequestCopyWith( 49 + CreateExifRequest value, 50 + $Res Function(CreateExifRequest) then, 51 + ) = _$CreateExifRequestCopyWithImpl<$Res, CreateExifRequest>; 52 + @useResult 53 + $Res call({ 54 + String photo, 55 + String? dateTimeOriginal, 56 + int? exposureTime, 57 + int? fNumber, 58 + String? flash, 59 + int? focalLengthIn35mmFormat, 60 + int? iSO, 61 + String? lensMake, 62 + String? lensModel, 63 + String? make, 64 + String? model, 65 + }); 66 + } 67 + 68 + /// @nodoc 69 + class _$CreateExifRequestCopyWithImpl<$Res, $Val extends CreateExifRequest> 70 + implements $CreateExifRequestCopyWith<$Res> { 71 + _$CreateExifRequestCopyWithImpl(this._value, this._then); 72 + 73 + // ignore: unused_field 74 + final $Val _value; 75 + // ignore: unused_field 76 + final $Res Function($Val) _then; 77 + 78 + /// Create a copy of CreateExifRequest 79 + /// with the given fields replaced by the non-null parameter values. 80 + @pragma('vm:prefer-inline') 81 + @override 82 + $Res call({ 83 + Object? photo = null, 84 + Object? dateTimeOriginal = freezed, 85 + Object? exposureTime = freezed, 86 + Object? fNumber = freezed, 87 + Object? flash = freezed, 88 + Object? focalLengthIn35mmFormat = freezed, 89 + Object? iSO = freezed, 90 + Object? lensMake = freezed, 91 + Object? lensModel = freezed, 92 + Object? make = freezed, 93 + Object? model = freezed, 94 + }) { 95 + return _then( 96 + _value.copyWith( 97 + photo: null == photo 98 + ? _value.photo 99 + : photo // ignore: cast_nullable_to_non_nullable 100 + as String, 101 + dateTimeOriginal: freezed == dateTimeOriginal 102 + ? _value.dateTimeOriginal 103 + : dateTimeOriginal // ignore: cast_nullable_to_non_nullable 104 + as String?, 105 + exposureTime: freezed == exposureTime 106 + ? _value.exposureTime 107 + : exposureTime // ignore: cast_nullable_to_non_nullable 108 + as int?, 109 + fNumber: freezed == fNumber 110 + ? _value.fNumber 111 + : fNumber // ignore: cast_nullable_to_non_nullable 112 + as int?, 113 + flash: freezed == flash 114 + ? _value.flash 115 + : flash // ignore: cast_nullable_to_non_nullable 116 + as String?, 117 + focalLengthIn35mmFormat: freezed == focalLengthIn35mmFormat 118 + ? _value.focalLengthIn35mmFormat 119 + : focalLengthIn35mmFormat // ignore: cast_nullable_to_non_nullable 120 + as int?, 121 + iSO: freezed == iSO 122 + ? _value.iSO 123 + : iSO // ignore: cast_nullable_to_non_nullable 124 + as int?, 125 + lensMake: freezed == lensMake 126 + ? _value.lensMake 127 + : lensMake // ignore: cast_nullable_to_non_nullable 128 + as String?, 129 + lensModel: freezed == lensModel 130 + ? _value.lensModel 131 + : lensModel // ignore: cast_nullable_to_non_nullable 132 + as String?, 133 + make: freezed == make 134 + ? _value.make 135 + : make // ignore: cast_nullable_to_non_nullable 136 + as String?, 137 + model: freezed == model 138 + ? _value.model 139 + : model // ignore: cast_nullable_to_non_nullable 140 + as String?, 141 + ) 142 + as $Val, 143 + ); 144 + } 145 + } 146 + 147 + /// @nodoc 148 + abstract class _$$CreateExifRequestImplCopyWith<$Res> 149 + implements $CreateExifRequestCopyWith<$Res> { 150 + factory _$$CreateExifRequestImplCopyWith( 151 + _$CreateExifRequestImpl value, 152 + $Res Function(_$CreateExifRequestImpl) then, 153 + ) = __$$CreateExifRequestImplCopyWithImpl<$Res>; 154 + @override 155 + @useResult 156 + $Res call({ 157 + String photo, 158 + String? dateTimeOriginal, 159 + int? exposureTime, 160 + int? fNumber, 161 + String? flash, 162 + int? focalLengthIn35mmFormat, 163 + int? iSO, 164 + String? lensMake, 165 + String? lensModel, 166 + String? make, 167 + String? model, 168 + }); 169 + } 170 + 171 + /// @nodoc 172 + class __$$CreateExifRequestImplCopyWithImpl<$Res> 173 + extends _$CreateExifRequestCopyWithImpl<$Res, _$CreateExifRequestImpl> 174 + implements _$$CreateExifRequestImplCopyWith<$Res> { 175 + __$$CreateExifRequestImplCopyWithImpl( 176 + _$CreateExifRequestImpl _value, 177 + $Res Function(_$CreateExifRequestImpl) _then, 178 + ) : super(_value, _then); 179 + 180 + /// Create a copy of CreateExifRequest 181 + /// with the given fields replaced by the non-null parameter values. 182 + @pragma('vm:prefer-inline') 183 + @override 184 + $Res call({ 185 + Object? photo = null, 186 + Object? dateTimeOriginal = freezed, 187 + Object? exposureTime = freezed, 188 + Object? fNumber = freezed, 189 + Object? flash = freezed, 190 + Object? focalLengthIn35mmFormat = freezed, 191 + Object? iSO = freezed, 192 + Object? lensMake = freezed, 193 + Object? lensModel = freezed, 194 + Object? make = freezed, 195 + Object? model = freezed, 196 + }) { 197 + return _then( 198 + _$CreateExifRequestImpl( 199 + photo: null == photo 200 + ? _value.photo 201 + : photo // ignore: cast_nullable_to_non_nullable 202 + as String, 203 + dateTimeOriginal: freezed == dateTimeOriginal 204 + ? _value.dateTimeOriginal 205 + : dateTimeOriginal // ignore: cast_nullable_to_non_nullable 206 + as String?, 207 + exposureTime: freezed == exposureTime 208 + ? _value.exposureTime 209 + : exposureTime // ignore: cast_nullable_to_non_nullable 210 + as int?, 211 + fNumber: freezed == fNumber 212 + ? _value.fNumber 213 + : fNumber // ignore: cast_nullable_to_non_nullable 214 + as int?, 215 + flash: freezed == flash 216 + ? _value.flash 217 + : flash // ignore: cast_nullable_to_non_nullable 218 + as String?, 219 + focalLengthIn35mmFormat: freezed == focalLengthIn35mmFormat 220 + ? _value.focalLengthIn35mmFormat 221 + : focalLengthIn35mmFormat // ignore: cast_nullable_to_non_nullable 222 + as int?, 223 + iSO: freezed == iSO 224 + ? _value.iSO 225 + : iSO // ignore: cast_nullable_to_non_nullable 226 + as int?, 227 + lensMake: freezed == lensMake 228 + ? _value.lensMake 229 + : lensMake // ignore: cast_nullable_to_non_nullable 230 + as String?, 231 + lensModel: freezed == lensModel 232 + ? _value.lensModel 233 + : lensModel // ignore: cast_nullable_to_non_nullable 234 + as String?, 235 + make: freezed == make 236 + ? _value.make 237 + : make // ignore: cast_nullable_to_non_nullable 238 + as String?, 239 + model: freezed == model 240 + ? _value.model 241 + : model // ignore: cast_nullable_to_non_nullable 242 + as String?, 243 + ), 244 + ); 245 + } 246 + } 247 + 248 + /// @nodoc 249 + @JsonSerializable() 250 + class _$CreateExifRequestImpl implements _CreateExifRequest { 251 + const _$CreateExifRequestImpl({ 252 + required this.photo, 253 + this.dateTimeOriginal, 254 + this.exposureTime, 255 + this.fNumber, 256 + this.flash, 257 + this.focalLengthIn35mmFormat, 258 + this.iSO, 259 + this.lensMake, 260 + this.lensModel, 261 + this.make, 262 + this.model, 263 + }); 264 + 265 + factory _$CreateExifRequestImpl.fromJson(Map<String, dynamic> json) => 266 + _$$CreateExifRequestImplFromJson(json); 267 + 268 + @override 269 + final String photo; 270 + @override 271 + final String? dateTimeOriginal; 272 + @override 273 + final int? exposureTime; 274 + @override 275 + final int? fNumber; 276 + @override 277 + final String? flash; 278 + @override 279 + final int? focalLengthIn35mmFormat; 280 + @override 281 + final int? iSO; 282 + @override 283 + final String? lensMake; 284 + @override 285 + final String? lensModel; 286 + @override 287 + final String? make; 288 + @override 289 + final String? model; 290 + 291 + @override 292 + String toString() { 293 + return 'CreateExifRequest(photo: $photo, dateTimeOriginal: $dateTimeOriginal, exposureTime: $exposureTime, fNumber: $fNumber, flash: $flash, focalLengthIn35mmFormat: $focalLengthIn35mmFormat, iSO: $iSO, lensMake: $lensMake, lensModel: $lensModel, make: $make, model: $model)'; 294 + } 295 + 296 + @override 297 + bool operator ==(Object other) { 298 + return identical(this, other) || 299 + (other.runtimeType == runtimeType && 300 + other is _$CreateExifRequestImpl && 301 + (identical(other.photo, photo) || other.photo == photo) && 302 + (identical(other.dateTimeOriginal, dateTimeOriginal) || 303 + other.dateTimeOriginal == dateTimeOriginal) && 304 + (identical(other.exposureTime, exposureTime) || 305 + other.exposureTime == exposureTime) && 306 + (identical(other.fNumber, fNumber) || other.fNumber == fNumber) && 307 + (identical(other.flash, flash) || other.flash == flash) && 308 + (identical( 309 + other.focalLengthIn35mmFormat, 310 + focalLengthIn35mmFormat, 311 + ) || 312 + other.focalLengthIn35mmFormat == focalLengthIn35mmFormat) && 313 + (identical(other.iSO, iSO) || other.iSO == iSO) && 314 + (identical(other.lensMake, lensMake) || 315 + other.lensMake == lensMake) && 316 + (identical(other.lensModel, lensModel) || 317 + other.lensModel == lensModel) && 318 + (identical(other.make, make) || other.make == make) && 319 + (identical(other.model, model) || other.model == model)); 320 + } 321 + 322 + @JsonKey(includeFromJson: false, includeToJson: false) 323 + @override 324 + int get hashCode => Object.hash( 325 + runtimeType, 326 + photo, 327 + dateTimeOriginal, 328 + exposureTime, 329 + fNumber, 330 + flash, 331 + focalLengthIn35mmFormat, 332 + iSO, 333 + lensMake, 334 + lensModel, 335 + make, 336 + model, 337 + ); 338 + 339 + /// Create a copy of CreateExifRequest 340 + /// with the given fields replaced by the non-null parameter values. 341 + @JsonKey(includeFromJson: false, includeToJson: false) 342 + @override 343 + @pragma('vm:prefer-inline') 344 + _$$CreateExifRequestImplCopyWith<_$CreateExifRequestImpl> get copyWith => 345 + __$$CreateExifRequestImplCopyWithImpl<_$CreateExifRequestImpl>( 346 + this, 347 + _$identity, 348 + ); 349 + 350 + @override 351 + Map<String, dynamic> toJson() { 352 + return _$$CreateExifRequestImplToJson(this); 353 + } 354 + } 355 + 356 + abstract class _CreateExifRequest implements CreateExifRequest { 357 + const factory _CreateExifRequest({ 358 + required final String photo, 359 + final String? dateTimeOriginal, 360 + final int? exposureTime, 361 + final int? fNumber, 362 + final String? flash, 363 + final int? focalLengthIn35mmFormat, 364 + final int? iSO, 365 + final String? lensMake, 366 + final String? lensModel, 367 + final String? make, 368 + final String? model, 369 + }) = _$CreateExifRequestImpl; 370 + 371 + factory _CreateExifRequest.fromJson(Map<String, dynamic> json) = 372 + _$CreateExifRequestImpl.fromJson; 373 + 374 + @override 375 + String get photo; 376 + @override 377 + String? get dateTimeOriginal; 378 + @override 379 + int? get exposureTime; 380 + @override 381 + int? get fNumber; 382 + @override 383 + String? get flash; 384 + @override 385 + int? get focalLengthIn35mmFormat; 386 + @override 387 + int? get iSO; 388 + @override 389 + String? get lensMake; 390 + @override 391 + String? get lensModel; 392 + @override 393 + String? get make; 394 + @override 395 + String? get model; 396 + 397 + /// Create a copy of CreateExifRequest 398 + /// with the given fields replaced by the non-null parameter values. 399 + @override 400 + @JsonKey(includeFromJson: false, includeToJson: false) 401 + _$$CreateExifRequestImplCopyWith<_$CreateExifRequestImpl> get copyWith => 402 + throw _privateConstructorUsedError; 403 + }
+39
lib/models/procedures/create_exif_request.g.dart
··· 1 + // GENERATED CODE - DO NOT MODIFY BY HAND 2 + 3 + part of 'create_exif_request.dart'; 4 + 5 + // ************************************************************************** 6 + // JsonSerializableGenerator 7 + // ************************************************************************** 8 + 9 + _$CreateExifRequestImpl _$$CreateExifRequestImplFromJson( 10 + Map<String, dynamic> json, 11 + ) => _$CreateExifRequestImpl( 12 + photo: json['photo'] as String, 13 + dateTimeOriginal: json['dateTimeOriginal'] as String?, 14 + exposureTime: (json['exposureTime'] as num?)?.toInt(), 15 + fNumber: (json['fNumber'] as num?)?.toInt(), 16 + flash: json['flash'] as String?, 17 + focalLengthIn35mmFormat: (json['focalLengthIn35mmFormat'] as num?)?.toInt(), 18 + iSO: (json['iSO'] as num?)?.toInt(), 19 + lensMake: json['lensMake'] as String?, 20 + lensModel: json['lensModel'] as String?, 21 + make: json['make'] as String?, 22 + model: json['model'] as String?, 23 + ); 24 + 25 + Map<String, dynamic> _$$CreateExifRequestImplToJson( 26 + _$CreateExifRequestImpl instance, 27 + ) => <String, dynamic>{ 28 + 'photo': instance.photo, 29 + 'dateTimeOriginal': instance.dateTimeOriginal, 30 + 'exposureTime': instance.exposureTime, 31 + 'fNumber': instance.fNumber, 32 + 'flash': instance.flash, 33 + 'focalLengthIn35mmFormat': instance.focalLengthIn35mmFormat, 34 + 'iSO': instance.iSO, 35 + 'lensMake': instance.lensMake, 36 + 'lensModel': instance.lensModel, 37 + 'make': instance.make, 38 + 'model': instance.model, 39 + };
+15
lib/models/procedures/create_exif_response.dart
··· 1 + import 'package:freezed_annotation/freezed_annotation.dart'; 2 + 3 + part 'create_exif_response.freezed.dart'; 4 + part 'create_exif_response.g.dart'; 5 + 6 + /// Response model for creating a new Exif record for a photo. 7 + /// 8 + /// [exifUri] - The URI of the created Exif record. 9 + @freezed 10 + class CreateExifResponse with _$CreateExifResponse { 11 + const factory CreateExifResponse({required String exifUri}) = _CreateExifResponse; 12 + 13 + factory CreateExifResponse.fromJson(Map<String, dynamic> json) => 14 + _$CreateExifResponseFromJson(json); 15 + }
+171
lib/models/procedures/create_exif_response.freezed.dart
··· 1 + // coverage:ignore-file 2 + // GENERATED CODE - DO NOT MODIFY BY HAND 3 + // ignore_for_file: type=lint 4 + // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark 5 + 6 + part of 'create_exif_response.dart'; 7 + 8 + // ************************************************************************** 9 + // FreezedGenerator 10 + // ************************************************************************** 11 + 12 + T _$identity<T>(T value) => value; 13 + 14 + final _privateConstructorUsedError = UnsupportedError( 15 + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', 16 + ); 17 + 18 + CreateExifResponse _$CreateExifResponseFromJson(Map<String, dynamic> json) { 19 + return _CreateExifResponse.fromJson(json); 20 + } 21 + 22 + /// @nodoc 23 + mixin _$CreateExifResponse { 24 + String get exifUri => throw _privateConstructorUsedError; 25 + 26 + /// Serializes this CreateExifResponse to a JSON map. 27 + Map<String, dynamic> toJson() => throw _privateConstructorUsedError; 28 + 29 + /// Create a copy of CreateExifResponse 30 + /// with the given fields replaced by the non-null parameter values. 31 + @JsonKey(includeFromJson: false, includeToJson: false) 32 + $CreateExifResponseCopyWith<CreateExifResponse> get copyWith => 33 + throw _privateConstructorUsedError; 34 + } 35 + 36 + /// @nodoc 37 + abstract class $CreateExifResponseCopyWith<$Res> { 38 + factory $CreateExifResponseCopyWith( 39 + CreateExifResponse value, 40 + $Res Function(CreateExifResponse) then, 41 + ) = _$CreateExifResponseCopyWithImpl<$Res, CreateExifResponse>; 42 + @useResult 43 + $Res call({String exifUri}); 44 + } 45 + 46 + /// @nodoc 47 + class _$CreateExifResponseCopyWithImpl<$Res, $Val extends CreateExifResponse> 48 + implements $CreateExifResponseCopyWith<$Res> { 49 + _$CreateExifResponseCopyWithImpl(this._value, this._then); 50 + 51 + // ignore: unused_field 52 + final $Val _value; 53 + // ignore: unused_field 54 + final $Res Function($Val) _then; 55 + 56 + /// Create a copy of CreateExifResponse 57 + /// with the given fields replaced by the non-null parameter values. 58 + @pragma('vm:prefer-inline') 59 + @override 60 + $Res call({Object? exifUri = null}) { 61 + return _then( 62 + _value.copyWith( 63 + exifUri: null == exifUri 64 + ? _value.exifUri 65 + : exifUri // ignore: cast_nullable_to_non_nullable 66 + as String, 67 + ) 68 + as $Val, 69 + ); 70 + } 71 + } 72 + 73 + /// @nodoc 74 + abstract class _$$CreateExifResponseImplCopyWith<$Res> 75 + implements $CreateExifResponseCopyWith<$Res> { 76 + factory _$$CreateExifResponseImplCopyWith( 77 + _$CreateExifResponseImpl value, 78 + $Res Function(_$CreateExifResponseImpl) then, 79 + ) = __$$CreateExifResponseImplCopyWithImpl<$Res>; 80 + @override 81 + @useResult 82 + $Res call({String exifUri}); 83 + } 84 + 85 + /// @nodoc 86 + class __$$CreateExifResponseImplCopyWithImpl<$Res> 87 + extends _$CreateExifResponseCopyWithImpl<$Res, _$CreateExifResponseImpl> 88 + implements _$$CreateExifResponseImplCopyWith<$Res> { 89 + __$$CreateExifResponseImplCopyWithImpl( 90 + _$CreateExifResponseImpl _value, 91 + $Res Function(_$CreateExifResponseImpl) _then, 92 + ) : super(_value, _then); 93 + 94 + /// Create a copy of CreateExifResponse 95 + /// with the given fields replaced by the non-null parameter values. 96 + @pragma('vm:prefer-inline') 97 + @override 98 + $Res call({Object? exifUri = null}) { 99 + return _then( 100 + _$CreateExifResponseImpl( 101 + exifUri: null == exifUri 102 + ? _value.exifUri 103 + : exifUri // ignore: cast_nullable_to_non_nullable 104 + as String, 105 + ), 106 + ); 107 + } 108 + } 109 + 110 + /// @nodoc 111 + @JsonSerializable() 112 + class _$CreateExifResponseImpl implements _CreateExifResponse { 113 + const _$CreateExifResponseImpl({required this.exifUri}); 114 + 115 + factory _$CreateExifResponseImpl.fromJson(Map<String, dynamic> json) => 116 + _$$CreateExifResponseImplFromJson(json); 117 + 118 + @override 119 + final String exifUri; 120 + 121 + @override 122 + String toString() { 123 + return 'CreateExifResponse(exifUri: $exifUri)'; 124 + } 125 + 126 + @override 127 + bool operator ==(Object other) { 128 + return identical(this, other) || 129 + (other.runtimeType == runtimeType && 130 + other is _$CreateExifResponseImpl && 131 + (identical(other.exifUri, exifUri) || other.exifUri == exifUri)); 132 + } 133 + 134 + @JsonKey(includeFromJson: false, includeToJson: false) 135 + @override 136 + int get hashCode => Object.hash(runtimeType, exifUri); 137 + 138 + /// Create a copy of CreateExifResponse 139 + /// with the given fields replaced by the non-null parameter values. 140 + @JsonKey(includeFromJson: false, includeToJson: false) 141 + @override 142 + @pragma('vm:prefer-inline') 143 + _$$CreateExifResponseImplCopyWith<_$CreateExifResponseImpl> get copyWith => 144 + __$$CreateExifResponseImplCopyWithImpl<_$CreateExifResponseImpl>( 145 + this, 146 + _$identity, 147 + ); 148 + 149 + @override 150 + Map<String, dynamic> toJson() { 151 + return _$$CreateExifResponseImplToJson(this); 152 + } 153 + } 154 + 155 + abstract class _CreateExifResponse implements CreateExifResponse { 156 + const factory _CreateExifResponse({required final String exifUri}) = 157 + _$CreateExifResponseImpl; 158 + 159 + factory _CreateExifResponse.fromJson(Map<String, dynamic> json) = 160 + _$CreateExifResponseImpl.fromJson; 161 + 162 + @override 163 + String get exifUri; 164 + 165 + /// Create a copy of CreateExifResponse 166 + /// with the given fields replaced by the non-null parameter values. 167 + @override 168 + @JsonKey(includeFromJson: false, includeToJson: false) 169 + _$$CreateExifResponseImplCopyWith<_$CreateExifResponseImpl> get copyWith => 170 + throw _privateConstructorUsedError; 171 + }
+15
lib/models/procedures/create_exif_response.g.dart
··· 1 + // GENERATED CODE - DO NOT MODIFY BY HAND 2 + 3 + part of 'create_exif_response.dart'; 4 + 5 + // ************************************************************************** 6 + // JsonSerializableGenerator 7 + // ************************************************************************** 8 + 9 + _$CreateExifResponseImpl _$$CreateExifResponseImplFromJson( 10 + Map<String, dynamic> json, 11 + ) => _$CreateExifResponseImpl(exifUri: json['exifUri'] as String); 12 + 13 + Map<String, dynamic> _$$CreateExifResponseImplToJson( 14 + _$CreateExifResponseImpl instance, 15 + ) => <String, dynamic>{'exifUri': instance.exifUri};
+14
lib/models/procedures/create_favorite_request.dart
··· 1 + import 'package:freezed_annotation/freezed_annotation.dart'; 2 + 3 + part 'create_favorite_request.freezed.dart'; 4 + part 'create_favorite_request.g.dart'; 5 + 6 + /// Request model for creating a favorite. 7 + /// See lexicon: social.grain.favorite.createFavorite 8 + @freezed 9 + class CreateFavoriteRequest with _$CreateFavoriteRequest { 10 + const factory CreateFavoriteRequest({required String subject}) = _CreateFavoriteRequest; 11 + 12 + factory CreateFavoriteRequest.fromJson(Map<String, dynamic> json) => 13 + _$CreateFavoriteRequestFromJson(json); 14 + }
+178
lib/models/procedures/create_favorite_request.freezed.dart
··· 1 + // coverage:ignore-file 2 + // GENERATED CODE - DO NOT MODIFY BY HAND 3 + // ignore_for_file: type=lint 4 + // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark 5 + 6 + part of 'create_favorite_request.dart'; 7 + 8 + // ************************************************************************** 9 + // FreezedGenerator 10 + // ************************************************************************** 11 + 12 + T _$identity<T>(T value) => value; 13 + 14 + final _privateConstructorUsedError = UnsupportedError( 15 + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', 16 + ); 17 + 18 + CreateFavoriteRequest _$CreateFavoriteRequestFromJson( 19 + Map<String, dynamic> json, 20 + ) { 21 + return _CreateFavoriteRequest.fromJson(json); 22 + } 23 + 24 + /// @nodoc 25 + mixin _$CreateFavoriteRequest { 26 + String get subject => throw _privateConstructorUsedError; 27 + 28 + /// Serializes this CreateFavoriteRequest to a JSON map. 29 + Map<String, dynamic> toJson() => throw _privateConstructorUsedError; 30 + 31 + /// Create a copy of CreateFavoriteRequest 32 + /// with the given fields replaced by the non-null parameter values. 33 + @JsonKey(includeFromJson: false, includeToJson: false) 34 + $CreateFavoriteRequestCopyWith<CreateFavoriteRequest> get copyWith => 35 + throw _privateConstructorUsedError; 36 + } 37 + 38 + /// @nodoc 39 + abstract class $CreateFavoriteRequestCopyWith<$Res> { 40 + factory $CreateFavoriteRequestCopyWith( 41 + CreateFavoriteRequest value, 42 + $Res Function(CreateFavoriteRequest) then, 43 + ) = _$CreateFavoriteRequestCopyWithImpl<$Res, CreateFavoriteRequest>; 44 + @useResult 45 + $Res call({String subject}); 46 + } 47 + 48 + /// @nodoc 49 + class _$CreateFavoriteRequestCopyWithImpl< 50 + $Res, 51 + $Val extends CreateFavoriteRequest 52 + > 53 + implements $CreateFavoriteRequestCopyWith<$Res> { 54 + _$CreateFavoriteRequestCopyWithImpl(this._value, this._then); 55 + 56 + // ignore: unused_field 57 + final $Val _value; 58 + // ignore: unused_field 59 + final $Res Function($Val) _then; 60 + 61 + /// Create a copy of CreateFavoriteRequest 62 + /// with the given fields replaced by the non-null parameter values. 63 + @pragma('vm:prefer-inline') 64 + @override 65 + $Res call({Object? subject = null}) { 66 + return _then( 67 + _value.copyWith( 68 + subject: null == subject 69 + ? _value.subject 70 + : subject // ignore: cast_nullable_to_non_nullable 71 + as String, 72 + ) 73 + as $Val, 74 + ); 75 + } 76 + } 77 + 78 + /// @nodoc 79 + abstract class _$$CreateFavoriteRequestImplCopyWith<$Res> 80 + implements $CreateFavoriteRequestCopyWith<$Res> { 81 + factory _$$CreateFavoriteRequestImplCopyWith( 82 + _$CreateFavoriteRequestImpl value, 83 + $Res Function(_$CreateFavoriteRequestImpl) then, 84 + ) = __$$CreateFavoriteRequestImplCopyWithImpl<$Res>; 85 + @override 86 + @useResult 87 + $Res call({String subject}); 88 + } 89 + 90 + /// @nodoc 91 + class __$$CreateFavoriteRequestImplCopyWithImpl<$Res> 92 + extends 93 + _$CreateFavoriteRequestCopyWithImpl<$Res, _$CreateFavoriteRequestImpl> 94 + implements _$$CreateFavoriteRequestImplCopyWith<$Res> { 95 + __$$CreateFavoriteRequestImplCopyWithImpl( 96 + _$CreateFavoriteRequestImpl _value, 97 + $Res Function(_$CreateFavoriteRequestImpl) _then, 98 + ) : super(_value, _then); 99 + 100 + /// Create a copy of CreateFavoriteRequest 101 + /// with the given fields replaced by the non-null parameter values. 102 + @pragma('vm:prefer-inline') 103 + @override 104 + $Res call({Object? subject = null}) { 105 + return _then( 106 + _$CreateFavoriteRequestImpl( 107 + subject: null == subject 108 + ? _value.subject 109 + : subject // ignore: cast_nullable_to_non_nullable 110 + as String, 111 + ), 112 + ); 113 + } 114 + } 115 + 116 + /// @nodoc 117 + @JsonSerializable() 118 + class _$CreateFavoriteRequestImpl implements _CreateFavoriteRequest { 119 + const _$CreateFavoriteRequestImpl({required this.subject}); 120 + 121 + factory _$CreateFavoriteRequestImpl.fromJson(Map<String, dynamic> json) => 122 + _$$CreateFavoriteRequestImplFromJson(json); 123 + 124 + @override 125 + final String subject; 126 + 127 + @override 128 + String toString() { 129 + return 'CreateFavoriteRequest(subject: $subject)'; 130 + } 131 + 132 + @override 133 + bool operator ==(Object other) { 134 + return identical(this, other) || 135 + (other.runtimeType == runtimeType && 136 + other is _$CreateFavoriteRequestImpl && 137 + (identical(other.subject, subject) || other.subject == subject)); 138 + } 139 + 140 + @JsonKey(includeFromJson: false, includeToJson: false) 141 + @override 142 + int get hashCode => Object.hash(runtimeType, subject); 143 + 144 + /// Create a copy of CreateFavoriteRequest 145 + /// with the given fields replaced by the non-null parameter values. 146 + @JsonKey(includeFromJson: false, includeToJson: false) 147 + @override 148 + @pragma('vm:prefer-inline') 149 + _$$CreateFavoriteRequestImplCopyWith<_$CreateFavoriteRequestImpl> 150 + get copyWith => 151 + __$$CreateFavoriteRequestImplCopyWithImpl<_$CreateFavoriteRequestImpl>( 152 + this, 153 + _$identity, 154 + ); 155 + 156 + @override 157 + Map<String, dynamic> toJson() { 158 + return _$$CreateFavoriteRequestImplToJson(this); 159 + } 160 + } 161 + 162 + abstract class _CreateFavoriteRequest implements CreateFavoriteRequest { 163 + const factory _CreateFavoriteRequest({required final String subject}) = 164 + _$CreateFavoriteRequestImpl; 165 + 166 + factory _CreateFavoriteRequest.fromJson(Map<String, dynamic> json) = 167 + _$CreateFavoriteRequestImpl.fromJson; 168 + 169 + @override 170 + String get subject; 171 + 172 + /// Create a copy of CreateFavoriteRequest 173 + /// with the given fields replaced by the non-null parameter values. 174 + @override 175 + @JsonKey(includeFromJson: false, includeToJson: false) 176 + _$$CreateFavoriteRequestImplCopyWith<_$CreateFavoriteRequestImpl> 177 + get copyWith => throw _privateConstructorUsedError; 178 + }
+15
lib/models/procedures/create_favorite_request.g.dart
··· 1 + // GENERATED CODE - DO NOT MODIFY BY HAND 2 + 3 + part of 'create_favorite_request.dart'; 4 + 5 + // ************************************************************************** 6 + // JsonSerializableGenerator 7 + // ************************************************************************** 8 + 9 + _$CreateFavoriteRequestImpl _$$CreateFavoriteRequestImplFromJson( 10 + Map<String, dynamic> json, 11 + ) => _$CreateFavoriteRequestImpl(subject: json['subject'] as String); 12 + 13 + Map<String, dynamic> _$$CreateFavoriteRequestImplToJson( 14 + _$CreateFavoriteRequestImpl instance, 15 + ) => <String, dynamic>{'subject': instance.subject};
+14
lib/models/procedures/create_favorite_response.dart
··· 1 + import 'package:freezed_annotation/freezed_annotation.dart'; 2 + 3 + part 'create_favorite_response.freezed.dart'; 4 + part 'create_favorite_response.g.dart'; 5 + 6 + /// Response model for creating a favorite. 7 + /// See lexicon: social.grain.favorite.createFavorite 8 + @freezed 9 + class CreateFavoriteResponse with _$CreateFavoriteResponse { 10 + const factory CreateFavoriteResponse({required String favoriteUri}) = _CreateFavoriteResponse; 11 + 12 + factory CreateFavoriteResponse.fromJson(Map<String, dynamic> json) => 13 + _$CreateFavoriteResponseFromJson(json); 14 + }
+179
lib/models/procedures/create_favorite_response.freezed.dart
··· 1 + // coverage:ignore-file 2 + // GENERATED CODE - DO NOT MODIFY BY HAND 3 + // ignore_for_file: type=lint 4 + // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark 5 + 6 + part of 'create_favorite_response.dart'; 7 + 8 + // ************************************************************************** 9 + // FreezedGenerator 10 + // ************************************************************************** 11 + 12 + T _$identity<T>(T value) => value; 13 + 14 + final _privateConstructorUsedError = UnsupportedError( 15 + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', 16 + ); 17 + 18 + CreateFavoriteResponse _$CreateFavoriteResponseFromJson( 19 + Map<String, dynamic> json, 20 + ) { 21 + return _CreateFavoriteResponse.fromJson(json); 22 + } 23 + 24 + /// @nodoc 25 + mixin _$CreateFavoriteResponse { 26 + String get favoriteUri => throw _privateConstructorUsedError; 27 + 28 + /// Serializes this CreateFavoriteResponse to a JSON map. 29 + Map<String, dynamic> toJson() => throw _privateConstructorUsedError; 30 + 31 + /// Create a copy of CreateFavoriteResponse 32 + /// with the given fields replaced by the non-null parameter values. 33 + @JsonKey(includeFromJson: false, includeToJson: false) 34 + $CreateFavoriteResponseCopyWith<CreateFavoriteResponse> get copyWith => 35 + throw _privateConstructorUsedError; 36 + } 37 + 38 + /// @nodoc 39 + abstract class $CreateFavoriteResponseCopyWith<$Res> { 40 + factory $CreateFavoriteResponseCopyWith( 41 + CreateFavoriteResponse value, 42 + $Res Function(CreateFavoriteResponse) then, 43 + ) = _$CreateFavoriteResponseCopyWithImpl<$Res, CreateFavoriteResponse>; 44 + @useResult 45 + $Res call({String favoriteUri}); 46 + } 47 + 48 + /// @nodoc 49 + class _$CreateFavoriteResponseCopyWithImpl< 50 + $Res, 51 + $Val extends CreateFavoriteResponse 52 + > 53 + implements $CreateFavoriteResponseCopyWith<$Res> { 54 + _$CreateFavoriteResponseCopyWithImpl(this._value, this._then); 55 + 56 + // ignore: unused_field 57 + final $Val _value; 58 + // ignore: unused_field 59 + final $Res Function($Val) _then; 60 + 61 + /// Create a copy of CreateFavoriteResponse 62 + /// with the given fields replaced by the non-null parameter values. 63 + @pragma('vm:prefer-inline') 64 + @override 65 + $Res call({Object? favoriteUri = null}) { 66 + return _then( 67 + _value.copyWith( 68 + favoriteUri: null == favoriteUri 69 + ? _value.favoriteUri 70 + : favoriteUri // ignore: cast_nullable_to_non_nullable 71 + as String, 72 + ) 73 + as $Val, 74 + ); 75 + } 76 + } 77 + 78 + /// @nodoc 79 + abstract class _$$CreateFavoriteResponseImplCopyWith<$Res> 80 + implements $CreateFavoriteResponseCopyWith<$Res> { 81 + factory _$$CreateFavoriteResponseImplCopyWith( 82 + _$CreateFavoriteResponseImpl value, 83 + $Res Function(_$CreateFavoriteResponseImpl) then, 84 + ) = __$$CreateFavoriteResponseImplCopyWithImpl<$Res>; 85 + @override 86 + @useResult 87 + $Res call({String favoriteUri}); 88 + } 89 + 90 + /// @nodoc 91 + class __$$CreateFavoriteResponseImplCopyWithImpl<$Res> 92 + extends 93 + _$CreateFavoriteResponseCopyWithImpl<$Res, _$CreateFavoriteResponseImpl> 94 + implements _$$CreateFavoriteResponseImplCopyWith<$Res> { 95 + __$$CreateFavoriteResponseImplCopyWithImpl( 96 + _$CreateFavoriteResponseImpl _value, 97 + $Res Function(_$CreateFavoriteResponseImpl) _then, 98 + ) : super(_value, _then); 99 + 100 + /// Create a copy of CreateFavoriteResponse 101 + /// with the given fields replaced by the non-null parameter values. 102 + @pragma('vm:prefer-inline') 103 + @override 104 + $Res call({Object? favoriteUri = null}) { 105 + return _then( 106 + _$CreateFavoriteResponseImpl( 107 + favoriteUri: null == favoriteUri 108 + ? _value.favoriteUri 109 + : favoriteUri // ignore: cast_nullable_to_non_nullable 110 + as String, 111 + ), 112 + ); 113 + } 114 + } 115 + 116 + /// @nodoc 117 + @JsonSerializable() 118 + class _$CreateFavoriteResponseImpl implements _CreateFavoriteResponse { 119 + const _$CreateFavoriteResponseImpl({required this.favoriteUri}); 120 + 121 + factory _$CreateFavoriteResponseImpl.fromJson(Map<String, dynamic> json) => 122 + _$$CreateFavoriteResponseImplFromJson(json); 123 + 124 + @override 125 + final String favoriteUri; 126 + 127 + @override 128 + String toString() { 129 + return 'CreateFavoriteResponse(favoriteUri: $favoriteUri)'; 130 + } 131 + 132 + @override 133 + bool operator ==(Object other) { 134 + return identical(this, other) || 135 + (other.runtimeType == runtimeType && 136 + other is _$CreateFavoriteResponseImpl && 137 + (identical(other.favoriteUri, favoriteUri) || 138 + other.favoriteUri == favoriteUri)); 139 + } 140 + 141 + @JsonKey(includeFromJson: false, includeToJson: false) 142 + @override 143 + int get hashCode => Object.hash(runtimeType, favoriteUri); 144 + 145 + /// Create a copy of CreateFavoriteResponse 146 + /// with the given fields replaced by the non-null parameter values. 147 + @JsonKey(includeFromJson: false, includeToJson: false) 148 + @override 149 + @pragma('vm:prefer-inline') 150 + _$$CreateFavoriteResponseImplCopyWith<_$CreateFavoriteResponseImpl> 151 + get copyWith => 152 + __$$CreateFavoriteResponseImplCopyWithImpl<_$CreateFavoriteResponseImpl>( 153 + this, 154 + _$identity, 155 + ); 156 + 157 + @override 158 + Map<String, dynamic> toJson() { 159 + return _$$CreateFavoriteResponseImplToJson(this); 160 + } 161 + } 162 + 163 + abstract class _CreateFavoriteResponse implements CreateFavoriteResponse { 164 + const factory _CreateFavoriteResponse({required final String favoriteUri}) = 165 + _$CreateFavoriteResponseImpl; 166 + 167 + factory _CreateFavoriteResponse.fromJson(Map<String, dynamic> json) = 168 + _$CreateFavoriteResponseImpl.fromJson; 169 + 170 + @override 171 + String get favoriteUri; 172 + 173 + /// Create a copy of CreateFavoriteResponse 174 + /// with the given fields replaced by the non-null parameter values. 175 + @override 176 + @JsonKey(includeFromJson: false, includeToJson: false) 177 + _$$CreateFavoriteResponseImplCopyWith<_$CreateFavoriteResponseImpl> 178 + get copyWith => throw _privateConstructorUsedError; 179 + }
+15
lib/models/procedures/create_favorite_response.g.dart
··· 1 + // GENERATED CODE - DO NOT MODIFY BY HAND 2 + 3 + part of 'create_favorite_response.dart'; 4 + 5 + // ************************************************************************** 6 + // JsonSerializableGenerator 7 + // ************************************************************************** 8 + 9 + _$CreateFavoriteResponseImpl _$$CreateFavoriteResponseImplFromJson( 10 + Map<String, dynamic> json, 11 + ) => _$CreateFavoriteResponseImpl(favoriteUri: json['favoriteUri'] as String); 12 + 13 + Map<String, dynamic> _$$CreateFavoriteResponseImplToJson( 14 + _$CreateFavoriteResponseImpl instance, 15 + ) => <String, dynamic>{'favoriteUri': instance.favoriteUri};
+15
lib/models/procedures/create_follow_request.dart
··· 1 + import 'package:freezed_annotation/freezed_annotation.dart'; 2 + 3 + part 'create_follow_request.freezed.dart'; 4 + part 'create_follow_request.g.dart'; 5 + 6 + /// Request model for creating a follow relationship. 7 + /// 8 + /// [subject] - The actor DID to follow. 9 + @freezed 10 + class CreateFollowRequest with _$CreateFollowRequest { 11 + const factory CreateFollowRequest({required String subject}) = _CreateFollowRequest; 12 + 13 + factory CreateFollowRequest.fromJson(Map<String, dynamic> json) => 14 + _$CreateFollowRequestFromJson(json); 15 + }
+171
lib/models/procedures/create_follow_request.freezed.dart
··· 1 + // coverage:ignore-file 2 + // GENERATED CODE - DO NOT MODIFY BY HAND 3 + // ignore_for_file: type=lint 4 + // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark 5 + 6 + part of 'create_follow_request.dart'; 7 + 8 + // ************************************************************************** 9 + // FreezedGenerator 10 + // ************************************************************************** 11 + 12 + T _$identity<T>(T value) => value; 13 + 14 + final _privateConstructorUsedError = UnsupportedError( 15 + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', 16 + ); 17 + 18 + CreateFollowRequest _$CreateFollowRequestFromJson(Map<String, dynamic> json) { 19 + return _CreateFollowRequest.fromJson(json); 20 + } 21 + 22 + /// @nodoc 23 + mixin _$CreateFollowRequest { 24 + String get subject => throw _privateConstructorUsedError; 25 + 26 + /// Serializes this CreateFollowRequest to a JSON map. 27 + Map<String, dynamic> toJson() => throw _privateConstructorUsedError; 28 + 29 + /// Create a copy of CreateFollowRequest 30 + /// with the given fields replaced by the non-null parameter values. 31 + @JsonKey(includeFromJson: false, includeToJson: false) 32 + $CreateFollowRequestCopyWith<CreateFollowRequest> get copyWith => 33 + throw _privateConstructorUsedError; 34 + } 35 + 36 + /// @nodoc 37 + abstract class $CreateFollowRequestCopyWith<$Res> { 38 + factory $CreateFollowRequestCopyWith( 39 + CreateFollowRequest value, 40 + $Res Function(CreateFollowRequest) then, 41 + ) = _$CreateFollowRequestCopyWithImpl<$Res, CreateFollowRequest>; 42 + @useResult 43 + $Res call({String subject}); 44 + } 45 + 46 + /// @nodoc 47 + class _$CreateFollowRequestCopyWithImpl<$Res, $Val extends CreateFollowRequest> 48 + implements $CreateFollowRequestCopyWith<$Res> { 49 + _$CreateFollowRequestCopyWithImpl(this._value, this._then); 50 + 51 + // ignore: unused_field 52 + final $Val _value; 53 + // ignore: unused_field 54 + final $Res Function($Val) _then; 55 + 56 + /// Create a copy of CreateFollowRequest 57 + /// with the given fields replaced by the non-null parameter values. 58 + @pragma('vm:prefer-inline') 59 + @override 60 + $Res call({Object? subject = null}) { 61 + return _then( 62 + _value.copyWith( 63 + subject: null == subject 64 + ? _value.subject 65 + : subject // ignore: cast_nullable_to_non_nullable 66 + as String, 67 + ) 68 + as $Val, 69 + ); 70 + } 71 + } 72 + 73 + /// @nodoc 74 + abstract class _$$CreateFollowRequestImplCopyWith<$Res> 75 + implements $CreateFollowRequestCopyWith<$Res> { 76 + factory _$$CreateFollowRequestImplCopyWith( 77 + _$CreateFollowRequestImpl value, 78 + $Res Function(_$CreateFollowRequestImpl) then, 79 + ) = __$$CreateFollowRequestImplCopyWithImpl<$Res>; 80 + @override 81 + @useResult 82 + $Res call({String subject}); 83 + } 84 + 85 + /// @nodoc 86 + class __$$CreateFollowRequestImplCopyWithImpl<$Res> 87 + extends _$CreateFollowRequestCopyWithImpl<$Res, _$CreateFollowRequestImpl> 88 + implements _$$CreateFollowRequestImplCopyWith<$Res> { 89 + __$$CreateFollowRequestImplCopyWithImpl( 90 + _$CreateFollowRequestImpl _value, 91 + $Res Function(_$CreateFollowRequestImpl) _then, 92 + ) : super(_value, _then); 93 + 94 + /// Create a copy of CreateFollowRequest 95 + /// with the given fields replaced by the non-null parameter values. 96 + @pragma('vm:prefer-inline') 97 + @override 98 + $Res call({Object? subject = null}) { 99 + return _then( 100 + _$CreateFollowRequestImpl( 101 + subject: null == subject 102 + ? _value.subject 103 + : subject // ignore: cast_nullable_to_non_nullable 104 + as String, 105 + ), 106 + ); 107 + } 108 + } 109 + 110 + /// @nodoc 111 + @JsonSerializable() 112 + class _$CreateFollowRequestImpl implements _CreateFollowRequest { 113 + const _$CreateFollowRequestImpl({required this.subject}); 114 + 115 + factory _$CreateFollowRequestImpl.fromJson(Map<String, dynamic> json) => 116 + _$$CreateFollowRequestImplFromJson(json); 117 + 118 + @override 119 + final String subject; 120 + 121 + @override 122 + String toString() { 123 + return 'CreateFollowRequest(subject: $subject)'; 124 + } 125 + 126 + @override 127 + bool operator ==(Object other) { 128 + return identical(this, other) || 129 + (other.runtimeType == runtimeType && 130 + other is _$CreateFollowRequestImpl && 131 + (identical(other.subject, subject) || other.subject == subject)); 132 + } 133 + 134 + @JsonKey(includeFromJson: false, includeToJson: false) 135 + @override 136 + int get hashCode => Object.hash(runtimeType, subject); 137 + 138 + /// Create a copy of CreateFollowRequest 139 + /// with the given fields replaced by the non-null parameter values. 140 + @JsonKey(includeFromJson: false, includeToJson: false) 141 + @override 142 + @pragma('vm:prefer-inline') 143 + _$$CreateFollowRequestImplCopyWith<_$CreateFollowRequestImpl> get copyWith => 144 + __$$CreateFollowRequestImplCopyWithImpl<_$CreateFollowRequestImpl>( 145 + this, 146 + _$identity, 147 + ); 148 + 149 + @override 150 + Map<String, dynamic> toJson() { 151 + return _$$CreateFollowRequestImplToJson(this); 152 + } 153 + } 154 + 155 + abstract class _CreateFollowRequest implements CreateFollowRequest { 156 + const factory _CreateFollowRequest({required final String subject}) = 157 + _$CreateFollowRequestImpl; 158 + 159 + factory _CreateFollowRequest.fromJson(Map<String, dynamic> json) = 160 + _$CreateFollowRequestImpl.fromJson; 161 + 162 + @override 163 + String get subject; 164 + 165 + /// Create a copy of CreateFollowRequest 166 + /// with the given fields replaced by the non-null parameter values. 167 + @override 168 + @JsonKey(includeFromJson: false, includeToJson: false) 169 + _$$CreateFollowRequestImplCopyWith<_$CreateFollowRequestImpl> get copyWith => 170 + throw _privateConstructorUsedError; 171 + }
+15
lib/models/procedures/create_follow_request.g.dart
··· 1 + // GENERATED CODE - DO NOT MODIFY BY HAND 2 + 3 + part of 'create_follow_request.dart'; 4 + 5 + // ************************************************************************** 6 + // JsonSerializableGenerator 7 + // ************************************************************************** 8 + 9 + _$CreateFollowRequestImpl _$$CreateFollowRequestImplFromJson( 10 + Map<String, dynamic> json, 11 + ) => _$CreateFollowRequestImpl(subject: json['subject'] as String); 12 + 13 + Map<String, dynamic> _$$CreateFollowRequestImplToJson( 14 + _$CreateFollowRequestImpl instance, 15 + ) => <String, dynamic>{'subject': instance.subject};
+15
lib/models/procedures/create_follow_response.dart
··· 1 + import 'package:freezed_annotation/freezed_annotation.dart'; 2 + 3 + part 'create_follow_response.freezed.dart'; 4 + part 'create_follow_response.g.dart'; 5 + 6 + /// Response model for creating a follow relationship. 7 + /// 8 + /// [followUri] - The URI of the created follow relationship. 9 + @freezed 10 + class CreateFollowResponse with _$CreateFollowResponse { 11 + const factory CreateFollowResponse({required String followUri}) = _CreateFollowResponse; 12 + 13 + factory CreateFollowResponse.fromJson(Map<String, dynamic> json) => 14 + _$CreateFollowResponseFromJson(json); 15 + }
+176
lib/models/procedures/create_follow_response.freezed.dart
··· 1 + // coverage:ignore-file 2 + // GENERATED CODE - DO NOT MODIFY BY HAND 3 + // ignore_for_file: type=lint 4 + // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark 5 + 6 + part of 'create_follow_response.dart'; 7 + 8 + // ************************************************************************** 9 + // FreezedGenerator 10 + // ************************************************************************** 11 + 12 + T _$identity<T>(T value) => value; 13 + 14 + final _privateConstructorUsedError = UnsupportedError( 15 + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', 16 + ); 17 + 18 + CreateFollowResponse _$CreateFollowResponseFromJson(Map<String, dynamic> json) { 19 + return _CreateFollowResponse.fromJson(json); 20 + } 21 + 22 + /// @nodoc 23 + mixin _$CreateFollowResponse { 24 + String get followUri => throw _privateConstructorUsedError; 25 + 26 + /// Serializes this CreateFollowResponse to a JSON map. 27 + Map<String, dynamic> toJson() => throw _privateConstructorUsedError; 28 + 29 + /// Create a copy of CreateFollowResponse 30 + /// with the given fields replaced by the non-null parameter values. 31 + @JsonKey(includeFromJson: false, includeToJson: false) 32 + $CreateFollowResponseCopyWith<CreateFollowResponse> get copyWith => 33 + throw _privateConstructorUsedError; 34 + } 35 + 36 + /// @nodoc 37 + abstract class $CreateFollowResponseCopyWith<$Res> { 38 + factory $CreateFollowResponseCopyWith( 39 + CreateFollowResponse value, 40 + $Res Function(CreateFollowResponse) then, 41 + ) = _$CreateFollowResponseCopyWithImpl<$Res, CreateFollowResponse>; 42 + @useResult 43 + $Res call({String followUri}); 44 + } 45 + 46 + /// @nodoc 47 + class _$CreateFollowResponseCopyWithImpl< 48 + $Res, 49 + $Val extends CreateFollowResponse 50 + > 51 + implements $CreateFollowResponseCopyWith<$Res> { 52 + _$CreateFollowResponseCopyWithImpl(this._value, this._then); 53 + 54 + // ignore: unused_field 55 + final $Val _value; 56 + // ignore: unused_field 57 + final $Res Function($Val) _then; 58 + 59 + /// Create a copy of CreateFollowResponse 60 + /// with the given fields replaced by the non-null parameter values. 61 + @pragma('vm:prefer-inline') 62 + @override 63 + $Res call({Object? followUri = null}) { 64 + return _then( 65 + _value.copyWith( 66 + followUri: null == followUri 67 + ? _value.followUri 68 + : followUri // ignore: cast_nullable_to_non_nullable 69 + as String, 70 + ) 71 + as $Val, 72 + ); 73 + } 74 + } 75 + 76 + /// @nodoc 77 + abstract class _$$CreateFollowResponseImplCopyWith<$Res> 78 + implements $CreateFollowResponseCopyWith<$Res> { 79 + factory _$$CreateFollowResponseImplCopyWith( 80 + _$CreateFollowResponseImpl value, 81 + $Res Function(_$CreateFollowResponseImpl) then, 82 + ) = __$$CreateFollowResponseImplCopyWithImpl<$Res>; 83 + @override 84 + @useResult 85 + $Res call({String followUri}); 86 + } 87 + 88 + /// @nodoc 89 + class __$$CreateFollowResponseImplCopyWithImpl<$Res> 90 + extends _$CreateFollowResponseCopyWithImpl<$Res, _$CreateFollowResponseImpl> 91 + implements _$$CreateFollowResponseImplCopyWith<$Res> { 92 + __$$CreateFollowResponseImplCopyWithImpl( 93 + _$CreateFollowResponseImpl _value, 94 + $Res Function(_$CreateFollowResponseImpl) _then, 95 + ) : super(_value, _then); 96 + 97 + /// Create a copy of CreateFollowResponse 98 + /// with the given fields replaced by the non-null parameter values. 99 + @pragma('vm:prefer-inline') 100 + @override 101 + $Res call({Object? followUri = null}) { 102 + return _then( 103 + _$CreateFollowResponseImpl( 104 + followUri: null == followUri 105 + ? _value.followUri 106 + : followUri // ignore: cast_nullable_to_non_nullable 107 + as String, 108 + ), 109 + ); 110 + } 111 + } 112 + 113 + /// @nodoc 114 + @JsonSerializable() 115 + class _$CreateFollowResponseImpl implements _CreateFollowResponse { 116 + const _$CreateFollowResponseImpl({required this.followUri}); 117 + 118 + factory _$CreateFollowResponseImpl.fromJson(Map<String, dynamic> json) => 119 + _$$CreateFollowResponseImplFromJson(json); 120 + 121 + @override 122 + final String followUri; 123 + 124 + @override 125 + String toString() { 126 + return 'CreateFollowResponse(followUri: $followUri)'; 127 + } 128 + 129 + @override 130 + bool operator ==(Object other) { 131 + return identical(this, other) || 132 + (other.runtimeType == runtimeType && 133 + other is _$CreateFollowResponseImpl && 134 + (identical(other.followUri, followUri) || 135 + other.followUri == followUri)); 136 + } 137 + 138 + @JsonKey(includeFromJson: false, includeToJson: false) 139 + @override 140 + int get hashCode => Object.hash(runtimeType, followUri); 141 + 142 + /// Create a copy of CreateFollowResponse 143 + /// with the given fields replaced by the non-null parameter values. 144 + @JsonKey(includeFromJson: false, includeToJson: false) 145 + @override 146 + @pragma('vm:prefer-inline') 147 + _$$CreateFollowResponseImplCopyWith<_$CreateFollowResponseImpl> 148 + get copyWith => 149 + __$$CreateFollowResponseImplCopyWithImpl<_$CreateFollowResponseImpl>( 150 + this, 151 + _$identity, 152 + ); 153 + 154 + @override 155 + Map<String, dynamic> toJson() { 156 + return _$$CreateFollowResponseImplToJson(this); 157 + } 158 + } 159 + 160 + abstract class _CreateFollowResponse implements CreateFollowResponse { 161 + const factory _CreateFollowResponse({required final String followUri}) = 162 + _$CreateFollowResponseImpl; 163 + 164 + factory _CreateFollowResponse.fromJson(Map<String, dynamic> json) = 165 + _$CreateFollowResponseImpl.fromJson; 166 + 167 + @override 168 + String get followUri; 169 + 170 + /// Create a copy of CreateFollowResponse 171 + /// with the given fields replaced by the non-null parameter values. 172 + @override 173 + @JsonKey(includeFromJson: false, includeToJson: false) 174 + _$$CreateFollowResponseImplCopyWith<_$CreateFollowResponseImpl> 175 + get copyWith => throw _privateConstructorUsedError; 176 + }
+15
lib/models/procedures/create_follow_response.g.dart
··· 1 + // GENERATED CODE - DO NOT MODIFY BY HAND 2 + 3 + part of 'create_follow_response.dart'; 4 + 5 + // ************************************************************************** 6 + // JsonSerializableGenerator 7 + // ************************************************************************** 8 + 9 + _$CreateFollowResponseImpl _$$CreateFollowResponseImplFromJson( 10 + Map<String, dynamic> json, 11 + ) => _$CreateFollowResponseImpl(followUri: json['followUri'] as String); 12 + 13 + Map<String, dynamic> _$$CreateFollowResponseImplToJson( 14 + _$CreateFollowResponseImpl instance, 15 + ) => <String, dynamic>{'followUri': instance.followUri};
+14
lib/models/procedures/delete_comment_request.dart
··· 1 + import 'package:freezed_annotation/freezed_annotation.dart'; 2 + 3 + part 'delete_comment_request.freezed.dart'; 4 + part 'delete_comment_request.g.dart'; 5 + 6 + /// Request model for deleting a comment. 7 + /// See lexicon: social.grain.comment.deleteComment 8 + @freezed 9 + class DeleteCommentRequest with _$DeleteCommentRequest { 10 + const factory DeleteCommentRequest({required String uri}) = _DeleteCommentRequest; 11 + 12 + factory DeleteCommentRequest.fromJson(Map<String, dynamic> json) => 13 + _$DeleteCommentRequestFromJson(json); 14 + }
+175
lib/models/procedures/delete_comment_request.freezed.dart
··· 1 + // coverage:ignore-file 2 + // GENERATED CODE - DO NOT MODIFY BY HAND 3 + // ignore_for_file: type=lint 4 + // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark 5 + 6 + part of 'delete_comment_request.dart'; 7 + 8 + // ************************************************************************** 9 + // FreezedGenerator 10 + // ************************************************************************** 11 + 12 + T _$identity<T>(T value) => value; 13 + 14 + final _privateConstructorUsedError = UnsupportedError( 15 + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', 16 + ); 17 + 18 + DeleteCommentRequest _$DeleteCommentRequestFromJson(Map<String, dynamic> json) { 19 + return _DeleteCommentRequest.fromJson(json); 20 + } 21 + 22 + /// @nodoc 23 + mixin _$DeleteCommentRequest { 24 + String get uri => throw _privateConstructorUsedError; 25 + 26 + /// Serializes this DeleteCommentRequest to a JSON map. 27 + Map<String, dynamic> toJson() => throw _privateConstructorUsedError; 28 + 29 + /// Create a copy of DeleteCommentRequest 30 + /// with the given fields replaced by the non-null parameter values. 31 + @JsonKey(includeFromJson: false, includeToJson: false) 32 + $DeleteCommentRequestCopyWith<DeleteCommentRequest> get copyWith => 33 + throw _privateConstructorUsedError; 34 + } 35 + 36 + /// @nodoc 37 + abstract class $DeleteCommentRequestCopyWith<$Res> { 38 + factory $DeleteCommentRequestCopyWith( 39 + DeleteCommentRequest value, 40 + $Res Function(DeleteCommentRequest) then, 41 + ) = _$DeleteCommentRequestCopyWithImpl<$Res, DeleteCommentRequest>; 42 + @useResult 43 + $Res call({String uri}); 44 + } 45 + 46 + /// @nodoc 47 + class _$DeleteCommentRequestCopyWithImpl< 48 + $Res, 49 + $Val extends DeleteCommentRequest 50 + > 51 + implements $DeleteCommentRequestCopyWith<$Res> { 52 + _$DeleteCommentRequestCopyWithImpl(this._value, this._then); 53 + 54 + // ignore: unused_field 55 + final $Val _value; 56 + // ignore: unused_field 57 + final $Res Function($Val) _then; 58 + 59 + /// Create a copy of DeleteCommentRequest 60 + /// with the given fields replaced by the non-null parameter values. 61 + @pragma('vm:prefer-inline') 62 + @override 63 + $Res call({Object? uri = null}) { 64 + return _then( 65 + _value.copyWith( 66 + uri: null == uri 67 + ? _value.uri 68 + : uri // ignore: cast_nullable_to_non_nullable 69 + as String, 70 + ) 71 + as $Val, 72 + ); 73 + } 74 + } 75 + 76 + /// @nodoc 77 + abstract class _$$DeleteCommentRequestImplCopyWith<$Res> 78 + implements $DeleteCommentRequestCopyWith<$Res> { 79 + factory _$$DeleteCommentRequestImplCopyWith( 80 + _$DeleteCommentRequestImpl value, 81 + $Res Function(_$DeleteCommentRequestImpl) then, 82 + ) = __$$DeleteCommentRequestImplCopyWithImpl<$Res>; 83 + @override 84 + @useResult 85 + $Res call({String uri}); 86 + } 87 + 88 + /// @nodoc 89 + class __$$DeleteCommentRequestImplCopyWithImpl<$Res> 90 + extends _$DeleteCommentRequestCopyWithImpl<$Res, _$DeleteCommentRequestImpl> 91 + implements _$$DeleteCommentRequestImplCopyWith<$Res> { 92 + __$$DeleteCommentRequestImplCopyWithImpl( 93 + _$DeleteCommentRequestImpl _value, 94 + $Res Function(_$DeleteCommentRequestImpl) _then, 95 + ) : super(_value, _then); 96 + 97 + /// Create a copy of DeleteCommentRequest 98 + /// with the given fields replaced by the non-null parameter values. 99 + @pragma('vm:prefer-inline') 100 + @override 101 + $Res call({Object? uri = null}) { 102 + return _then( 103 + _$DeleteCommentRequestImpl( 104 + uri: null == uri 105 + ? _value.uri 106 + : uri // ignore: cast_nullable_to_non_nullable 107 + as String, 108 + ), 109 + ); 110 + } 111 + } 112 + 113 + /// @nodoc 114 + @JsonSerializable() 115 + class _$DeleteCommentRequestImpl implements _DeleteCommentRequest { 116 + const _$DeleteCommentRequestImpl({required this.uri}); 117 + 118 + factory _$DeleteCommentRequestImpl.fromJson(Map<String, dynamic> json) => 119 + _$$DeleteCommentRequestImplFromJson(json); 120 + 121 + @override 122 + final String uri; 123 + 124 + @override 125 + String toString() { 126 + return 'DeleteCommentRequest(uri: $uri)'; 127 + } 128 + 129 + @override 130 + bool operator ==(Object other) { 131 + return identical(this, other) || 132 + (other.runtimeType == runtimeType && 133 + other is _$DeleteCommentRequestImpl && 134 + (identical(other.uri, uri) || other.uri == uri)); 135 + } 136 + 137 + @JsonKey(includeFromJson: false, includeToJson: false) 138 + @override 139 + int get hashCode => Object.hash(runtimeType, uri); 140 + 141 + /// Create a copy of DeleteCommentRequest 142 + /// with the given fields replaced by the non-null parameter values. 143 + @JsonKey(includeFromJson: false, includeToJson: false) 144 + @override 145 + @pragma('vm:prefer-inline') 146 + _$$DeleteCommentRequestImplCopyWith<_$DeleteCommentRequestImpl> 147 + get copyWith => 148 + __$$DeleteCommentRequestImplCopyWithImpl<_$DeleteCommentRequestImpl>( 149 + this, 150 + _$identity, 151 + ); 152 + 153 + @override 154 + Map<String, dynamic> toJson() { 155 + return _$$DeleteCommentRequestImplToJson(this); 156 + } 157 + } 158 + 159 + abstract class _DeleteCommentRequest implements DeleteCommentRequest { 160 + const factory _DeleteCommentRequest({required final String uri}) = 161 + _$DeleteCommentRequestImpl; 162 + 163 + factory _DeleteCommentRequest.fromJson(Map<String, dynamic> json) = 164 + _$DeleteCommentRequestImpl.fromJson; 165 + 166 + @override 167 + String get uri; 168 + 169 + /// Create a copy of DeleteCommentRequest 170 + /// with the given fields replaced by the non-null parameter values. 171 + @override 172 + @JsonKey(includeFromJson: false, includeToJson: false) 173 + _$$DeleteCommentRequestImplCopyWith<_$DeleteCommentRequestImpl> 174 + get copyWith => throw _privateConstructorUsedError; 175 + }
+15
lib/models/procedures/delete_comment_request.g.dart
··· 1 + // GENERATED CODE - DO NOT MODIFY BY HAND 2 + 3 + part of 'delete_comment_request.dart'; 4 + 5 + // ************************************************************************** 6 + // JsonSerializableGenerator 7 + // ************************************************************************** 8 + 9 + _$DeleteCommentRequestImpl _$$DeleteCommentRequestImplFromJson( 10 + Map<String, dynamic> json, 11 + ) => _$DeleteCommentRequestImpl(uri: json['uri'] as String); 12 + 13 + Map<String, dynamic> _$$DeleteCommentRequestImplToJson( 14 + _$DeleteCommentRequestImpl instance, 15 + ) => <String, dynamic>{'uri': instance.uri};
+14
lib/models/procedures/delete_comment_response.dart
··· 1 + import 'package:freezed_annotation/freezed_annotation.dart'; 2 + 3 + part 'delete_comment_response.freezed.dart'; 4 + part 'delete_comment_response.g.dart'; 5 + 6 + /// Response model for deleting a comment. 7 + /// See lexicon: social.grain.comment.deleteComment 8 + @freezed 9 + class DeleteCommentResponse with _$DeleteCommentResponse { 10 + const factory DeleteCommentResponse({required bool success}) = _DeleteCommentResponse; 11 + 12 + factory DeleteCommentResponse.fromJson(Map<String, dynamic> json) => 13 + _$DeleteCommentResponseFromJson(json); 14 + }
+178
lib/models/procedures/delete_comment_response.freezed.dart
··· 1 + // coverage:ignore-file 2 + // GENERATED CODE - DO NOT MODIFY BY HAND 3 + // ignore_for_file: type=lint 4 + // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark 5 + 6 + part of 'delete_comment_response.dart'; 7 + 8 + // ************************************************************************** 9 + // FreezedGenerator 10 + // ************************************************************************** 11 + 12 + T _$identity<T>(T value) => value; 13 + 14 + final _privateConstructorUsedError = UnsupportedError( 15 + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', 16 + ); 17 + 18 + DeleteCommentResponse _$DeleteCommentResponseFromJson( 19 + Map<String, dynamic> json, 20 + ) { 21 + return _DeleteCommentResponse.fromJson(json); 22 + } 23 + 24 + /// @nodoc 25 + mixin _$DeleteCommentResponse { 26 + bool get success => throw _privateConstructorUsedError; 27 + 28 + /// Serializes this DeleteCommentResponse to a JSON map. 29 + Map<String, dynamic> toJson() => throw _privateConstructorUsedError; 30 + 31 + /// Create a copy of DeleteCommentResponse 32 + /// with the given fields replaced by the non-null parameter values. 33 + @JsonKey(includeFromJson: false, includeToJson: false) 34 + $DeleteCommentResponseCopyWith<DeleteCommentResponse> get copyWith => 35 + throw _privateConstructorUsedError; 36 + } 37 + 38 + /// @nodoc 39 + abstract class $DeleteCommentResponseCopyWith<$Res> { 40 + factory $DeleteCommentResponseCopyWith( 41 + DeleteCommentResponse value, 42 + $Res Function(DeleteCommentResponse) then, 43 + ) = _$DeleteCommentResponseCopyWithImpl<$Res, DeleteCommentResponse>; 44 + @useResult 45 + $Res call({bool success}); 46 + } 47 + 48 + /// @nodoc 49 + class _$DeleteCommentResponseCopyWithImpl< 50 + $Res, 51 + $Val extends DeleteCommentResponse 52 + > 53 + implements $DeleteCommentResponseCopyWith<$Res> { 54 + _$DeleteCommentResponseCopyWithImpl(this._value, this._then); 55 + 56 + // ignore: unused_field 57 + final $Val _value; 58 + // ignore: unused_field 59 + final $Res Function($Val) _then; 60 + 61 + /// Create a copy of DeleteCommentResponse 62 + /// with the given fields replaced by the non-null parameter values. 63 + @pragma('vm:prefer-inline') 64 + @override 65 + $Res call({Object? success = null}) { 66 + return _then( 67 + _value.copyWith( 68 + success: null == success 69 + ? _value.success 70 + : success // ignore: cast_nullable_to_non_nullable 71 + as bool, 72 + ) 73 + as $Val, 74 + ); 75 + } 76 + } 77 + 78 + /// @nodoc 79 + abstract class _$$DeleteCommentResponseImplCopyWith<$Res> 80 + implements $DeleteCommentResponseCopyWith<$Res> { 81 + factory _$$DeleteCommentResponseImplCopyWith( 82 + _$DeleteCommentResponseImpl value, 83 + $Res Function(_$DeleteCommentResponseImpl) then, 84 + ) = __$$DeleteCommentResponseImplCopyWithImpl<$Res>; 85 + @override 86 + @useResult 87 + $Res call({bool success}); 88 + } 89 + 90 + /// @nodoc 91 + class __$$DeleteCommentResponseImplCopyWithImpl<$Res> 92 + extends 93 + _$DeleteCommentResponseCopyWithImpl<$Res, _$DeleteCommentResponseImpl> 94 + implements _$$DeleteCommentResponseImplCopyWith<$Res> { 95 + __$$DeleteCommentResponseImplCopyWithImpl( 96 + _$DeleteCommentResponseImpl _value, 97 + $Res Function(_$DeleteCommentResponseImpl) _then, 98 + ) : super(_value, _then); 99 + 100 + /// Create a copy of DeleteCommentResponse 101 + /// with the given fields replaced by the non-null parameter values. 102 + @pragma('vm:prefer-inline') 103 + @override 104 + $Res call({Object? success = null}) { 105 + return _then( 106 + _$DeleteCommentResponseImpl( 107 + success: null == success 108 + ? _value.success 109 + : success // ignore: cast_nullable_to_non_nullable 110 + as bool, 111 + ), 112 + ); 113 + } 114 + } 115 + 116 + /// @nodoc 117 + @JsonSerializable() 118 + class _$DeleteCommentResponseImpl implements _DeleteCommentResponse { 119 + const _$DeleteCommentResponseImpl({required this.success}); 120 + 121 + factory _$DeleteCommentResponseImpl.fromJson(Map<String, dynamic> json) => 122 + _$$DeleteCommentResponseImplFromJson(json); 123 + 124 + @override 125 + final bool success; 126 + 127 + @override 128 + String toString() { 129 + return 'DeleteCommentResponse(success: $success)'; 130 + } 131 + 132 + @override 133 + bool operator ==(Object other) { 134 + return identical(this, other) || 135 + (other.runtimeType == runtimeType && 136 + other is _$DeleteCommentResponseImpl && 137 + (identical(other.success, success) || other.success == success)); 138 + } 139 + 140 + @JsonKey(includeFromJson: false, includeToJson: false) 141 + @override 142 + int get hashCode => Object.hash(runtimeType, success); 143 + 144 + /// Create a copy of DeleteCommentResponse 145 + /// with the given fields replaced by the non-null parameter values. 146 + @JsonKey(includeFromJson: false, includeToJson: false) 147 + @override 148 + @pragma('vm:prefer-inline') 149 + _$$DeleteCommentResponseImplCopyWith<_$DeleteCommentResponseImpl> 150 + get copyWith => 151 + __$$DeleteCommentResponseImplCopyWithImpl<_$DeleteCommentResponseImpl>( 152 + this, 153 + _$identity, 154 + ); 155 + 156 + @override 157 + Map<String, dynamic> toJson() { 158 + return _$$DeleteCommentResponseImplToJson(this); 159 + } 160 + } 161 + 162 + abstract class _DeleteCommentResponse implements DeleteCommentResponse { 163 + const factory _DeleteCommentResponse({required final bool success}) = 164 + _$DeleteCommentResponseImpl; 165 + 166 + factory _DeleteCommentResponse.fromJson(Map<String, dynamic> json) = 167 + _$DeleteCommentResponseImpl.fromJson; 168 + 169 + @override 170 + bool get success; 171 + 172 + /// Create a copy of DeleteCommentResponse 173 + /// with the given fields replaced by the non-null parameter values. 174 + @override 175 + @JsonKey(includeFromJson: false, includeToJson: false) 176 + _$$DeleteCommentResponseImplCopyWith<_$DeleteCommentResponseImpl> 177 + get copyWith => throw _privateConstructorUsedError; 178 + }
+15
lib/models/procedures/delete_comment_response.g.dart
··· 1 + // GENERATED CODE - DO NOT MODIFY BY HAND 2 + 3 + part of 'delete_comment_response.dart'; 4 + 5 + // ************************************************************************** 6 + // JsonSerializableGenerator 7 + // ************************************************************************** 8 + 9 + _$DeleteCommentResponseImpl _$$DeleteCommentResponseImplFromJson( 10 + Map<String, dynamic> json, 11 + ) => _$DeleteCommentResponseImpl(success: json['success'] as bool); 12 + 13 + Map<String, dynamic> _$$DeleteCommentResponseImplToJson( 14 + _$DeleteCommentResponseImpl instance, 15 + ) => <String, dynamic>{'success': instance.success};
+14
lib/models/procedures/delete_favorite_request.dart
··· 1 + import 'package:freezed_annotation/freezed_annotation.dart'; 2 + 3 + part 'delete_favorite_request.freezed.dart'; 4 + part 'delete_favorite_request.g.dart'; 5 + 6 + /// Request model for deleting a favorite. 7 + /// See lexicon: social.grain.favorite.deleteFavorite 8 + @freezed 9 + class DeleteFavoriteRequest with _$DeleteFavoriteRequest { 10 + const factory DeleteFavoriteRequest({required String uri}) = _DeleteFavoriteRequest; 11 + 12 + factory DeleteFavoriteRequest.fromJson(Map<String, dynamic> json) => 13 + _$DeleteFavoriteRequestFromJson(json); 14 + }
+178
lib/models/procedures/delete_favorite_request.freezed.dart
··· 1 + // coverage:ignore-file 2 + // GENERATED CODE - DO NOT MODIFY BY HAND 3 + // ignore_for_file: type=lint 4 + // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark 5 + 6 + part of 'delete_favorite_request.dart'; 7 + 8 + // ************************************************************************** 9 + // FreezedGenerator 10 + // ************************************************************************** 11 + 12 + T _$identity<T>(T value) => value; 13 + 14 + final _privateConstructorUsedError = UnsupportedError( 15 + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', 16 + ); 17 + 18 + DeleteFavoriteRequest _$DeleteFavoriteRequestFromJson( 19 + Map<String, dynamic> json, 20 + ) { 21 + return _DeleteFavoriteRequest.fromJson(json); 22 + } 23 + 24 + /// @nodoc 25 + mixin _$DeleteFavoriteRequest { 26 + String get uri => throw _privateConstructorUsedError; 27 + 28 + /// Serializes this DeleteFavoriteRequest to a JSON map. 29 + Map<String, dynamic> toJson() => throw _privateConstructorUsedError; 30 + 31 + /// Create a copy of DeleteFavoriteRequest 32 + /// with the given fields replaced by the non-null parameter values. 33 + @JsonKey(includeFromJson: false, includeToJson: false) 34 + $DeleteFavoriteRequestCopyWith<DeleteFavoriteRequest> get copyWith => 35 + throw _privateConstructorUsedError; 36 + } 37 + 38 + /// @nodoc 39 + abstract class $DeleteFavoriteRequestCopyWith<$Res> { 40 + factory $DeleteFavoriteRequestCopyWith( 41 + DeleteFavoriteRequest value, 42 + $Res Function(DeleteFavoriteRequest) then, 43 + ) = _$DeleteFavoriteRequestCopyWithImpl<$Res, DeleteFavoriteRequest>; 44 + @useResult 45 + $Res call({String uri}); 46 + } 47 + 48 + /// @nodoc 49 + class _$DeleteFavoriteRequestCopyWithImpl< 50 + $Res, 51 + $Val extends DeleteFavoriteRequest 52 + > 53 + implements $DeleteFavoriteRequestCopyWith<$Res> { 54 + _$DeleteFavoriteRequestCopyWithImpl(this._value, this._then); 55 + 56 + // ignore: unused_field 57 + final $Val _value; 58 + // ignore: unused_field 59 + final $Res Function($Val) _then; 60 + 61 + /// Create a copy of DeleteFavoriteRequest 62 + /// with the given fields replaced by the non-null parameter values. 63 + @pragma('vm:prefer-inline') 64 + @override 65 + $Res call({Object? uri = null}) { 66 + return _then( 67 + _value.copyWith( 68 + uri: null == uri 69 + ? _value.uri 70 + : uri // ignore: cast_nullable_to_non_nullable 71 + as String, 72 + ) 73 + as $Val, 74 + ); 75 + } 76 + } 77 + 78 + /// @nodoc 79 + abstract class _$$DeleteFavoriteRequestImplCopyWith<$Res> 80 + implements $DeleteFavoriteRequestCopyWith<$Res> { 81 + factory _$$DeleteFavoriteRequestImplCopyWith( 82 + _$DeleteFavoriteRequestImpl value, 83 + $Res Function(_$DeleteFavoriteRequestImpl) then, 84 + ) = __$$DeleteFavoriteRequestImplCopyWithImpl<$Res>; 85 + @override 86 + @useResult 87 + $Res call({String uri}); 88 + } 89 + 90 + /// @nodoc 91 + class __$$DeleteFavoriteRequestImplCopyWithImpl<$Res> 92 + extends 93 + _$DeleteFavoriteRequestCopyWithImpl<$Res, _$DeleteFavoriteRequestImpl> 94 + implements _$$DeleteFavoriteRequestImplCopyWith<$Res> { 95 + __$$DeleteFavoriteRequestImplCopyWithImpl( 96 + _$DeleteFavoriteRequestImpl _value, 97 + $Res Function(_$DeleteFavoriteRequestImpl) _then, 98 + ) : super(_value, _then); 99 + 100 + /// Create a copy of DeleteFavoriteRequest 101 + /// with the given fields replaced by the non-null parameter values. 102 + @pragma('vm:prefer-inline') 103 + @override 104 + $Res call({Object? uri = null}) { 105 + return _then( 106 + _$DeleteFavoriteRequestImpl( 107 + uri: null == uri 108 + ? _value.uri 109 + : uri // ignore: cast_nullable_to_non_nullable 110 + as String, 111 + ), 112 + ); 113 + } 114 + } 115 + 116 + /// @nodoc 117 + @JsonSerializable() 118 + class _$DeleteFavoriteRequestImpl implements _DeleteFavoriteRequest { 119 + const _$DeleteFavoriteRequestImpl({required this.uri}); 120 + 121 + factory _$DeleteFavoriteRequestImpl.fromJson(Map<String, dynamic> json) => 122 + _$$DeleteFavoriteRequestImplFromJson(json); 123 + 124 + @override 125 + final String uri; 126 + 127 + @override 128 + String toString() { 129 + return 'DeleteFavoriteRequest(uri: $uri)'; 130 + } 131 + 132 + @override 133 + bool operator ==(Object other) { 134 + return identical(this, other) || 135 + (other.runtimeType == runtimeType && 136 + other is _$DeleteFavoriteRequestImpl && 137 + (identical(other.uri, uri) || other.uri == uri)); 138 + } 139 + 140 + @JsonKey(includeFromJson: false, includeToJson: false) 141 + @override 142 + int get hashCode => Object.hash(runtimeType, uri); 143 + 144 + /// Create a copy of DeleteFavoriteRequest 145 + /// with the given fields replaced by the non-null parameter values. 146 + @JsonKey(includeFromJson: false, includeToJson: false) 147 + @override 148 + @pragma('vm:prefer-inline') 149 + _$$DeleteFavoriteRequestImplCopyWith<_$DeleteFavoriteRequestImpl> 150 + get copyWith => 151 + __$$DeleteFavoriteRequestImplCopyWithImpl<_$DeleteFavoriteRequestImpl>( 152 + this, 153 + _$identity, 154 + ); 155 + 156 + @override 157 + Map<String, dynamic> toJson() { 158 + return _$$DeleteFavoriteRequestImplToJson(this); 159 + } 160 + } 161 + 162 + abstract class _DeleteFavoriteRequest implements DeleteFavoriteRequest { 163 + const factory _DeleteFavoriteRequest({required final String uri}) = 164 + _$DeleteFavoriteRequestImpl; 165 + 166 + factory _DeleteFavoriteRequest.fromJson(Map<String, dynamic> json) = 167 + _$DeleteFavoriteRequestImpl.fromJson; 168 + 169 + @override 170 + String get uri; 171 + 172 + /// Create a copy of DeleteFavoriteRequest 173 + /// with the given fields replaced by the non-null parameter values. 174 + @override 175 + @JsonKey(includeFromJson: false, includeToJson: false) 176 + _$$DeleteFavoriteRequestImplCopyWith<_$DeleteFavoriteRequestImpl> 177 + get copyWith => throw _privateConstructorUsedError; 178 + }
+15
lib/models/procedures/delete_favorite_request.g.dart
··· 1 + // GENERATED CODE - DO NOT MODIFY BY HAND 2 + 3 + part of 'delete_favorite_request.dart'; 4 + 5 + // ************************************************************************** 6 + // JsonSerializableGenerator 7 + // ************************************************************************** 8 + 9 + _$DeleteFavoriteRequestImpl _$$DeleteFavoriteRequestImplFromJson( 10 + Map<String, dynamic> json, 11 + ) => _$DeleteFavoriteRequestImpl(uri: json['uri'] as String); 12 + 13 + Map<String, dynamic> _$$DeleteFavoriteRequestImplToJson( 14 + _$DeleteFavoriteRequestImpl instance, 15 + ) => <String, dynamic>{'uri': instance.uri};
+14
lib/models/procedures/delete_favorite_response.dart
··· 1 + import 'package:freezed_annotation/freezed_annotation.dart'; 2 + 3 + part 'delete_favorite_response.freezed.dart'; 4 + part 'delete_favorite_response.g.dart'; 5 + 6 + /// Response model for deleting a favorite. 7 + /// See lexicon: social.grain.favorite.deleteFavorite 8 + @freezed 9 + class DeleteFavoriteResponse with _$DeleteFavoriteResponse { 10 + const factory DeleteFavoriteResponse({required bool success}) = _DeleteFavoriteResponse; 11 + 12 + factory DeleteFavoriteResponse.fromJson(Map<String, dynamic> json) => 13 + _$DeleteFavoriteResponseFromJson(json); 14 + }
+178
lib/models/procedures/delete_favorite_response.freezed.dart
··· 1 + // coverage:ignore-file 2 + // GENERATED CODE - DO NOT MODIFY BY HAND 3 + // ignore_for_file: type=lint 4 + // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark 5 + 6 + part of 'delete_favorite_response.dart'; 7 + 8 + // ************************************************************************** 9 + // FreezedGenerator 10 + // ************************************************************************** 11 + 12 + T _$identity<T>(T value) => value; 13 + 14 + final _privateConstructorUsedError = UnsupportedError( 15 + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', 16 + ); 17 + 18 + DeleteFavoriteResponse _$DeleteFavoriteResponseFromJson( 19 + Map<String, dynamic> json, 20 + ) { 21 + return _DeleteFavoriteResponse.fromJson(json); 22 + } 23 + 24 + /// @nodoc 25 + mixin _$DeleteFavoriteResponse { 26 + bool get success => throw _privateConstructorUsedError; 27 + 28 + /// Serializes this DeleteFavoriteResponse to a JSON map. 29 + Map<String, dynamic> toJson() => throw _privateConstructorUsedError; 30 + 31 + /// Create a copy of DeleteFavoriteResponse 32 + /// with the given fields replaced by the non-null parameter values. 33 + @JsonKey(includeFromJson: false, includeToJson: false) 34 + $DeleteFavoriteResponseCopyWith<DeleteFavoriteResponse> get copyWith => 35 + throw _privateConstructorUsedError; 36 + } 37 + 38 + /// @nodoc 39 + abstract class $DeleteFavoriteResponseCopyWith<$Res> { 40 + factory $DeleteFavoriteResponseCopyWith( 41 + DeleteFavoriteResponse value, 42 + $Res Function(DeleteFavoriteResponse) then, 43 + ) = _$DeleteFavoriteResponseCopyWithImpl<$Res, DeleteFavoriteResponse>; 44 + @useResult 45 + $Res call({bool success}); 46 + } 47 + 48 + /// @nodoc 49 + class _$DeleteFavoriteResponseCopyWithImpl< 50 + $Res, 51 + $Val extends DeleteFavoriteResponse 52 + > 53 + implements $DeleteFavoriteResponseCopyWith<$Res> { 54 + _$DeleteFavoriteResponseCopyWithImpl(this._value, this._then); 55 + 56 + // ignore: unused_field 57 + final $Val _value; 58 + // ignore: unused_field 59 + final $Res Function($Val) _then; 60 + 61 + /// Create a copy of DeleteFavoriteResponse 62 + /// with the given fields replaced by the non-null parameter values. 63 + @pragma('vm:prefer-inline') 64 + @override 65 + $Res call({Object? success = null}) { 66 + return _then( 67 + _value.copyWith( 68 + success: null == success 69 + ? _value.success 70 + : success // ignore: cast_nullable_to_non_nullable 71 + as bool, 72 + ) 73 + as $Val, 74 + ); 75 + } 76 + } 77 + 78 + /// @nodoc 79 + abstract class _$$DeleteFavoriteResponseImplCopyWith<$Res> 80 + implements $DeleteFavoriteResponseCopyWith<$Res> { 81 + factory _$$DeleteFavoriteResponseImplCopyWith( 82 + _$DeleteFavoriteResponseImpl value, 83 + $Res Function(_$DeleteFavoriteResponseImpl) then, 84 + ) = __$$DeleteFavoriteResponseImplCopyWithImpl<$Res>; 85 + @override 86 + @useResult 87 + $Res call({bool success}); 88 + } 89 + 90 + /// @nodoc 91 + class __$$DeleteFavoriteResponseImplCopyWithImpl<$Res> 92 + extends 93 + _$DeleteFavoriteResponseCopyWithImpl<$Res, _$DeleteFavoriteResponseImpl> 94 + implements _$$DeleteFavoriteResponseImplCopyWith<$Res> { 95 + __$$DeleteFavoriteResponseImplCopyWithImpl( 96 + _$DeleteFavoriteResponseImpl _value, 97 + $Res Function(_$DeleteFavoriteResponseImpl) _then, 98 + ) : super(_value, _then); 99 + 100 + /// Create a copy of DeleteFavoriteResponse 101 + /// with the given fields replaced by the non-null parameter values. 102 + @pragma('vm:prefer-inline') 103 + @override 104 + $Res call({Object? success = null}) { 105 + return _then( 106 + _$DeleteFavoriteResponseImpl( 107 + success: null == success 108 + ? _value.success 109 + : success // ignore: cast_nullable_to_non_nullable 110 + as bool, 111 + ), 112 + ); 113 + } 114 + } 115 + 116 + /// @nodoc 117 + @JsonSerializable() 118 + class _$DeleteFavoriteResponseImpl implements _DeleteFavoriteResponse { 119 + const _$DeleteFavoriteResponseImpl({required this.success}); 120 + 121 + factory _$DeleteFavoriteResponseImpl.fromJson(Map<String, dynamic> json) => 122 + _$$DeleteFavoriteResponseImplFromJson(json); 123 + 124 + @override 125 + final bool success; 126 + 127 + @override 128 + String toString() { 129 + return 'DeleteFavoriteResponse(success: $success)'; 130 + } 131 + 132 + @override 133 + bool operator ==(Object other) { 134 + return identical(this, other) || 135 + (other.runtimeType == runtimeType && 136 + other is _$DeleteFavoriteResponseImpl && 137 + (identical(other.success, success) || other.success == success)); 138 + } 139 + 140 + @JsonKey(includeFromJson: false, includeToJson: false) 141 + @override 142 + int get hashCode => Object.hash(runtimeType, success); 143 + 144 + /// Create a copy of DeleteFavoriteResponse 145 + /// with the given fields replaced by the non-null parameter values. 146 + @JsonKey(includeFromJson: false, includeToJson: false) 147 + @override 148 + @pragma('vm:prefer-inline') 149 + _$$DeleteFavoriteResponseImplCopyWith<_$DeleteFavoriteResponseImpl> 150 + get copyWith => 151 + __$$DeleteFavoriteResponseImplCopyWithImpl<_$DeleteFavoriteResponseImpl>( 152 + this, 153 + _$identity, 154 + ); 155 + 156 + @override 157 + Map<String, dynamic> toJson() { 158 + return _$$DeleteFavoriteResponseImplToJson(this); 159 + } 160 + } 161 + 162 + abstract class _DeleteFavoriteResponse implements DeleteFavoriteResponse { 163 + const factory _DeleteFavoriteResponse({required final bool success}) = 164 + _$DeleteFavoriteResponseImpl; 165 + 166 + factory _DeleteFavoriteResponse.fromJson(Map<String, dynamic> json) = 167 + _$DeleteFavoriteResponseImpl.fromJson; 168 + 169 + @override 170 + bool get success; 171 + 172 + /// Create a copy of DeleteFavoriteResponse 173 + /// with the given fields replaced by the non-null parameter values. 174 + @override 175 + @JsonKey(includeFromJson: false, includeToJson: false) 176 + _$$DeleteFavoriteResponseImplCopyWith<_$DeleteFavoriteResponseImpl> 177 + get copyWith => throw _privateConstructorUsedError; 178 + }
+15
lib/models/procedures/delete_favorite_response.g.dart
··· 1 + // GENERATED CODE - DO NOT MODIFY BY HAND 2 + 3 + part of 'delete_favorite_response.dart'; 4 + 5 + // ************************************************************************** 6 + // JsonSerializableGenerator 7 + // ************************************************************************** 8 + 9 + _$DeleteFavoriteResponseImpl _$$DeleteFavoriteResponseImplFromJson( 10 + Map<String, dynamic> json, 11 + ) => _$DeleteFavoriteResponseImpl(success: json['success'] as bool); 12 + 13 + Map<String, dynamic> _$$DeleteFavoriteResponseImplToJson( 14 + _$DeleteFavoriteResponseImpl instance, 15 + ) => <String, dynamic>{'success': instance.success};
+15
lib/models/procedures/delete_follow_request.dart
··· 1 + import 'package:freezed_annotation/freezed_annotation.dart'; 2 + 3 + part 'delete_follow_request.freezed.dart'; 4 + part 'delete_follow_request.g.dart'; 5 + 6 + /// Request model for deleting a follow relationship. 7 + /// 8 + /// [uri] - The URI of the follow relationship to delete. 9 + @freezed 10 + class DeleteFollowRequest with _$DeleteFollowRequest { 11 + const factory DeleteFollowRequest({required String uri}) = _DeleteFollowRequest; 12 + 13 + factory DeleteFollowRequest.fromJson(Map<String, dynamic> json) => 14 + _$DeleteFollowRequestFromJson(json); 15 + }
+171
lib/models/procedures/delete_follow_request.freezed.dart
··· 1 + // coverage:ignore-file 2 + // GENERATED CODE - DO NOT MODIFY BY HAND 3 + // ignore_for_file: type=lint 4 + // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark 5 + 6 + part of 'delete_follow_request.dart'; 7 + 8 + // ************************************************************************** 9 + // FreezedGenerator 10 + // ************************************************************************** 11 + 12 + T _$identity<T>(T value) => value; 13 + 14 + final _privateConstructorUsedError = UnsupportedError( 15 + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', 16 + ); 17 + 18 + DeleteFollowRequest _$DeleteFollowRequestFromJson(Map<String, dynamic> json) { 19 + return _DeleteFollowRequest.fromJson(json); 20 + } 21 + 22 + /// @nodoc 23 + mixin _$DeleteFollowRequest { 24 + String get uri => throw _privateConstructorUsedError; 25 + 26 + /// Serializes this DeleteFollowRequest to a JSON map. 27 + Map<String, dynamic> toJson() => throw _privateConstructorUsedError; 28 + 29 + /// Create a copy of DeleteFollowRequest 30 + /// with the given fields replaced by the non-null parameter values. 31 + @JsonKey(includeFromJson: false, includeToJson: false) 32 + $DeleteFollowRequestCopyWith<DeleteFollowRequest> get copyWith => 33 + throw _privateConstructorUsedError; 34 + } 35 + 36 + /// @nodoc 37 + abstract class $DeleteFollowRequestCopyWith<$Res> { 38 + factory $DeleteFollowRequestCopyWith( 39 + DeleteFollowRequest value, 40 + $Res Function(DeleteFollowRequest) then, 41 + ) = _$DeleteFollowRequestCopyWithImpl<$Res, DeleteFollowRequest>; 42 + @useResult 43 + $Res call({String uri}); 44 + } 45 + 46 + /// @nodoc 47 + class _$DeleteFollowRequestCopyWithImpl<$Res, $Val extends DeleteFollowRequest> 48 + implements $DeleteFollowRequestCopyWith<$Res> { 49 + _$DeleteFollowRequestCopyWithImpl(this._value, this._then); 50 + 51 + // ignore: unused_field 52 + final $Val _value; 53 + // ignore: unused_field 54 + final $Res Function($Val) _then; 55 + 56 + /// Create a copy of DeleteFollowRequest 57 + /// with the given fields replaced by the non-null parameter values. 58 + @pragma('vm:prefer-inline') 59 + @override 60 + $Res call({Object? uri = null}) { 61 + return _then( 62 + _value.copyWith( 63 + uri: null == uri 64 + ? _value.uri 65 + : uri // ignore: cast_nullable_to_non_nullable 66 + as String, 67 + ) 68 + as $Val, 69 + ); 70 + } 71 + } 72 + 73 + /// @nodoc 74 + abstract class _$$DeleteFollowRequestImplCopyWith<$Res> 75 + implements $DeleteFollowRequestCopyWith<$Res> { 76 + factory _$$DeleteFollowRequestImplCopyWith( 77 + _$DeleteFollowRequestImpl value, 78 + $Res Function(_$DeleteFollowRequestImpl) then, 79 + ) = __$$DeleteFollowRequestImplCopyWithImpl<$Res>; 80 + @override 81 + @useResult 82 + $Res call({String uri}); 83 + } 84 + 85 + /// @nodoc 86 + class __$$DeleteFollowRequestImplCopyWithImpl<$Res> 87 + extends _$DeleteFollowRequestCopyWithImpl<$Res, _$DeleteFollowRequestImpl> 88 + implements _$$DeleteFollowRequestImplCopyWith<$Res> { 89 + __$$DeleteFollowRequestImplCopyWithImpl( 90 + _$DeleteFollowRequestImpl _value, 91 + $Res Function(_$DeleteFollowRequestImpl) _then, 92 + ) : super(_value, _then); 93 + 94 + /// Create a copy of DeleteFollowRequest 95 + /// with the given fields replaced by the non-null parameter values. 96 + @pragma('vm:prefer-inline') 97 + @override 98 + $Res call({Object? uri = null}) { 99 + return _then( 100 + _$DeleteFollowRequestImpl( 101 + uri: null == uri 102 + ? _value.uri 103 + : uri // ignore: cast_nullable_to_non_nullable 104 + as String, 105 + ), 106 + ); 107 + } 108 + } 109 + 110 + /// @nodoc 111 + @JsonSerializable() 112 + class _$DeleteFollowRequestImpl implements _DeleteFollowRequest { 113 + const _$DeleteFollowRequestImpl({required this.uri}); 114 + 115 + factory _$DeleteFollowRequestImpl.fromJson(Map<String, dynamic> json) => 116 + _$$DeleteFollowRequestImplFromJson(json); 117 + 118 + @override 119 + final String uri; 120 + 121 + @override 122 + String toString() { 123 + return 'DeleteFollowRequest(uri: $uri)'; 124 + } 125 + 126 + @override 127 + bool operator ==(Object other) { 128 + return identical(this, other) || 129 + (other.runtimeType == runtimeType && 130 + other is _$DeleteFollowRequestImpl && 131 + (identical(other.uri, uri) || other.uri == uri)); 132 + } 133 + 134 + @JsonKey(includeFromJson: false, includeToJson: false) 135 + @override 136 + int get hashCode => Object.hash(runtimeType, uri); 137 + 138 + /// Create a copy of DeleteFollowRequest 139 + /// with the given fields replaced by the non-null parameter values. 140 + @JsonKey(includeFromJson: false, includeToJson: false) 141 + @override 142 + @pragma('vm:prefer-inline') 143 + _$$DeleteFollowRequestImplCopyWith<_$DeleteFollowRequestImpl> get copyWith => 144 + __$$DeleteFollowRequestImplCopyWithImpl<_$DeleteFollowRequestImpl>( 145 + this, 146 + _$identity, 147 + ); 148 + 149 + @override 150 + Map<String, dynamic> toJson() { 151 + return _$$DeleteFollowRequestImplToJson(this); 152 + } 153 + } 154 + 155 + abstract class _DeleteFollowRequest implements DeleteFollowRequest { 156 + const factory _DeleteFollowRequest({required final String uri}) = 157 + _$DeleteFollowRequestImpl; 158 + 159 + factory _DeleteFollowRequest.fromJson(Map<String, dynamic> json) = 160 + _$DeleteFollowRequestImpl.fromJson; 161 + 162 + @override 163 + String get uri; 164 + 165 + /// Create a copy of DeleteFollowRequest 166 + /// with the given fields replaced by the non-null parameter values. 167 + @override 168 + @JsonKey(includeFromJson: false, includeToJson: false) 169 + _$$DeleteFollowRequestImplCopyWith<_$DeleteFollowRequestImpl> get copyWith => 170 + throw _privateConstructorUsedError; 171 + }
+15
lib/models/procedures/delete_follow_request.g.dart
··· 1 + // GENERATED CODE - DO NOT MODIFY BY HAND 2 + 3 + part of 'delete_follow_request.dart'; 4 + 5 + // ************************************************************************** 6 + // JsonSerializableGenerator 7 + // ************************************************************************** 8 + 9 + _$DeleteFollowRequestImpl _$$DeleteFollowRequestImplFromJson( 10 + Map<String, dynamic> json, 11 + ) => _$DeleteFollowRequestImpl(uri: json['uri'] as String); 12 + 13 + Map<String, dynamic> _$$DeleteFollowRequestImplToJson( 14 + _$DeleteFollowRequestImpl instance, 15 + ) => <String, dynamic>{'uri': instance.uri};
+15
lib/models/procedures/delete_follow_response.dart
··· 1 + import 'package:freezed_annotation/freezed_annotation.dart'; 2 + 3 + part 'delete_follow_response.freezed.dart'; 4 + part 'delete_follow_response.g.dart'; 5 + 6 + /// Response model for deleting a follow relationship. 7 + /// 8 + /// [success] - Indicates if the deletion was successful. 9 + @freezed 10 + class DeleteFollowResponse with _$DeleteFollowResponse { 11 + const factory DeleteFollowResponse({required bool success}) = _DeleteFollowResponse; 12 + 13 + factory DeleteFollowResponse.fromJson(Map<String, dynamic> json) => 14 + _$DeleteFollowResponseFromJson(json); 15 + }
+175
lib/models/procedures/delete_follow_response.freezed.dart
··· 1 + // coverage:ignore-file 2 + // GENERATED CODE - DO NOT MODIFY BY HAND 3 + // ignore_for_file: type=lint 4 + // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark 5 + 6 + part of 'delete_follow_response.dart'; 7 + 8 + // ************************************************************************** 9 + // FreezedGenerator 10 + // ************************************************************************** 11 + 12 + T _$identity<T>(T value) => value; 13 + 14 + final _privateConstructorUsedError = UnsupportedError( 15 + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', 16 + ); 17 + 18 + DeleteFollowResponse _$DeleteFollowResponseFromJson(Map<String, dynamic> json) { 19 + return _DeleteFollowResponse.fromJson(json); 20 + } 21 + 22 + /// @nodoc 23 + mixin _$DeleteFollowResponse { 24 + bool get success => throw _privateConstructorUsedError; 25 + 26 + /// Serializes this DeleteFollowResponse to a JSON map. 27 + Map<String, dynamic> toJson() => throw _privateConstructorUsedError; 28 + 29 + /// Create a copy of DeleteFollowResponse 30 + /// with the given fields replaced by the non-null parameter values. 31 + @JsonKey(includeFromJson: false, includeToJson: false) 32 + $DeleteFollowResponseCopyWith<DeleteFollowResponse> get copyWith => 33 + throw _privateConstructorUsedError; 34 + } 35 + 36 + /// @nodoc 37 + abstract class $DeleteFollowResponseCopyWith<$Res> { 38 + factory $DeleteFollowResponseCopyWith( 39 + DeleteFollowResponse value, 40 + $Res Function(DeleteFollowResponse) then, 41 + ) = _$DeleteFollowResponseCopyWithImpl<$Res, DeleteFollowResponse>; 42 + @useResult 43 + $Res call({bool success}); 44 + } 45 + 46 + /// @nodoc 47 + class _$DeleteFollowResponseCopyWithImpl< 48 + $Res, 49 + $Val extends DeleteFollowResponse 50 + > 51 + implements $DeleteFollowResponseCopyWith<$Res> { 52 + _$DeleteFollowResponseCopyWithImpl(this._value, this._then); 53 + 54 + // ignore: unused_field 55 + final $Val _value; 56 + // ignore: unused_field 57 + final $Res Function($Val) _then; 58 + 59 + /// Create a copy of DeleteFollowResponse 60 + /// with the given fields replaced by the non-null parameter values. 61 + @pragma('vm:prefer-inline') 62 + @override 63 + $Res call({Object? success = null}) { 64 + return _then( 65 + _value.copyWith( 66 + success: null == success 67 + ? _value.success 68 + : success // ignore: cast_nullable_to_non_nullable 69 + as bool, 70 + ) 71 + as $Val, 72 + ); 73 + } 74 + } 75 + 76 + /// @nodoc 77 + abstract class _$$DeleteFollowResponseImplCopyWith<$Res> 78 + implements $DeleteFollowResponseCopyWith<$Res> { 79 + factory _$$DeleteFollowResponseImplCopyWith( 80 + _$DeleteFollowResponseImpl value, 81 + $Res Function(_$DeleteFollowResponseImpl) then, 82 + ) = __$$DeleteFollowResponseImplCopyWithImpl<$Res>; 83 + @override 84 + @useResult 85 + $Res call({bool success}); 86 + } 87 + 88 + /// @nodoc 89 + class __$$DeleteFollowResponseImplCopyWithImpl<$Res> 90 + extends _$DeleteFollowResponseCopyWithImpl<$Res, _$DeleteFollowResponseImpl> 91 + implements _$$DeleteFollowResponseImplCopyWith<$Res> { 92 + __$$DeleteFollowResponseImplCopyWithImpl( 93 + _$DeleteFollowResponseImpl _value, 94 + $Res Function(_$DeleteFollowResponseImpl) _then, 95 + ) : super(_value, _then); 96 + 97 + /// Create a copy of DeleteFollowResponse 98 + /// with the given fields replaced by the non-null parameter values. 99 + @pragma('vm:prefer-inline') 100 + @override 101 + $Res call({Object? success = null}) { 102 + return _then( 103 + _$DeleteFollowResponseImpl( 104 + success: null == success 105 + ? _value.success 106 + : success // ignore: cast_nullable_to_non_nullable 107 + as bool, 108 + ), 109 + ); 110 + } 111 + } 112 + 113 + /// @nodoc 114 + @JsonSerializable() 115 + class _$DeleteFollowResponseImpl implements _DeleteFollowResponse { 116 + const _$DeleteFollowResponseImpl({required this.success}); 117 + 118 + factory _$DeleteFollowResponseImpl.fromJson(Map<String, dynamic> json) => 119 + _$$DeleteFollowResponseImplFromJson(json); 120 + 121 + @override 122 + final bool success; 123 + 124 + @override 125 + String toString() { 126 + return 'DeleteFollowResponse(success: $success)'; 127 + } 128 + 129 + @override 130 + bool operator ==(Object other) { 131 + return identical(this, other) || 132 + (other.runtimeType == runtimeType && 133 + other is _$DeleteFollowResponseImpl && 134 + (identical(other.success, success) || other.success == success)); 135 + } 136 + 137 + @JsonKey(includeFromJson: false, includeToJson: false) 138 + @override 139 + int get hashCode => Object.hash(runtimeType, success); 140 + 141 + /// Create a copy of DeleteFollowResponse 142 + /// with the given fields replaced by the non-null parameter values. 143 + @JsonKey(includeFromJson: false, includeToJson: false) 144 + @override 145 + @pragma('vm:prefer-inline') 146 + _$$DeleteFollowResponseImplCopyWith<_$DeleteFollowResponseImpl> 147 + get copyWith => 148 + __$$DeleteFollowResponseImplCopyWithImpl<_$DeleteFollowResponseImpl>( 149 + this, 150 + _$identity, 151 + ); 152 + 153 + @override 154 + Map<String, dynamic> toJson() { 155 + return _$$DeleteFollowResponseImplToJson(this); 156 + } 157 + } 158 + 159 + abstract class _DeleteFollowResponse implements DeleteFollowResponse { 160 + const factory _DeleteFollowResponse({required final bool success}) = 161 + _$DeleteFollowResponseImpl; 162 + 163 + factory _DeleteFollowResponse.fromJson(Map<String, dynamic> json) = 164 + _$DeleteFollowResponseImpl.fromJson; 165 + 166 + @override 167 + bool get success; 168 + 169 + /// Create a copy of DeleteFollowResponse 170 + /// with the given fields replaced by the non-null parameter values. 171 + @override 172 + @JsonKey(includeFromJson: false, includeToJson: false) 173 + _$$DeleteFollowResponseImplCopyWith<_$DeleteFollowResponseImpl> 174 + get copyWith => throw _privateConstructorUsedError; 175 + }
+15
lib/models/procedures/delete_follow_response.g.dart
··· 1 + // GENERATED CODE - DO NOT MODIFY BY HAND 2 + 3 + part of 'delete_follow_response.dart'; 4 + 5 + // ************************************************************************** 6 + // JsonSerializableGenerator 7 + // ************************************************************************** 8 + 9 + _$DeleteFollowResponseImpl _$$DeleteFollowResponseImplFromJson( 10 + Map<String, dynamic> json, 11 + ) => _$DeleteFollowResponseImpl(success: json['success'] as bool); 12 + 13 + Map<String, dynamic> _$$DeleteFollowResponseImplToJson( 14 + _$DeleteFollowResponseImpl instance, 15 + ) => <String, dynamic>{'success': instance.success};
+14
lib/models/procedures/delete_photo_request.dart
··· 1 + import 'package:freezed_annotation/freezed_annotation.dart'; 2 + 3 + part 'delete_photo_request.freezed.dart'; 4 + part 'delete_photo_request.g.dart'; 5 + 6 + /// Request model for deleting a photo. 7 + /// See lexicon: social.grain.photo.deletePhoto 8 + @freezed 9 + class DeletePhotoRequest with _$DeletePhotoRequest { 10 + const factory DeletePhotoRequest({required String uri}) = _DeletePhotoRequest; 11 + 12 + factory DeletePhotoRequest.fromJson(Map<String, dynamic> json) => 13 + _$DeletePhotoRequestFromJson(json); 14 + }
+171
lib/models/procedures/delete_photo_request.freezed.dart
··· 1 + // coverage:ignore-file 2 + // GENERATED CODE - DO NOT MODIFY BY HAND 3 + // ignore_for_file: type=lint 4 + // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark 5 + 6 + part of 'delete_photo_request.dart'; 7 + 8 + // ************************************************************************** 9 + // FreezedGenerator 10 + // ************************************************************************** 11 + 12 + T _$identity<T>(T value) => value; 13 + 14 + final _privateConstructorUsedError = UnsupportedError( 15 + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', 16 + ); 17 + 18 + DeletePhotoRequest _$DeletePhotoRequestFromJson(Map<String, dynamic> json) { 19 + return _DeletePhotoRequest.fromJson(json); 20 + } 21 + 22 + /// @nodoc 23 + mixin _$DeletePhotoRequest { 24 + String get uri => throw _privateConstructorUsedError; 25 + 26 + /// Serializes this DeletePhotoRequest to a JSON map. 27 + Map<String, dynamic> toJson() => throw _privateConstructorUsedError; 28 + 29 + /// Create a copy of DeletePhotoRequest 30 + /// with the given fields replaced by the non-null parameter values. 31 + @JsonKey(includeFromJson: false, includeToJson: false) 32 + $DeletePhotoRequestCopyWith<DeletePhotoRequest> get copyWith => 33 + throw _privateConstructorUsedError; 34 + } 35 + 36 + /// @nodoc 37 + abstract class $DeletePhotoRequestCopyWith<$Res> { 38 + factory $DeletePhotoRequestCopyWith( 39 + DeletePhotoRequest value, 40 + $Res Function(DeletePhotoRequest) then, 41 + ) = _$DeletePhotoRequestCopyWithImpl<$Res, DeletePhotoRequest>; 42 + @useResult 43 + $Res call({String uri}); 44 + } 45 + 46 + /// @nodoc 47 + class _$DeletePhotoRequestCopyWithImpl<$Res, $Val extends DeletePhotoRequest> 48 + implements $DeletePhotoRequestCopyWith<$Res> { 49 + _$DeletePhotoRequestCopyWithImpl(this._value, this._then); 50 + 51 + // ignore: unused_field 52 + final $Val _value; 53 + // ignore: unused_field 54 + final $Res Function($Val) _then; 55 + 56 + /// Create a copy of DeletePhotoRequest 57 + /// with the given fields replaced by the non-null parameter values. 58 + @pragma('vm:prefer-inline') 59 + @override 60 + $Res call({Object? uri = null}) { 61 + return _then( 62 + _value.copyWith( 63 + uri: null == uri 64 + ? _value.uri 65 + : uri // ignore: cast_nullable_to_non_nullable 66 + as String, 67 + ) 68 + as $Val, 69 + ); 70 + } 71 + } 72 + 73 + /// @nodoc 74 + abstract class _$$DeletePhotoRequestImplCopyWith<$Res> 75 + implements $DeletePhotoRequestCopyWith<$Res> { 76 + factory _$$DeletePhotoRequestImplCopyWith( 77 + _$DeletePhotoRequestImpl value, 78 + $Res Function(_$DeletePhotoRequestImpl) then, 79 + ) = __$$DeletePhotoRequestImplCopyWithImpl<$Res>; 80 + @override 81 + @useResult 82 + $Res call({String uri}); 83 + } 84 + 85 + /// @nodoc 86 + class __$$DeletePhotoRequestImplCopyWithImpl<$Res> 87 + extends _$DeletePhotoRequestCopyWithImpl<$Res, _$DeletePhotoRequestImpl> 88 + implements _$$DeletePhotoRequestImplCopyWith<$Res> { 89 + __$$DeletePhotoRequestImplCopyWithImpl( 90 + _$DeletePhotoRequestImpl _value, 91 + $Res Function(_$DeletePhotoRequestImpl) _then, 92 + ) : super(_value, _then); 93 + 94 + /// Create a copy of DeletePhotoRequest 95 + /// with the given fields replaced by the non-null parameter values. 96 + @pragma('vm:prefer-inline') 97 + @override 98 + $Res call({Object? uri = null}) { 99 + return _then( 100 + _$DeletePhotoRequestImpl( 101 + uri: null == uri 102 + ? _value.uri 103 + : uri // ignore: cast_nullable_to_non_nullable 104 + as String, 105 + ), 106 + ); 107 + } 108 + } 109 + 110 + /// @nodoc 111 + @JsonSerializable() 112 + class _$DeletePhotoRequestImpl implements _DeletePhotoRequest { 113 + const _$DeletePhotoRequestImpl({required this.uri}); 114 + 115 + factory _$DeletePhotoRequestImpl.fromJson(Map<String, dynamic> json) => 116 + _$$DeletePhotoRequestImplFromJson(json); 117 + 118 + @override 119 + final String uri; 120 + 121 + @override 122 + String toString() { 123 + return 'DeletePhotoRequest(uri: $uri)'; 124 + } 125 + 126 + @override 127 + bool operator ==(Object other) { 128 + return identical(this, other) || 129 + (other.runtimeType == runtimeType && 130 + other is _$DeletePhotoRequestImpl && 131 + (identical(other.uri, uri) || other.uri == uri)); 132 + } 133 + 134 + @JsonKey(includeFromJson: false, includeToJson: false) 135 + @override 136 + int get hashCode => Object.hash(runtimeType, uri); 137 + 138 + /// Create a copy of DeletePhotoRequest 139 + /// with the given fields replaced by the non-null parameter values. 140 + @JsonKey(includeFromJson: false, includeToJson: false) 141 + @override 142 + @pragma('vm:prefer-inline') 143 + _$$DeletePhotoRequestImplCopyWith<_$DeletePhotoRequestImpl> get copyWith => 144 + __$$DeletePhotoRequestImplCopyWithImpl<_$DeletePhotoRequestImpl>( 145 + this, 146 + _$identity, 147 + ); 148 + 149 + @override 150 + Map<String, dynamic> toJson() { 151 + return _$$DeletePhotoRequestImplToJson(this); 152 + } 153 + } 154 + 155 + abstract class _DeletePhotoRequest implements DeletePhotoRequest { 156 + const factory _DeletePhotoRequest({required final String uri}) = 157 + _$DeletePhotoRequestImpl; 158 + 159 + factory _DeletePhotoRequest.fromJson(Map<String, dynamic> json) = 160 + _$DeletePhotoRequestImpl.fromJson; 161 + 162 + @override 163 + String get uri; 164 + 165 + /// Create a copy of DeletePhotoRequest 166 + /// with the given fields replaced by the non-null parameter values. 167 + @override 168 + @JsonKey(includeFromJson: false, includeToJson: false) 169 + _$$DeletePhotoRequestImplCopyWith<_$DeletePhotoRequestImpl> get copyWith => 170 + throw _privateConstructorUsedError; 171 + }
+15
lib/models/procedures/delete_photo_request.g.dart
··· 1 + // GENERATED CODE - DO NOT MODIFY BY HAND 2 + 3 + part of 'delete_photo_request.dart'; 4 + 5 + // ************************************************************************** 6 + // JsonSerializableGenerator 7 + // ************************************************************************** 8 + 9 + _$DeletePhotoRequestImpl _$$DeletePhotoRequestImplFromJson( 10 + Map<String, dynamic> json, 11 + ) => _$DeletePhotoRequestImpl(uri: json['uri'] as String); 12 + 13 + Map<String, dynamic> _$$DeletePhotoRequestImplToJson( 14 + _$DeletePhotoRequestImpl instance, 15 + ) => <String, dynamic>{'uri': instance.uri};
+14
lib/models/procedures/delete_photo_response.dart
··· 1 + import 'package:freezed_annotation/freezed_annotation.dart'; 2 + 3 + part 'delete_photo_response.freezed.dart'; 4 + part 'delete_photo_response.g.dart'; 5 + 6 + /// Response model for deleting a photo. 7 + /// See lexicon: social.grain.photo.deletePhoto 8 + @freezed 9 + class DeletePhotoResponse with _$DeletePhotoResponse { 10 + const factory DeletePhotoResponse({required bool success}) = _DeletePhotoResponse; 11 + 12 + factory DeletePhotoResponse.fromJson(Map<String, dynamic> json) => 13 + _$DeletePhotoResponseFromJson(json); 14 + }
+171
lib/models/procedures/delete_photo_response.freezed.dart
··· 1 + // coverage:ignore-file 2 + // GENERATED CODE - DO NOT MODIFY BY HAND 3 + // ignore_for_file: type=lint 4 + // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark 5 + 6 + part of 'delete_photo_response.dart'; 7 + 8 + // ************************************************************************** 9 + // FreezedGenerator 10 + // ************************************************************************** 11 + 12 + T _$identity<T>(T value) => value; 13 + 14 + final _privateConstructorUsedError = UnsupportedError( 15 + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', 16 + ); 17 + 18 + DeletePhotoResponse _$DeletePhotoResponseFromJson(Map<String, dynamic> json) { 19 + return _DeletePhotoResponse.fromJson(json); 20 + } 21 + 22 + /// @nodoc 23 + mixin _$DeletePhotoResponse { 24 + bool get success => throw _privateConstructorUsedError; 25 + 26 + /// Serializes this DeletePhotoResponse to a JSON map. 27 + Map<String, dynamic> toJson() => throw _privateConstructorUsedError; 28 + 29 + /// Create a copy of DeletePhotoResponse 30 + /// with the given fields replaced by the non-null parameter values. 31 + @JsonKey(includeFromJson: false, includeToJson: false) 32 + $DeletePhotoResponseCopyWith<DeletePhotoResponse> get copyWith => 33 + throw _privateConstructorUsedError; 34 + } 35 + 36 + /// @nodoc 37 + abstract class $DeletePhotoResponseCopyWith<$Res> { 38 + factory $DeletePhotoResponseCopyWith( 39 + DeletePhotoResponse value, 40 + $Res Function(DeletePhotoResponse) then, 41 + ) = _$DeletePhotoResponseCopyWithImpl<$Res, DeletePhotoResponse>; 42 + @useResult 43 + $Res call({bool success}); 44 + } 45 + 46 + /// @nodoc 47 + class _$DeletePhotoResponseCopyWithImpl<$Res, $Val extends DeletePhotoResponse> 48 + implements $DeletePhotoResponseCopyWith<$Res> { 49 + _$DeletePhotoResponseCopyWithImpl(this._value, this._then); 50 + 51 + // ignore: unused_field 52 + final $Val _value; 53 + // ignore: unused_field 54 + final $Res Function($Val) _then; 55 + 56 + /// Create a copy of DeletePhotoResponse 57 + /// with the given fields replaced by the non-null parameter values. 58 + @pragma('vm:prefer-inline') 59 + @override 60 + $Res call({Object? success = null}) { 61 + return _then( 62 + _value.copyWith( 63 + success: null == success 64 + ? _value.success 65 + : success // ignore: cast_nullable_to_non_nullable 66 + as bool, 67 + ) 68 + as $Val, 69 + ); 70 + } 71 + } 72 + 73 + /// @nodoc 74 + abstract class _$$DeletePhotoResponseImplCopyWith<$Res> 75 + implements $DeletePhotoResponseCopyWith<$Res> { 76 + factory _$$DeletePhotoResponseImplCopyWith( 77 + _$DeletePhotoResponseImpl value, 78 + $Res Function(_$DeletePhotoResponseImpl) then, 79 + ) = __$$DeletePhotoResponseImplCopyWithImpl<$Res>; 80 + @override 81 + @useResult 82 + $Res call({bool success}); 83 + } 84 + 85 + /// @nodoc 86 + class __$$DeletePhotoResponseImplCopyWithImpl<$Res> 87 + extends _$DeletePhotoResponseCopyWithImpl<$Res, _$DeletePhotoResponseImpl> 88 + implements _$$DeletePhotoResponseImplCopyWith<$Res> { 89 + __$$DeletePhotoResponseImplCopyWithImpl( 90 + _$DeletePhotoResponseImpl _value, 91 + $Res Function(_$DeletePhotoResponseImpl) _then, 92 + ) : super(_value, _then); 93 + 94 + /// Create a copy of DeletePhotoResponse 95 + /// with the given fields replaced by the non-null parameter values. 96 + @pragma('vm:prefer-inline') 97 + @override 98 + $Res call({Object? success = null}) { 99 + return _then( 100 + _$DeletePhotoResponseImpl( 101 + success: null == success 102 + ? _value.success 103 + : success // ignore: cast_nullable_to_non_nullable 104 + as bool, 105 + ), 106 + ); 107 + } 108 + } 109 + 110 + /// @nodoc 111 + @JsonSerializable() 112 + class _$DeletePhotoResponseImpl implements _DeletePhotoResponse { 113 + const _$DeletePhotoResponseImpl({required this.success}); 114 + 115 + factory _$DeletePhotoResponseImpl.fromJson(Map<String, dynamic> json) => 116 + _$$DeletePhotoResponseImplFromJson(json); 117 + 118 + @override 119 + final bool success; 120 + 121 + @override 122 + String toString() { 123 + return 'DeletePhotoResponse(success: $success)'; 124 + } 125 + 126 + @override 127 + bool operator ==(Object other) { 128 + return identical(this, other) || 129 + (other.runtimeType == runtimeType && 130 + other is _$DeletePhotoResponseImpl && 131 + (identical(other.success, success) || other.success == success)); 132 + } 133 + 134 + @JsonKey(includeFromJson: false, includeToJson: false) 135 + @override 136 + int get hashCode => Object.hash(runtimeType, success); 137 + 138 + /// Create a copy of DeletePhotoResponse 139 + /// with the given fields replaced by the non-null parameter values. 140 + @JsonKey(includeFromJson: false, includeToJson: false) 141 + @override 142 + @pragma('vm:prefer-inline') 143 + _$$DeletePhotoResponseImplCopyWith<_$DeletePhotoResponseImpl> get copyWith => 144 + __$$DeletePhotoResponseImplCopyWithImpl<_$DeletePhotoResponseImpl>( 145 + this, 146 + _$identity, 147 + ); 148 + 149 + @override 150 + Map<String, dynamic> toJson() { 151 + return _$$DeletePhotoResponseImplToJson(this); 152 + } 153 + } 154 + 155 + abstract class _DeletePhotoResponse implements DeletePhotoResponse { 156 + const factory _DeletePhotoResponse({required final bool success}) = 157 + _$DeletePhotoResponseImpl; 158 + 159 + factory _DeletePhotoResponse.fromJson(Map<String, dynamic> json) = 160 + _$DeletePhotoResponseImpl.fromJson; 161 + 162 + @override 163 + bool get success; 164 + 165 + /// Create a copy of DeletePhotoResponse 166 + /// with the given fields replaced by the non-null parameter values. 167 + @override 168 + @JsonKey(includeFromJson: false, includeToJson: false) 169 + _$$DeletePhotoResponseImplCopyWith<_$DeletePhotoResponseImpl> get copyWith => 170 + throw _privateConstructorUsedError; 171 + }
+15
lib/models/procedures/delete_photo_response.g.dart
··· 1 + // GENERATED CODE - DO NOT MODIFY BY HAND 2 + 3 + part of 'delete_photo_response.dart'; 4 + 5 + // ************************************************************************** 6 + // JsonSerializableGenerator 7 + // ************************************************************************** 8 + 9 + _$DeletePhotoResponseImpl _$$DeletePhotoResponseImplFromJson( 10 + Map<String, dynamic> json, 11 + ) => _$DeletePhotoResponseImpl(success: json['success'] as bool); 12 + 13 + Map<String, dynamic> _$$DeletePhotoResponseImplToJson( 14 + _$DeletePhotoResponseImpl instance, 15 + ) => <String, dynamic>{'success': instance.success};
+34
lib/models/procedures/procedures.dart
··· 1 + export 'apply_alts_request.dart'; 2 + export 'apply_alts_response.dart'; 3 + export 'apply_sort_request.dart'; 4 + export 'apply_sort_response.dart'; 5 + export 'create_comment_request.dart'; 6 + export 'create_comment_response.dart'; 7 + export 'create_exif_request.dart'; 8 + export 'create_exif_response.dart'; 9 + export 'create_favorite_request.dart'; 10 + export 'create_favorite_response.dart'; 11 + export 'create_follow_request.dart'; 12 + export 'create_follow_response.dart'; 13 + export 'create_gallery_item_request.dart'; 14 + export 'create_gallery_item_response.dart'; 15 + export 'create_gallery_request.dart'; 16 + export 'create_gallery_response.dart'; 17 + export 'delete_comment_request.dart'; 18 + export 'delete_comment_response.dart'; 19 + export 'delete_favorite_request.dart'; 20 + export 'delete_favorite_response.dart'; 21 + export 'delete_follow_request.dart'; 22 + export 'delete_follow_response.dart'; 23 + export 'delete_gallery_item_request.dart'; 24 + export 'delete_gallery_item_response.dart'; 25 + export 'delete_gallery_request.dart'; 26 + export 'delete_gallery_response.dart'; 27 + export 'delete_photo_request.dart'; 28 + export 'delete_photo_response.dart'; 29 + export 'update_avatar_response.dart'; 30 + export 'update_gallery_request.dart'; 31 + export 'update_gallery_response.dart'; 32 + export 'update_profile_request.dart'; 33 + export 'update_profile_response.dart'; 34 + export 'upload_photo_response.dart';
+15
lib/models/procedures/update_avatar_response.dart
··· 1 + import 'package:freezed_annotation/freezed_annotation.dart'; 2 + 3 + part 'update_avatar_response.freezed.dart'; 4 + part 'update_avatar_response.g.dart'; 5 + 6 + /// Response model for updating an actor's avatar image. 7 + /// 8 + /// [success] - Indicates if the update was successful. 9 + @freezed 10 + class UpdateAvatarResponse with _$UpdateAvatarResponse { 11 + const factory UpdateAvatarResponse({required bool success}) = _UpdateAvatarResponse; 12 + 13 + factory UpdateAvatarResponse.fromJson(Map<String, dynamic> json) => 14 + _$UpdateAvatarResponseFromJson(json); 15 + }
+175
lib/models/procedures/update_avatar_response.freezed.dart
··· 1 + // coverage:ignore-file 2 + // GENERATED CODE - DO NOT MODIFY BY HAND 3 + // ignore_for_file: type=lint 4 + // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark 5 + 6 + part of 'update_avatar_response.dart'; 7 + 8 + // ************************************************************************** 9 + // FreezedGenerator 10 + // ************************************************************************** 11 + 12 + T _$identity<T>(T value) => value; 13 + 14 + final _privateConstructorUsedError = UnsupportedError( 15 + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', 16 + ); 17 + 18 + UpdateAvatarResponse _$UpdateAvatarResponseFromJson(Map<String, dynamic> json) { 19 + return _UpdateAvatarResponse.fromJson(json); 20 + } 21 + 22 + /// @nodoc 23 + mixin _$UpdateAvatarResponse { 24 + bool get success => throw _privateConstructorUsedError; 25 + 26 + /// Serializes this UpdateAvatarResponse to a JSON map. 27 + Map<String, dynamic> toJson() => throw _privateConstructorUsedError; 28 + 29 + /// Create a copy of UpdateAvatarResponse 30 + /// with the given fields replaced by the non-null parameter values. 31 + @JsonKey(includeFromJson: false, includeToJson: false) 32 + $UpdateAvatarResponseCopyWith<UpdateAvatarResponse> get copyWith => 33 + throw _privateConstructorUsedError; 34 + } 35 + 36 + /// @nodoc 37 + abstract class $UpdateAvatarResponseCopyWith<$Res> { 38 + factory $UpdateAvatarResponseCopyWith( 39 + UpdateAvatarResponse value, 40 + $Res Function(UpdateAvatarResponse) then, 41 + ) = _$UpdateAvatarResponseCopyWithImpl<$Res, UpdateAvatarResponse>; 42 + @useResult 43 + $Res call({bool success}); 44 + } 45 + 46 + /// @nodoc 47 + class _$UpdateAvatarResponseCopyWithImpl< 48 + $Res, 49 + $Val extends UpdateAvatarResponse 50 + > 51 + implements $UpdateAvatarResponseCopyWith<$Res> { 52 + _$UpdateAvatarResponseCopyWithImpl(this._value, this._then); 53 + 54 + // ignore: unused_field 55 + final $Val _value; 56 + // ignore: unused_field 57 + final $Res Function($Val) _then; 58 + 59 + /// Create a copy of UpdateAvatarResponse 60 + /// with the given fields replaced by the non-null parameter values. 61 + @pragma('vm:prefer-inline') 62 + @override 63 + $Res call({Object? success = null}) { 64 + return _then( 65 + _value.copyWith( 66 + success: null == success 67 + ? _value.success 68 + : success // ignore: cast_nullable_to_non_nullable 69 + as bool, 70 + ) 71 + as $Val, 72 + ); 73 + } 74 + } 75 + 76 + /// @nodoc 77 + abstract class _$$UpdateAvatarResponseImplCopyWith<$Res> 78 + implements $UpdateAvatarResponseCopyWith<$Res> { 79 + factory _$$UpdateAvatarResponseImplCopyWith( 80 + _$UpdateAvatarResponseImpl value, 81 + $Res Function(_$UpdateAvatarResponseImpl) then, 82 + ) = __$$UpdateAvatarResponseImplCopyWithImpl<$Res>; 83 + @override 84 + @useResult 85 + $Res call({bool success}); 86 + } 87 + 88 + /// @nodoc 89 + class __$$UpdateAvatarResponseImplCopyWithImpl<$Res> 90 + extends _$UpdateAvatarResponseCopyWithImpl<$Res, _$UpdateAvatarResponseImpl> 91 + implements _$$UpdateAvatarResponseImplCopyWith<$Res> { 92 + __$$UpdateAvatarResponseImplCopyWithImpl( 93 + _$UpdateAvatarResponseImpl _value, 94 + $Res Function(_$UpdateAvatarResponseImpl) _then, 95 + ) : super(_value, _then); 96 + 97 + /// Create a copy of UpdateAvatarResponse 98 + /// with the given fields replaced by the non-null parameter values. 99 + @pragma('vm:prefer-inline') 100 + @override 101 + $Res call({Object? success = null}) { 102 + return _then( 103 + _$UpdateAvatarResponseImpl( 104 + success: null == success 105 + ? _value.success 106 + : success // ignore: cast_nullable_to_non_nullable 107 + as bool, 108 + ), 109 + ); 110 + } 111 + } 112 + 113 + /// @nodoc 114 + @JsonSerializable() 115 + class _$UpdateAvatarResponseImpl implements _UpdateAvatarResponse { 116 + const _$UpdateAvatarResponseImpl({required this.success}); 117 + 118 + factory _$UpdateAvatarResponseImpl.fromJson(Map<String, dynamic> json) => 119 + _$$UpdateAvatarResponseImplFromJson(json); 120 + 121 + @override 122 + final bool success; 123 + 124 + @override 125 + String toString() { 126 + return 'UpdateAvatarResponse(success: $success)'; 127 + } 128 + 129 + @override 130 + bool operator ==(Object other) { 131 + return identical(this, other) || 132 + (other.runtimeType == runtimeType && 133 + other is _$UpdateAvatarResponseImpl && 134 + (identical(other.success, success) || other.success == success)); 135 + } 136 + 137 + @JsonKey(includeFromJson: false, includeToJson: false) 138 + @override 139 + int get hashCode => Object.hash(runtimeType, success); 140 + 141 + /// Create a copy of UpdateAvatarResponse 142 + /// with the given fields replaced by the non-null parameter values. 143 + @JsonKey(includeFromJson: false, includeToJson: false) 144 + @override 145 + @pragma('vm:prefer-inline') 146 + _$$UpdateAvatarResponseImplCopyWith<_$UpdateAvatarResponseImpl> 147 + get copyWith => 148 + __$$UpdateAvatarResponseImplCopyWithImpl<_$UpdateAvatarResponseImpl>( 149 + this, 150 + _$identity, 151 + ); 152 + 153 + @override 154 + Map<String, dynamic> toJson() { 155 + return _$$UpdateAvatarResponseImplToJson(this); 156 + } 157 + } 158 + 159 + abstract class _UpdateAvatarResponse implements UpdateAvatarResponse { 160 + const factory _UpdateAvatarResponse({required final bool success}) = 161 + _$UpdateAvatarResponseImpl; 162 + 163 + factory _UpdateAvatarResponse.fromJson(Map<String, dynamic> json) = 164 + _$UpdateAvatarResponseImpl.fromJson; 165 + 166 + @override 167 + bool get success; 168 + 169 + /// Create a copy of UpdateAvatarResponse 170 + /// with the given fields replaced by the non-null parameter values. 171 + @override 172 + @JsonKey(includeFromJson: false, includeToJson: false) 173 + _$$UpdateAvatarResponseImplCopyWith<_$UpdateAvatarResponseImpl> 174 + get copyWith => throw _privateConstructorUsedError; 175 + }
+15
lib/models/procedures/update_avatar_response.g.dart
··· 1 + // GENERATED CODE - DO NOT MODIFY BY HAND 2 + 3 + part of 'update_avatar_response.dart'; 4 + 5 + // ************************************************************************** 6 + // JsonSerializableGenerator 7 + // ************************************************************************** 8 + 9 + _$UpdateAvatarResponseImpl _$$UpdateAvatarResponseImplFromJson( 10 + Map<String, dynamic> json, 11 + ) => _$UpdateAvatarResponseImpl(success: json['success'] as bool); 12 + 13 + Map<String, dynamic> _$$UpdateAvatarResponseImplToJson( 14 + _$UpdateAvatarResponseImpl instance, 15 + ) => <String, dynamic>{'success': instance.success};
+17
lib/models/procedures/update_profile_request.dart
··· 1 + import 'package:freezed_annotation/freezed_annotation.dart'; 2 + 3 + part 'update_profile_request.freezed.dart'; 4 + part 'update_profile_request.g.dart'; 5 + 6 + /// Request model for updating an actor's profile information. 7 + /// 8 + /// [displayName] - The display name (optional). 9 + /// [description] - The profile description (optional). 10 + @freezed 11 + class UpdateProfileRequest with _$UpdateProfileRequest { 12 + const factory UpdateProfileRequest({String? displayName, String? description}) = 13 + _UpdateProfileRequest; 14 + 15 + factory UpdateProfileRequest.fromJson(Map<String, dynamic> json) => 16 + _$UpdateProfileRequestFromJson(json); 17 + }
+193
lib/models/procedures/update_profile_request.freezed.dart
··· 1 + // coverage:ignore-file 2 + // GENERATED CODE - DO NOT MODIFY BY HAND 3 + // ignore_for_file: type=lint 4 + // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark 5 + 6 + part of 'update_profile_request.dart'; 7 + 8 + // ************************************************************************** 9 + // FreezedGenerator 10 + // ************************************************************************** 11 + 12 + T _$identity<T>(T value) => value; 13 + 14 + final _privateConstructorUsedError = UnsupportedError( 15 + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', 16 + ); 17 + 18 + UpdateProfileRequest _$UpdateProfileRequestFromJson(Map<String, dynamic> json) { 19 + return _UpdateProfileRequest.fromJson(json); 20 + } 21 + 22 + /// @nodoc 23 + mixin _$UpdateProfileRequest { 24 + String? get displayName => throw _privateConstructorUsedError; 25 + String? get description => throw _privateConstructorUsedError; 26 + 27 + /// Serializes this UpdateProfileRequest to a JSON map. 28 + Map<String, dynamic> toJson() => throw _privateConstructorUsedError; 29 + 30 + /// Create a copy of UpdateProfileRequest 31 + /// with the given fields replaced by the non-null parameter values. 32 + @JsonKey(includeFromJson: false, includeToJson: false) 33 + $UpdateProfileRequestCopyWith<UpdateProfileRequest> get copyWith => 34 + throw _privateConstructorUsedError; 35 + } 36 + 37 + /// @nodoc 38 + abstract class $UpdateProfileRequestCopyWith<$Res> { 39 + factory $UpdateProfileRequestCopyWith( 40 + UpdateProfileRequest value, 41 + $Res Function(UpdateProfileRequest) then, 42 + ) = _$UpdateProfileRequestCopyWithImpl<$Res, UpdateProfileRequest>; 43 + @useResult 44 + $Res call({String? displayName, String? description}); 45 + } 46 + 47 + /// @nodoc 48 + class _$UpdateProfileRequestCopyWithImpl< 49 + $Res, 50 + $Val extends UpdateProfileRequest 51 + > 52 + implements $UpdateProfileRequestCopyWith<$Res> { 53 + _$UpdateProfileRequestCopyWithImpl(this._value, this._then); 54 + 55 + // ignore: unused_field 56 + final $Val _value; 57 + // ignore: unused_field 58 + final $Res Function($Val) _then; 59 + 60 + /// Create a copy of UpdateProfileRequest 61 + /// with the given fields replaced by the non-null parameter values. 62 + @pragma('vm:prefer-inline') 63 + @override 64 + $Res call({Object? displayName = freezed, Object? description = freezed}) { 65 + return _then( 66 + _value.copyWith( 67 + displayName: freezed == displayName 68 + ? _value.displayName 69 + : displayName // ignore: cast_nullable_to_non_nullable 70 + as String?, 71 + description: freezed == description 72 + ? _value.description 73 + : description // ignore: cast_nullable_to_non_nullable 74 + as String?, 75 + ) 76 + as $Val, 77 + ); 78 + } 79 + } 80 + 81 + /// @nodoc 82 + abstract class _$$UpdateProfileRequestImplCopyWith<$Res> 83 + implements $UpdateProfileRequestCopyWith<$Res> { 84 + factory _$$UpdateProfileRequestImplCopyWith( 85 + _$UpdateProfileRequestImpl value, 86 + $Res Function(_$UpdateProfileRequestImpl) then, 87 + ) = __$$UpdateProfileRequestImplCopyWithImpl<$Res>; 88 + @override 89 + @useResult 90 + $Res call({String? displayName, String? description}); 91 + } 92 + 93 + /// @nodoc 94 + class __$$UpdateProfileRequestImplCopyWithImpl<$Res> 95 + extends _$UpdateProfileRequestCopyWithImpl<$Res, _$UpdateProfileRequestImpl> 96 + implements _$$UpdateProfileRequestImplCopyWith<$Res> { 97 + __$$UpdateProfileRequestImplCopyWithImpl( 98 + _$UpdateProfileRequestImpl _value, 99 + $Res Function(_$UpdateProfileRequestImpl) _then, 100 + ) : super(_value, _then); 101 + 102 + /// Create a copy of UpdateProfileRequest 103 + /// with the given fields replaced by the non-null parameter values. 104 + @pragma('vm:prefer-inline') 105 + @override 106 + $Res call({Object? displayName = freezed, Object? description = freezed}) { 107 + return _then( 108 + _$UpdateProfileRequestImpl( 109 + displayName: freezed == displayName 110 + ? _value.displayName 111 + : displayName // ignore: cast_nullable_to_non_nullable 112 + as String?, 113 + description: freezed == description 114 + ? _value.description 115 + : description // ignore: cast_nullable_to_non_nullable 116 + as String?, 117 + ), 118 + ); 119 + } 120 + } 121 + 122 + /// @nodoc 123 + @JsonSerializable() 124 + class _$UpdateProfileRequestImpl implements _UpdateProfileRequest { 125 + const _$UpdateProfileRequestImpl({this.displayName, this.description}); 126 + 127 + factory _$UpdateProfileRequestImpl.fromJson(Map<String, dynamic> json) => 128 + _$$UpdateProfileRequestImplFromJson(json); 129 + 130 + @override 131 + final String? displayName; 132 + @override 133 + final String? description; 134 + 135 + @override 136 + String toString() { 137 + return 'UpdateProfileRequest(displayName: $displayName, description: $description)'; 138 + } 139 + 140 + @override 141 + bool operator ==(Object other) { 142 + return identical(this, other) || 143 + (other.runtimeType == runtimeType && 144 + other is _$UpdateProfileRequestImpl && 145 + (identical(other.displayName, displayName) || 146 + other.displayName == displayName) && 147 + (identical(other.description, description) || 148 + other.description == description)); 149 + } 150 + 151 + @JsonKey(includeFromJson: false, includeToJson: false) 152 + @override 153 + int get hashCode => Object.hash(runtimeType, displayName, description); 154 + 155 + /// Create a copy of UpdateProfileRequest 156 + /// with the given fields replaced by the non-null parameter values. 157 + @JsonKey(includeFromJson: false, includeToJson: false) 158 + @override 159 + @pragma('vm:prefer-inline') 160 + _$$UpdateProfileRequestImplCopyWith<_$UpdateProfileRequestImpl> 161 + get copyWith => 162 + __$$UpdateProfileRequestImplCopyWithImpl<_$UpdateProfileRequestImpl>( 163 + this, 164 + _$identity, 165 + ); 166 + 167 + @override 168 + Map<String, dynamic> toJson() { 169 + return _$$UpdateProfileRequestImplToJson(this); 170 + } 171 + } 172 + 173 + abstract class _UpdateProfileRequest implements UpdateProfileRequest { 174 + const factory _UpdateProfileRequest({ 175 + final String? displayName, 176 + final String? description, 177 + }) = _$UpdateProfileRequestImpl; 178 + 179 + factory _UpdateProfileRequest.fromJson(Map<String, dynamic> json) = 180 + _$UpdateProfileRequestImpl.fromJson; 181 + 182 + @override 183 + String? get displayName; 184 + @override 185 + String? get description; 186 + 187 + /// Create a copy of UpdateProfileRequest 188 + /// with the given fields replaced by the non-null parameter values. 189 + @override 190 + @JsonKey(includeFromJson: false, includeToJson: false) 191 + _$$UpdateProfileRequestImplCopyWith<_$UpdateProfileRequestImpl> 192 + get copyWith => throw _privateConstructorUsedError; 193 + }
+21
lib/models/procedures/update_profile_request.g.dart
··· 1 + // GENERATED CODE - DO NOT MODIFY BY HAND 2 + 3 + part of 'update_profile_request.dart'; 4 + 5 + // ************************************************************************** 6 + // JsonSerializableGenerator 7 + // ************************************************************************** 8 + 9 + _$UpdateProfileRequestImpl _$$UpdateProfileRequestImplFromJson( 10 + Map<String, dynamic> json, 11 + ) => _$UpdateProfileRequestImpl( 12 + displayName: json['displayName'] as String?, 13 + description: json['description'] as String?, 14 + ); 15 + 16 + Map<String, dynamic> _$$UpdateProfileRequestImplToJson( 17 + _$UpdateProfileRequestImpl instance, 18 + ) => <String, dynamic>{ 19 + 'displayName': instance.displayName, 20 + 'description': instance.description, 21 + };
+15
lib/models/procedures/update_profile_response.dart
··· 1 + import 'package:freezed_annotation/freezed_annotation.dart'; 2 + 3 + part 'update_profile_response.freezed.dart'; 4 + part 'update_profile_response.g.dart'; 5 + 6 + /// Response model for updating an actor's profile information. 7 + /// 8 + /// [success] - Indicates if the update was successful. 9 + @freezed 10 + class UpdateProfileResponse with _$UpdateProfileResponse { 11 + const factory UpdateProfileResponse({required bool success}) = _UpdateProfileResponse; 12 + 13 + factory UpdateProfileResponse.fromJson(Map<String, dynamic> json) => 14 + _$UpdateProfileResponseFromJson(json); 15 + }
+178
lib/models/procedures/update_profile_response.freezed.dart
··· 1 + // coverage:ignore-file 2 + // GENERATED CODE - DO NOT MODIFY BY HAND 3 + // ignore_for_file: type=lint 4 + // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark 5 + 6 + part of 'update_profile_response.dart'; 7 + 8 + // ************************************************************************** 9 + // FreezedGenerator 10 + // ************************************************************************** 11 + 12 + T _$identity<T>(T value) => value; 13 + 14 + final _privateConstructorUsedError = UnsupportedError( 15 + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', 16 + ); 17 + 18 + UpdateProfileResponse _$UpdateProfileResponseFromJson( 19 + Map<String, dynamic> json, 20 + ) { 21 + return _UpdateProfileResponse.fromJson(json); 22 + } 23 + 24 + /// @nodoc 25 + mixin _$UpdateProfileResponse { 26 + bool get success => throw _privateConstructorUsedError; 27 + 28 + /// Serializes this UpdateProfileResponse to a JSON map. 29 + Map<String, dynamic> toJson() => throw _privateConstructorUsedError; 30 + 31 + /// Create a copy of UpdateProfileResponse 32 + /// with the given fields replaced by the non-null parameter values. 33 + @JsonKey(includeFromJson: false, includeToJson: false) 34 + $UpdateProfileResponseCopyWith<UpdateProfileResponse> get copyWith => 35 + throw _privateConstructorUsedError; 36 + } 37 + 38 + /// @nodoc 39 + abstract class $UpdateProfileResponseCopyWith<$Res> { 40 + factory $UpdateProfileResponseCopyWith( 41 + UpdateProfileResponse value, 42 + $Res Function(UpdateProfileResponse) then, 43 + ) = _$UpdateProfileResponseCopyWithImpl<$Res, UpdateProfileResponse>; 44 + @useResult 45 + $Res call({bool success}); 46 + } 47 + 48 + /// @nodoc 49 + class _$UpdateProfileResponseCopyWithImpl< 50 + $Res, 51 + $Val extends UpdateProfileResponse 52 + > 53 + implements $UpdateProfileResponseCopyWith<$Res> { 54 + _$UpdateProfileResponseCopyWithImpl(this._value, this._then); 55 + 56 + // ignore: unused_field 57 + final $Val _value; 58 + // ignore: unused_field 59 + final $Res Function($Val) _then; 60 + 61 + /// Create a copy of UpdateProfileResponse 62 + /// with the given fields replaced by the non-null parameter values. 63 + @pragma('vm:prefer-inline') 64 + @override 65 + $Res call({Object? success = null}) { 66 + return _then( 67 + _value.copyWith( 68 + success: null == success 69 + ? _value.success 70 + : success // ignore: cast_nullable_to_non_nullable 71 + as bool, 72 + ) 73 + as $Val, 74 + ); 75 + } 76 + } 77 + 78 + /// @nodoc 79 + abstract class _$$UpdateProfileResponseImplCopyWith<$Res> 80 + implements $UpdateProfileResponseCopyWith<$Res> { 81 + factory _$$UpdateProfileResponseImplCopyWith( 82 + _$UpdateProfileResponseImpl value, 83 + $Res Function(_$UpdateProfileResponseImpl) then, 84 + ) = __$$UpdateProfileResponseImplCopyWithImpl<$Res>; 85 + @override 86 + @useResult 87 + $Res call({bool success}); 88 + } 89 + 90 + /// @nodoc 91 + class __$$UpdateProfileResponseImplCopyWithImpl<$Res> 92 + extends 93 + _$UpdateProfileResponseCopyWithImpl<$Res, _$UpdateProfileResponseImpl> 94 + implements _$$UpdateProfileResponseImplCopyWith<$Res> { 95 + __$$UpdateProfileResponseImplCopyWithImpl( 96 + _$UpdateProfileResponseImpl _value, 97 + $Res Function(_$UpdateProfileResponseImpl) _then, 98 + ) : super(_value, _then); 99 + 100 + /// Create a copy of UpdateProfileResponse 101 + /// with the given fields replaced by the non-null parameter values. 102 + @pragma('vm:prefer-inline') 103 + @override 104 + $Res call({Object? success = null}) { 105 + return _then( 106 + _$UpdateProfileResponseImpl( 107 + success: null == success 108 + ? _value.success 109 + : success // ignore: cast_nullable_to_non_nullable 110 + as bool, 111 + ), 112 + ); 113 + } 114 + } 115 + 116 + /// @nodoc 117 + @JsonSerializable() 118 + class _$UpdateProfileResponseImpl implements _UpdateProfileResponse { 119 + const _$UpdateProfileResponseImpl({required this.success}); 120 + 121 + factory _$UpdateProfileResponseImpl.fromJson(Map<String, dynamic> json) => 122 + _$$UpdateProfileResponseImplFromJson(json); 123 + 124 + @override 125 + final bool success; 126 + 127 + @override 128 + String toString() { 129 + return 'UpdateProfileResponse(success: $success)'; 130 + } 131 + 132 + @override 133 + bool operator ==(Object other) { 134 + return identical(this, other) || 135 + (other.runtimeType == runtimeType && 136 + other is _$UpdateProfileResponseImpl && 137 + (identical(other.success, success) || other.success == success)); 138 + } 139 + 140 + @JsonKey(includeFromJson: false, includeToJson: false) 141 + @override 142 + int get hashCode => Object.hash(runtimeType, success); 143 + 144 + /// Create a copy of UpdateProfileResponse 145 + /// with the given fields replaced by the non-null parameter values. 146 + @JsonKey(includeFromJson: false, includeToJson: false) 147 + @override 148 + @pragma('vm:prefer-inline') 149 + _$$UpdateProfileResponseImplCopyWith<_$UpdateProfileResponseImpl> 150 + get copyWith => 151 + __$$UpdateProfileResponseImplCopyWithImpl<_$UpdateProfileResponseImpl>( 152 + this, 153 + _$identity, 154 + ); 155 + 156 + @override 157 + Map<String, dynamic> toJson() { 158 + return _$$UpdateProfileResponseImplToJson(this); 159 + } 160 + } 161 + 162 + abstract class _UpdateProfileResponse implements UpdateProfileResponse { 163 + const factory _UpdateProfileResponse({required final bool success}) = 164 + _$UpdateProfileResponseImpl; 165 + 166 + factory _UpdateProfileResponse.fromJson(Map<String, dynamic> json) = 167 + _$UpdateProfileResponseImpl.fromJson; 168 + 169 + @override 170 + bool get success; 171 + 172 + /// Create a copy of UpdateProfileResponse 173 + /// with the given fields replaced by the non-null parameter values. 174 + @override 175 + @JsonKey(includeFromJson: false, includeToJson: false) 176 + _$$UpdateProfileResponseImplCopyWith<_$UpdateProfileResponseImpl> 177 + get copyWith => throw _privateConstructorUsedError; 178 + }
+15
lib/models/procedures/update_profile_response.g.dart
··· 1 + // GENERATED CODE - DO NOT MODIFY BY HAND 2 + 3 + part of 'update_profile_response.dart'; 4 + 5 + // ************************************************************************** 6 + // JsonSerializableGenerator 7 + // ************************************************************************** 8 + 9 + _$UpdateProfileResponseImpl _$$UpdateProfileResponseImplFromJson( 10 + Map<String, dynamic> json, 11 + ) => _$UpdateProfileResponseImpl(success: json['success'] as bool); 12 + 13 + Map<String, dynamic> _$$UpdateProfileResponseImplToJson( 14 + _$UpdateProfileResponseImpl instance, 15 + ) => <String, dynamic>{'success': instance.success};
+14
lib/models/procedures/upload_photo_response.dart
··· 1 + import 'package:freezed_annotation/freezed_annotation.dart'; 2 + 3 + part 'upload_photo_response.freezed.dart'; 4 + part 'upload_photo_response.g.dart'; 5 + 6 + /// Response model for uploading a photo. 7 + /// See lexicon: social.grain.photo.uploadPhoto 8 + @freezed 9 + class UploadPhotoResponse with _$UploadPhotoResponse { 10 + const factory UploadPhotoResponse({required String photoUri}) = _UploadPhotoResponse; 11 + 12 + factory UploadPhotoResponse.fromJson(Map<String, dynamic> json) => 13 + _$UploadPhotoResponseFromJson(json); 14 + }
+172
lib/models/procedures/upload_photo_response.freezed.dart
··· 1 + // coverage:ignore-file 2 + // GENERATED CODE - DO NOT MODIFY BY HAND 3 + // ignore_for_file: type=lint 4 + // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark 5 + 6 + part of 'upload_photo_response.dart'; 7 + 8 + // ************************************************************************** 9 + // FreezedGenerator 10 + // ************************************************************************** 11 + 12 + T _$identity<T>(T value) => value; 13 + 14 + final _privateConstructorUsedError = UnsupportedError( 15 + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', 16 + ); 17 + 18 + UploadPhotoResponse _$UploadPhotoResponseFromJson(Map<String, dynamic> json) { 19 + return _UploadPhotoResponse.fromJson(json); 20 + } 21 + 22 + /// @nodoc 23 + mixin _$UploadPhotoResponse { 24 + String get photoUri => throw _privateConstructorUsedError; 25 + 26 + /// Serializes this UploadPhotoResponse to a JSON map. 27 + Map<String, dynamic> toJson() => throw _privateConstructorUsedError; 28 + 29 + /// Create a copy of UploadPhotoResponse 30 + /// with the given fields replaced by the non-null parameter values. 31 + @JsonKey(includeFromJson: false, includeToJson: false) 32 + $UploadPhotoResponseCopyWith<UploadPhotoResponse> get copyWith => 33 + throw _privateConstructorUsedError; 34 + } 35 + 36 + /// @nodoc 37 + abstract class $UploadPhotoResponseCopyWith<$Res> { 38 + factory $UploadPhotoResponseCopyWith( 39 + UploadPhotoResponse value, 40 + $Res Function(UploadPhotoResponse) then, 41 + ) = _$UploadPhotoResponseCopyWithImpl<$Res, UploadPhotoResponse>; 42 + @useResult 43 + $Res call({String photoUri}); 44 + } 45 + 46 + /// @nodoc 47 + class _$UploadPhotoResponseCopyWithImpl<$Res, $Val extends UploadPhotoResponse> 48 + implements $UploadPhotoResponseCopyWith<$Res> { 49 + _$UploadPhotoResponseCopyWithImpl(this._value, this._then); 50 + 51 + // ignore: unused_field 52 + final $Val _value; 53 + // ignore: unused_field 54 + final $Res Function($Val) _then; 55 + 56 + /// Create a copy of UploadPhotoResponse 57 + /// with the given fields replaced by the non-null parameter values. 58 + @pragma('vm:prefer-inline') 59 + @override 60 + $Res call({Object? photoUri = null}) { 61 + return _then( 62 + _value.copyWith( 63 + photoUri: null == photoUri 64 + ? _value.photoUri 65 + : photoUri // ignore: cast_nullable_to_non_nullable 66 + as String, 67 + ) 68 + as $Val, 69 + ); 70 + } 71 + } 72 + 73 + /// @nodoc 74 + abstract class _$$UploadPhotoResponseImplCopyWith<$Res> 75 + implements $UploadPhotoResponseCopyWith<$Res> { 76 + factory _$$UploadPhotoResponseImplCopyWith( 77 + _$UploadPhotoResponseImpl value, 78 + $Res Function(_$UploadPhotoResponseImpl) then, 79 + ) = __$$UploadPhotoResponseImplCopyWithImpl<$Res>; 80 + @override 81 + @useResult 82 + $Res call({String photoUri}); 83 + } 84 + 85 + /// @nodoc 86 + class __$$UploadPhotoResponseImplCopyWithImpl<$Res> 87 + extends _$UploadPhotoResponseCopyWithImpl<$Res, _$UploadPhotoResponseImpl> 88 + implements _$$UploadPhotoResponseImplCopyWith<$Res> { 89 + __$$UploadPhotoResponseImplCopyWithImpl( 90 + _$UploadPhotoResponseImpl _value, 91 + $Res Function(_$UploadPhotoResponseImpl) _then, 92 + ) : super(_value, _then); 93 + 94 + /// Create a copy of UploadPhotoResponse 95 + /// with the given fields replaced by the non-null parameter values. 96 + @pragma('vm:prefer-inline') 97 + @override 98 + $Res call({Object? photoUri = null}) { 99 + return _then( 100 + _$UploadPhotoResponseImpl( 101 + photoUri: null == photoUri 102 + ? _value.photoUri 103 + : photoUri // ignore: cast_nullable_to_non_nullable 104 + as String, 105 + ), 106 + ); 107 + } 108 + } 109 + 110 + /// @nodoc 111 + @JsonSerializable() 112 + class _$UploadPhotoResponseImpl implements _UploadPhotoResponse { 113 + const _$UploadPhotoResponseImpl({required this.photoUri}); 114 + 115 + factory _$UploadPhotoResponseImpl.fromJson(Map<String, dynamic> json) => 116 + _$$UploadPhotoResponseImplFromJson(json); 117 + 118 + @override 119 + final String photoUri; 120 + 121 + @override 122 + String toString() { 123 + return 'UploadPhotoResponse(photoUri: $photoUri)'; 124 + } 125 + 126 + @override 127 + bool operator ==(Object other) { 128 + return identical(this, other) || 129 + (other.runtimeType == runtimeType && 130 + other is _$UploadPhotoResponseImpl && 131 + (identical(other.photoUri, photoUri) || 132 + other.photoUri == photoUri)); 133 + } 134 + 135 + @JsonKey(includeFromJson: false, includeToJson: false) 136 + @override 137 + int get hashCode => Object.hash(runtimeType, photoUri); 138 + 139 + /// Create a copy of UploadPhotoResponse 140 + /// with the given fields replaced by the non-null parameter values. 141 + @JsonKey(includeFromJson: false, includeToJson: false) 142 + @override 143 + @pragma('vm:prefer-inline') 144 + _$$UploadPhotoResponseImplCopyWith<_$UploadPhotoResponseImpl> get copyWith => 145 + __$$UploadPhotoResponseImplCopyWithImpl<_$UploadPhotoResponseImpl>( 146 + this, 147 + _$identity, 148 + ); 149 + 150 + @override 151 + Map<String, dynamic> toJson() { 152 + return _$$UploadPhotoResponseImplToJson(this); 153 + } 154 + } 155 + 156 + abstract class _UploadPhotoResponse implements UploadPhotoResponse { 157 + const factory _UploadPhotoResponse({required final String photoUri}) = 158 + _$UploadPhotoResponseImpl; 159 + 160 + factory _UploadPhotoResponse.fromJson(Map<String, dynamic> json) = 161 + _$UploadPhotoResponseImpl.fromJson; 162 + 163 + @override 164 + String get photoUri; 165 + 166 + /// Create a copy of UploadPhotoResponse 167 + /// with the given fields replaced by the non-null parameter values. 168 + @override 169 + @JsonKey(includeFromJson: false, includeToJson: false) 170 + _$$UploadPhotoResponseImplCopyWith<_$UploadPhotoResponseImpl> get copyWith => 171 + throw _privateConstructorUsedError; 172 + }
+15
lib/models/procedures/upload_photo_response.g.dart
··· 1 + // GENERATED CODE - DO NOT MODIFY BY HAND 2 + 3 + part of 'upload_photo_response.dart'; 4 + 5 + // ************************************************************************** 6 + // JsonSerializableGenerator 7 + // ************************************************************************** 8 + 9 + _$UploadPhotoResponseImpl _$$UploadPhotoResponseImplFromJson( 10 + Map<String, dynamic> json, 11 + ) => _$UploadPhotoResponseImpl(photoUri: json['photoUri'] as String); 12 + 13 + Map<String, dynamic> _$$UploadPhotoResponseImplToJson( 14 + _$UploadPhotoResponseImpl instance, 15 + ) => <String, dynamic>{'photoUri': instance.photoUri};
+3 -4
lib/models/session.dart
··· 1 1 import 'package:freezed_annotation/freezed_annotation.dart'; 2 2 3 - import 'atproto_session.dart'; 4 - 5 3 part 'session.freezed.dart'; 6 4 part 'session.g.dart'; 7 5 8 6 @freezed 9 7 class Session with _$Session { 10 8 const factory Session({ 11 - required AtprotoSession session, 12 9 required String token, 13 - required String pds, 10 + required String refreshToken, 11 + required DateTime expiresAt, 12 + required String did, 14 13 }) = _Session; 15 14 16 15 factory Session.fromJson(Map<String, dynamic> json) => _$SessionFromJson(json);
+67 -51
lib/models/session.freezed.dart
··· 21 21 22 22 /// @nodoc 23 23 mixin _$Session { 24 - AtprotoSession get session => throw _privateConstructorUsedError; 25 24 String get token => throw _privateConstructorUsedError; 26 - String get pds => throw _privateConstructorUsedError; 25 + String get refreshToken => throw _privateConstructorUsedError; 26 + DateTime get expiresAt => throw _privateConstructorUsedError; 27 + String get did => throw _privateConstructorUsedError; 27 28 28 29 /// Serializes this Session to a JSON map. 29 30 Map<String, dynamic> toJson() => throw _privateConstructorUsedError; ··· 39 40 factory $SessionCopyWith(Session value, $Res Function(Session) then) = 40 41 _$SessionCopyWithImpl<$Res, Session>; 41 42 @useResult 42 - $Res call({AtprotoSession session, String token, String pds}); 43 - 44 - $AtprotoSessionCopyWith<$Res> get session; 43 + $Res call({ 44 + String token, 45 + String refreshToken, 46 + DateTime expiresAt, 47 + String did, 48 + }); 45 49 } 46 50 47 51 /// @nodoc ··· 59 63 @pragma('vm:prefer-inline') 60 64 @override 61 65 $Res call({ 62 - Object? session = null, 63 66 Object? token = null, 64 - Object? pds = null, 67 + Object? refreshToken = null, 68 + Object? expiresAt = null, 69 + Object? did = null, 65 70 }) { 66 71 return _then( 67 72 _value.copyWith( 68 - session: null == session 69 - ? _value.session 70 - : session // ignore: cast_nullable_to_non_nullable 71 - as AtprotoSession, 72 73 token: null == token 73 74 ? _value.token 74 75 : token // ignore: cast_nullable_to_non_nullable 75 76 as String, 76 - pds: null == pds 77 - ? _value.pds 78 - : pds // ignore: cast_nullable_to_non_nullable 77 + refreshToken: null == refreshToken 78 + ? _value.refreshToken 79 + : refreshToken // ignore: cast_nullable_to_non_nullable 80 + as String, 81 + expiresAt: null == expiresAt 82 + ? _value.expiresAt 83 + : expiresAt // ignore: cast_nullable_to_non_nullable 84 + as DateTime, 85 + did: null == did 86 + ? _value.did 87 + : did // ignore: cast_nullable_to_non_nullable 79 88 as String, 80 89 ) 81 90 as $Val, 82 91 ); 83 92 } 84 - 85 - /// Create a copy of Session 86 - /// with the given fields replaced by the non-null parameter values. 87 - @override 88 - @pragma('vm:prefer-inline') 89 - $AtprotoSessionCopyWith<$Res> get session { 90 - return $AtprotoSessionCopyWith<$Res>(_value.session, (value) { 91 - return _then(_value.copyWith(session: value) as $Val); 92 - }); 93 - } 94 93 } 95 94 96 95 /// @nodoc ··· 101 100 ) = __$$SessionImplCopyWithImpl<$Res>; 102 101 @override 103 102 @useResult 104 - $Res call({AtprotoSession session, String token, String pds}); 105 - 106 - @override 107 - $AtprotoSessionCopyWith<$Res> get session; 103 + $Res call({ 104 + String token, 105 + String refreshToken, 106 + DateTime expiresAt, 107 + String did, 108 + }); 108 109 } 109 110 110 111 /// @nodoc ··· 121 122 @pragma('vm:prefer-inline') 122 123 @override 123 124 $Res call({ 124 - Object? session = null, 125 125 Object? token = null, 126 - Object? pds = null, 126 + Object? refreshToken = null, 127 + Object? expiresAt = null, 128 + Object? did = null, 127 129 }) { 128 130 return _then( 129 131 _$SessionImpl( 130 - session: null == session 131 - ? _value.session 132 - : session // ignore: cast_nullable_to_non_nullable 133 - as AtprotoSession, 134 132 token: null == token 135 133 ? _value.token 136 134 : token // ignore: cast_nullable_to_non_nullable 137 135 as String, 138 - pds: null == pds 139 - ? _value.pds 140 - : pds // ignore: cast_nullable_to_non_nullable 136 + refreshToken: null == refreshToken 137 + ? _value.refreshToken 138 + : refreshToken // ignore: cast_nullable_to_non_nullable 139 + as String, 140 + expiresAt: null == expiresAt 141 + ? _value.expiresAt 142 + : expiresAt // ignore: cast_nullable_to_non_nullable 143 + as DateTime, 144 + did: null == did 145 + ? _value.did 146 + : did // ignore: cast_nullable_to_non_nullable 141 147 as String, 142 148 ), 143 149 ); ··· 148 154 @JsonSerializable() 149 155 class _$SessionImpl implements _Session { 150 156 const _$SessionImpl({ 151 - required this.session, 152 157 required this.token, 153 - required this.pds, 158 + required this.refreshToken, 159 + required this.expiresAt, 160 + required this.did, 154 161 }); 155 162 156 163 factory _$SessionImpl.fromJson(Map<String, dynamic> json) => 157 164 _$$SessionImplFromJson(json); 158 165 159 166 @override 160 - final AtprotoSession session; 167 + final String token; 168 + @override 169 + final String refreshToken; 161 170 @override 162 - final String token; 171 + final DateTime expiresAt; 163 172 @override 164 - final String pds; 173 + final String did; 165 174 166 175 @override 167 176 String toString() { 168 - return 'Session(session: $session, token: $token, pds: $pds)'; 177 + return 'Session(token: $token, refreshToken: $refreshToken, expiresAt: $expiresAt, did: $did)'; 169 178 } 170 179 171 180 @override ··· 173 182 return identical(this, other) || 174 183 (other.runtimeType == runtimeType && 175 184 other is _$SessionImpl && 176 - (identical(other.session, session) || other.session == session) && 177 185 (identical(other.token, token) || other.token == token) && 178 - (identical(other.pds, pds) || other.pds == pds)); 186 + (identical(other.refreshToken, refreshToken) || 187 + other.refreshToken == refreshToken) && 188 + (identical(other.expiresAt, expiresAt) || 189 + other.expiresAt == expiresAt) && 190 + (identical(other.did, did) || other.did == did)); 179 191 } 180 192 181 193 @JsonKey(includeFromJson: false, includeToJson: false) 182 194 @override 183 - int get hashCode => Object.hash(runtimeType, session, token, pds); 195 + int get hashCode => 196 + Object.hash(runtimeType, token, refreshToken, expiresAt, did); 184 197 185 198 /// Create a copy of Session 186 199 /// with the given fields replaced by the non-null parameter values. ··· 198 211 199 212 abstract class _Session implements Session { 200 213 const factory _Session({ 201 - required final AtprotoSession session, 202 214 required final String token, 203 - required final String pds, 215 + required final String refreshToken, 216 + required final DateTime expiresAt, 217 + required final String did, 204 218 }) = _$SessionImpl; 205 219 206 220 factory _Session.fromJson(Map<String, dynamic> json) = _$SessionImpl.fromJson; 207 221 208 222 @override 209 - AtprotoSession get session; 223 + String get token; 224 + @override 225 + String get refreshToken; 210 226 @override 211 - String get token; 227 + DateTime get expiresAt; 212 228 @override 213 - String get pds; 229 + String get did; 214 230 215 231 /// Create a copy of Session 216 232 /// with the given fields replaced by the non-null parameter values.
+6 -4
lib/models/session.g.dart
··· 8 8 9 9 _$SessionImpl _$$SessionImplFromJson(Map<String, dynamic> json) => 10 10 _$SessionImpl( 11 - session: AtprotoSession.fromJson(json['session'] as Map<String, dynamic>), 12 11 token: json['token'] as String, 13 - pds: json['pds'] as String, 12 + refreshToken: json['refreshToken'] as String, 13 + expiresAt: DateTime.parse(json['expiresAt'] as String), 14 + did: json['did'] as String, 14 15 ); 15 16 16 17 Map<String, dynamic> _$$SessionImplToJson(_$SessionImpl instance) => 17 18 <String, dynamic>{ 18 - 'session': instance.session, 19 19 'token': instance.token, 20 - 'pds': instance.pds, 20 + 'refreshToken': instance.refreshToken, 21 + 'expiresAt': instance.expiresAt.toIso8601String(), 22 + 'did': instance.did, 21 23 };
+101 -110
lib/providers/gallery_cache_provider.dart
··· 1 1 import 'dart:async'; 2 2 import 'dart:io'; 3 - import 'dart:ui' as ui; 4 3 5 4 import 'package:bluesky_text/bluesky_text.dart'; 6 5 import 'package:flutter/foundation.dart'; 7 6 import 'package:grain/models/gallery_photo.dart'; 7 + import 'package:grain/models/procedures/apply_alts_update.dart'; 8 + import 'package:grain/models/procedures/procedures.dart'; 9 + import 'package:grain/providers/profile_provider.dart'; 8 10 import 'package:image_picker/image_picker.dart'; 9 11 import 'package:riverpod_annotation/riverpod_annotation.dart'; 10 12 11 13 import '../api.dart'; 14 + import '../app_logger.dart'; 12 15 import '../models/gallery.dart'; 13 16 import '../models/gallery_item.dart'; 14 17 import '../photo_manip.dart'; ··· 59 62 bool success = false; 60 63 String? newFavUri; 61 64 if (isFav) { 62 - newFavUri = await apiService.createFavorite(galleryUri: uri); 63 - success = newFavUri != null; 65 + final response = await apiService.createFavorite( 66 + request: CreateFavoriteRequest(subject: latestGallery.uri), 67 + ); 68 + newFavUri = response.favoriteUri; 69 + success = true; 64 70 } else { 65 - success = await apiService.deleteRecord(latestGallery.viewer?.fav ?? uri); 71 + final deleteResponse = await apiService.deleteFavorite( 72 + request: DeleteFavoriteRequest(uri: latestGallery.viewer?.fav ?? uri), 73 + ); 74 + success = deleteResponse.success; 66 75 newFavUri = null; 67 76 } 68 77 if (success) { 69 78 final newCount = (latestGallery.favCount ?? 0) + (isFav ? 1 : -1); 70 79 final updatedViewer = latestGallery.viewer?.copyWith(fav: newFavUri); 71 - state = {...state, uri: latestGallery.copyWith(favCount: newCount, viewer: updatedViewer)}; 80 + final updatedGallery = latestGallery.copyWith(favCount: newCount, viewer: updatedViewer); 81 + state = {...state, uri: updatedGallery}; 82 + 83 + // Push favorite change to profile provider favs 84 + final profileProvider = ref.read( 85 + profileNotifierProvider(apiService.currentUser!.did).notifier, 86 + ); 87 + if (isFav) { 88 + profileProvider.addFavorite(updatedGallery); 89 + } else { 90 + profileProvider.removeFavorite(updatedGallery.uri); 91 + } 72 92 } 73 93 } 74 94 ··· 77 97 final gallery = state[galleryUri]; 78 98 if (gallery == null) return; 79 99 // Call backend to delete the gallery item 80 - await apiService.deleteRecord(galleryItemUri); 100 + await apiService.deleteGalleryItem(request: DeleteGalleryItemRequest(uri: galleryItemUri)); 81 101 // Remove by gallery item record URI, not photo URI 82 102 final updatedItems = gallery.items.where((p) => p.gallery?.item != galleryItemUri).toList(); 83 103 final updatedGallery = gallery.copyWith(items: updatedItems); 84 104 state = {...state, galleryUri: updatedGallery}; 85 105 } 86 106 87 - /// Uploads multiple photos, gets their dimensions, resizes them, creates the photos, and adds them as gallery items. 88 - /// At the end, polls for the updated gallery items and updates the cache. 89 - /// Returns the list of new photoUris if successful, or empty list otherwise. 90 107 Future<List<String>> uploadAndAddPhotosToGallery({ 91 108 required String galleryUri, 92 109 required List<XFile> xfiles, ··· 110 127 // Resize the image 111 128 final resizedResult = await compute<File, ResizeResult>((f) => resizeImage(file: f), file); 112 129 // Upload the blob 113 - final blobResult = await apiService.uploadBlob(resizedResult.file); 114 - if (blobResult == null) continue; 115 - // Get image dimensions 116 - final bytes = await xfile.readAsBytes(); 117 - final completer = Completer<Map<String, int>>(); 118 - ui.decodeImageFromList(bytes, (image) { 119 - completer.complete({'width': image.width, 'height': image.height}); 120 - }); 121 - final dims = await completer.future; 122 - // Create the photo 123 - final photoUri = await apiService.createPhoto( 124 - blob: blobResult, 125 - width: dims['width']!, 126 - height: dims['height']!, 127 - ); 128 - if (photoUri == null) continue; 129 - 130 + final res = await apiService.uploadPhoto(resizedResult.file); 131 + if (res.photoUri.isEmpty) continue; 130 132 // If EXIF data was found, create photo exif record 131 133 if (exif != null) { 132 - await apiService.createPhotoExif( 133 - photo: photoUri, 134 - dateTimeOriginal: exif['dateTimeOriginal'] as String?, 135 - exposureTime: exif['exposureTime'] as int?, 136 - fNumber: exif['fNumber'] as int?, 137 - flash: exif['flash'] as String?, 138 - focalLengthIn35mmFormat: exif['focalLengthIn35mmFilm'] as int?, 139 - iSO: exif['iSOSpeedRatings'] as int?, 140 - lensMake: exif['lensMake'] as String?, 141 - lensModel: exif['lensModel'] as String?, 142 - make: exif['make'] as String?, 143 - model: exif['model'] as String?, 134 + await apiService.createExif( 135 + request: CreateExifRequest( 136 + photo: res.photoUri, 137 + dateTimeOriginal: exif['dateTimeOriginal'], 138 + exposureTime: exif['exposureTime'], 139 + fNumber: exif['fNumber'], 140 + flash: exif['flash'], 141 + focalLengthIn35mmFormat: exif['focalLengthIn35mmFilm'], 142 + iSO: exif['iSOSpeedRatings'], 143 + lensMake: exif['lensMake'], 144 + lensModel: exif['lensModel'], 145 + make: exif['make'], 146 + model: exif['model'], 147 + ), 144 148 ); 145 149 } 146 150 147 151 // Create the gallery item 148 152 await apiService.createGalleryItem( 149 - galleryUri: galleryUri, 150 - photoUri: photoUri, 151 - position: position, 153 + request: CreateGalleryItemRequest( 154 + galleryUri: galleryUri, 155 + photoUri: res.photoUri, 156 + position: position, 157 + ), 152 158 ); 153 - photoUris.add(photoUri); 159 + photoUris.add(res.photoUri); 154 160 position++; 155 161 } 156 - // Poll for updated gallery items 157 - final expectedCount = (gallery?.items.length ?? 0) + photoUris.length; 158 - await apiService.pollGalleryItems(galleryUri: galleryUri, expectedCount: expectedCount); 159 162 // Fetch the updated gallery and update the cache 160 163 final updatedGallery = await apiService.getGallery(uri: galleryUri); 161 164 if (updatedGallery != null) { ··· 172 175 required List<XFile> xfiles, 173 176 bool includeExif = true, 174 177 }) async { 175 - // Extract facets from description 176 - final facetsList = await _extractFacets(description); 177 - final facets = facetsList.isEmpty ? null : facetsList; 178 - // Create the gallery with facets 179 - final galleryUri = await apiService.createGallery( 180 - title: title, 181 - description: description, 182 - facets: facets, 178 + final res = await apiService.createGallery( 179 + request: CreateGalleryRequest(title: title, description: description), 183 180 ); 184 - if (galleryUri == null) return (null, <String>[]); 185 181 // Upload and add photos 186 182 final photoUris = await uploadAndAddPhotosToGallery( 187 - galleryUri: galleryUri, 183 + galleryUri: res.galleryUri, 188 184 xfiles: xfiles, 189 185 includeExif: includeExif, 190 186 ); 191 - return (galleryUri, photoUris); 187 + return (res.galleryUri, photoUris); 192 188 } 193 189 194 - /// Creates gallery items for existing photoUris, polls for updated gallery items, and updates the cache. 190 + /// Creates gallery items for existing photoUris and updates the cache. 195 191 /// Returns the list of new gallery item URIs if successful, or empty list otherwise. 196 192 Future<List<String>> addGalleryItemsToGallery({ 197 193 required String galleryUri, ··· 210 206 int position = positionOffset; 211 207 for (final photoUri in photoUris) { 212 208 // Create the gallery item 213 - final itemUri = await apiService.createGalleryItem( 214 - galleryUri: galleryUri, 215 - photoUri: photoUri, 216 - position: position, 209 + final res = await apiService.createGalleryItem( 210 + request: CreateGalleryItemRequest( 211 + galleryUri: galleryUri, 212 + photoUri: photoUri, 213 + position: position, 214 + ), 217 215 ); 218 - if (itemUri != null) { 219 - galleryItemUris.add(itemUri); 216 + if (res.itemUri.isNotEmpty) { 217 + galleryItemUris.add(res.itemUri); 220 218 position++; 221 219 } 222 220 } 223 - // Poll for updated gallery items 224 - final expectedCount = (gallery?.items.length ?? 0) + galleryItemUris.length; 225 - await apiService.pollGalleryItems(galleryUri: galleryUri, expectedCount: expectedCount); 226 221 // Fetch the updated gallery and update the cache 227 222 final updatedGallery = await apiService.getGallery(uri: galleryUri); 228 223 if (updatedGallery != null) { ··· 233 228 234 229 /// Deletes a gallery from the backend and removes it from the cache. 235 230 Future<void> deleteGallery(String uri) async { 236 - // Fetch the latest gallery from backend to ensure all items are deleted 237 - final gallery = await apiService.getGallery(uri: uri); 238 - if (gallery != null) { 239 - // Delete all gallery item records 240 - for (final item in gallery.items) { 241 - final itemUri = item.gallery?.item; 242 - if (itemUri != null && itemUri.isNotEmpty) { 243 - await apiService.deleteRecord(itemUri); 244 - } 245 - } 246 - } 247 - await apiService.deleteRecord(uri); 231 + await apiService.deleteGallery(request: DeleteGalleryRequest(uri: uri)); 248 232 removeGallery(uri); 249 233 } 250 234 ··· 269 253 for (int i = 0; i < orderedItems.length; i++) { 270 254 orderedItems[i] = orderedItems[i].copyWith(position: i); 271 255 } 272 - await apiService.updateGallerySortOrder(galleryUri: galleryUri, orderedItems: orderedItems); 256 + final res = await apiService.applySort( 257 + request: ApplySortRequest( 258 + writes: orderedItems 259 + .map((item) => ApplySortUpdate(itemUri: item.uri, position: item.position)) 260 + .toList(), 261 + ), 262 + ); 263 + if (!res.success) { 264 + appLogger.w('Failed to reorder gallery items for $galleryUri'); 265 + return; 266 + } 273 267 // Update cache with new order 274 268 final updatedPhotos = orderedItems 275 269 .where((item) => gallery.items.any((p) => p.uri == item.item)) ··· 282 276 state = {...state, galleryUri: updatedGallery}; 283 277 } 284 278 285 - /// Updates gallery details (title, description), polls for cid change, and updates cache. 279 + /// Updates gallery details (title, description) and updates cache. 286 280 Future<bool> updateGalleryDetails({ 287 281 required String galleryUri, 288 282 required String title, 289 283 required String description, 290 284 required String createdAt, 291 285 }) async { 292 - final prevGallery = state[galleryUri]; 293 - final prevCid = prevGallery?.cid; 294 - // Extract facets from description 295 - final facetsList = await _extractFacets(description); 296 - final facets = facetsList.isEmpty ? null : facetsList; 297 - final success = await apiService.updateGallery( 298 - galleryUri: galleryUri, 299 - title: title, 300 - description: description, 301 - createdAt: createdAt, 302 - facets: facets, 303 - ); 304 - if (success) { 305 - final start = DateTime.now(); 306 - const timeout = Duration(seconds: 20); 307 - const pollInterval = Duration(milliseconds: 1000); 308 - Gallery? updatedGallery; 309 - while (DateTime.now().difference(start) < timeout) { 310 - updatedGallery = await apiService.getGallery(uri: galleryUri); 311 - if (updatedGallery != null && updatedGallery.cid != prevCid) { 312 - break; 313 - } 314 - await Future.delayed(pollInterval); 315 - } 316 - if (updatedGallery != null) { 317 - state = {...state, galleryUri: updatedGallery}; 318 - } 286 + try { 287 + await apiService.updateGallery( 288 + request: UpdateGalleryRequest( 289 + galleryUri: galleryUri, 290 + title: title, 291 + description: description, 292 + ), 293 + ); 294 + } catch (e, st) { 295 + appLogger.e('Failed to update gallery details: $e', stackTrace: st); 296 + return false; 297 + } 298 + final updatedGallery = await apiService.getGallery(uri: galleryUri); 299 + if (updatedGallery != null) { 300 + state = {...state, galleryUri: updatedGallery}; 319 301 } 320 - return success; 302 + return true; 321 303 } 322 304 323 305 /// Fetches timeline galleries from the API and updates the cache. ··· 335 317 required String galleryUri, 336 318 required List<Map<String, dynamic>> altUpdates, 337 319 }) async { 338 - final success = await apiService.updatePhotos(altUpdates); 339 - if (!success) return false; 320 + final res = await apiService.applyAlts( 321 + request: ApplyAltsRequest( 322 + writes: altUpdates.map((update) { 323 + return ApplyAltsUpdate( 324 + photoUri: update['photoUri'] as String, 325 + alt: update['alt'] as String, 326 + ); 327 + }).toList(), 328 + ), 329 + ); 330 + if (!res.success) return false; 340 331 341 332 // Update the gallery photos' alt text in the cache manually 342 333 final gallery = state[galleryUri];
+1 -1
lib/providers/gallery_cache_provider.g.dart
··· 6 6 // RiverpodGenerator 7 7 // ************************************************************************** 8 8 9 - String _$galleryCacheHash() => r'cd0665a1f246bd700195cf5ce50893ba73b878f9'; 9 + String _$galleryCacheHash() => r'd74ced0d6fcf6369bed80f7f0219bd591c13db5a'; 10 10 11 11 /// Holds a cache of galleries by URI. 12 12 ///
+10 -24
lib/providers/gallery_thread_cache_provider.dart
··· 1 - import 'package:bluesky_text/bluesky_text.dart'; 2 1 import 'package:grain/api.dart'; 3 2 import 'package:grain/models/comment.dart'; 4 3 import 'package:grain/models/gallery.dart'; 4 + import 'package:grain/models/procedures/create_comment_request.dart'; 5 + import 'package:grain/models/procedures/delete_comment_request.dart'; 5 6 import 'package:grain/providers/gallery_cache_provider.dart'; 6 7 import 'package:riverpod_annotation/riverpod_annotation.dart'; 7 8 ··· 65 66 } 66 67 } 67 68 68 - Future<List<Map<String, dynamic>>> _extractFacets(String text) async { 69 - final blueskyText = BlueskyText(text); 70 - final entities = blueskyText.entities; 71 - final facets = await entities.toFacets(); 72 - return List<Map<String, dynamic>>.from(facets); 73 - } 74 - 75 69 Future<bool> createComment({required String text, String? replyTo, String? focus}) async { 76 70 try { 77 - final facetsList = await _extractFacets(text); 78 - final facets = facetsList.isEmpty ? null : facetsList; 79 - final uri = await apiService.createComment( 71 + final request = CreateCommentRequest( 80 72 text: text, 81 73 subject: galleryUri, 82 74 replyTo: replyTo, 83 - facets: facets, 84 75 focus: focus, 85 76 ); 86 - if (uri != null) { 87 - final thread = await apiService.pollGalleryThreadComments( 88 - galleryUri: galleryUri, 89 - expectedCount: state.comments.length + 1, 90 - ); 77 + final res = await apiService.createComment(request: request); 78 + if (res.commentUri.isNotEmpty) { 79 + final thread = await apiService.getGalleryThread(uri: galleryUri); 91 80 if (thread != null) { 92 81 state = state.copyWith(gallery: thread.gallery, comments: thread.comments); 93 82 // Update the gallery cache with the latest gallery ··· 102 91 } 103 92 104 93 Future<bool> deleteComment(Comment comment) async { 105 - final deleted = await apiService.deleteRecord(comment.uri); 106 - if (!deleted) return false; 107 - final expectedCount = state.comments.length - 1; 108 - final thread = await apiService.pollGalleryThreadComments( 109 - galleryUri: galleryUri, 110 - expectedCount: expectedCount, 111 - ); 94 + final request = DeleteCommentRequest(uri: comment.uri); 95 + final res = await apiService.deleteComment(request: request); 96 + if (!res.success) return false; 97 + final thread = await apiService.getGalleryThread(uri: galleryUri); 112 98 if (thread != null) { 113 99 state = state.copyWith(gallery: thread.gallery, comments: thread.comments); 114 100 // Update the gallery cache with the latest gallery
+1 -1
lib/providers/gallery_thread_cache_provider.g.dart
··· 6 6 // RiverpodGenerator 7 7 // ************************************************************************** 8 8 9 - String _$galleryThreadHash() => r'fa270baa7dd229fdd6b4e2610cf232aed53ed3db'; 9 + String _$galleryThreadHash() => r'80fa9b4e19b9d7606654fff8549516d4654dfa87'; 10 10 11 11 /// Copied from Dart SDK 12 12 class _SystemHash {
+55 -39
lib/providers/profile_provider.dart
··· 1 1 import 'dart:io'; 2 2 3 3 import 'package:bluesky_text/bluesky_text.dart'; 4 + import 'package:flutter/foundation.dart'; 4 5 import 'package:grain/api.dart'; 5 6 import 'package:grain/models/gallery.dart'; 6 - import 'package:grain/models/profile.dart'; 7 + import 'package:grain/models/procedures/create_follow_request.dart'; 8 + import 'package:grain/models/procedures/delete_follow_request.dart'; 9 + import 'package:grain/models/procedures/update_profile_request.dart'; 7 10 import 'package:grain/models/profile_with_galleries.dart'; 11 + import 'package:grain/photo_manip.dart'; 8 12 import 'package:grain/providers/gallery_cache_provider.dart'; 9 13 import 'package:image_picker/image_picker.dart'; 10 14 import 'package:riverpod_annotation/riverpod_annotation.dart'; ··· 82 86 required String description, 83 87 dynamic avatarFile, 84 88 }) async { 85 - final currentProfile = state.value?.profile; 86 - final isUnchanged = 87 - currentProfile != null && 88 - currentProfile.displayName == displayName && 89 - currentProfile.description == description && 90 - avatarFile == null; 91 - if (isUnchanged) { 92 - // No changes, skip API call 93 - return true; 94 - } 95 89 File? file; 96 90 if (avatarFile is XFile) { 97 91 file = File(avatarFile.path); ··· 100 94 } else { 101 95 file = null; 102 96 } 103 - final success = await apiService.updateProfile( 104 - displayName: displayName, 105 - description: description, 106 - avatarFile: file, 97 + final profileRes = await apiService.updateProfile( 98 + request: UpdateProfileRequest(displayName: displayName, description: description), 107 99 ); 108 - if (success) { 109 - final start = DateTime.now(); 110 - const timeout = Duration(seconds: 20); 111 - const pollInterval = Duration(milliseconds: 1000); 112 - Profile? updated; 113 - final prevCid = state.value?.profile.cid; 114 - state = const AsyncValue.loading(); // Force UI to show loading and rebuild 115 - while (DateTime.now().difference(start) < timeout) { 116 - updated = await apiService.fetchProfile(did: did); 117 - if (updated != null && updated.cid != prevCid) { 118 - break; 119 - } 120 - await Future.delayed(pollInterval); 121 - } 122 - // Always assign a new instance to state 100 + bool avatarSuccess = true; 101 + if (file != null) { 102 + final resizedResult = await compute<File, ResizeResult>((f) => resizeImage(file: f), file); 103 + final avatarRes = await apiService.updateAvatar(avatarFile: resizedResult.file); 104 + avatarSuccess = avatarRes.success; 105 + } 106 + // Refetch updated profile if update succeeded 107 + if (profileRes.success || avatarSuccess) { 108 + final updated = await apiService.fetchProfile(did: did); 123 109 if (updated != null) { 124 110 final galleries = await apiService.fetchActorGalleries(did: did); 125 111 final facets = await computeAndFilterFacets(updated.description); 126 - // Update the gallery cache provider 127 112 ref.read(galleryCacheProvider.notifier).setGalleriesForActor(did, galleries); 128 113 state = AsyncValue.data( 129 114 ProfileWithGalleries( ··· 134 119 ); 135 120 } else { 136 121 state = const AsyncValue.data(null); 137 - } 138 - if (updated == null) { 139 122 await refresh(); 140 123 } 124 + return true; 125 + } else { 126 + await refresh(); 127 + return false; 141 128 } 142 - return success; 143 129 } 144 130 145 131 Future<void> toggleFollow(String? followerDid) async { ··· 150 136 final followUri = viewer?.following; 151 137 if (followUri != null && followUri.isNotEmpty) { 152 138 // Unfollow 153 - final success = await apiService.deleteRecord(followUri); 154 - if (success) { 139 + final res = await apiService.deleteFollow(request: DeleteFollowRequest(uri: followUri)); 140 + if (res.success) { 155 141 final updatedProfile = profile.copyWith( 156 142 viewer: viewer?.copyWith(following: null), 157 143 followersCount: (profile.followersCount ?? 1) - 1, ··· 166 152 } 167 153 } else { 168 154 // Follow 169 - final newFollowUri = await apiService.createFollow(followeeDid: did); 170 - if (newFollowUri != null) { 155 + final res = await apiService.createFollow(request: CreateFollowRequest(subject: followerDid)); 156 + if (res.followUri.isNotEmpty) { 171 157 final updatedProfile = profile.copyWith( 172 - viewer: viewer?.copyWith(following: newFollowUri), 158 + viewer: viewer?.copyWith(following: res.followUri), 173 159 followersCount: (profile.followersCount ?? 0) + 1, 174 160 ); 175 161 state = AsyncValue.data( ··· 212 198 profile: updatedProfile, 213 199 galleries: updatedGalleries, 214 200 favs: currentProfile.favs, 201 + ), 202 + ); 203 + } 204 + } 205 + 206 + /// Adds a gallery to the user's favorites in the profile state. 207 + void addFavorite(Gallery gallery) { 208 + final currentProfile = state.value; 209 + if (currentProfile != null) { 210 + final updatedFavs = [gallery, ...?currentProfile.favs]; 211 + state = AsyncValue.data( 212 + ProfileWithGalleries( 213 + profile: currentProfile.profile, 214 + galleries: currentProfile.galleries, 215 + favs: updatedFavs, 216 + ), 217 + ); 218 + } 219 + } 220 + 221 + /// Removes a gallery from the user's favorites in the profile state by URI. 222 + void removeFavorite(String galleryUri) { 223 + final currentProfile = state.value; 224 + if (currentProfile != null) { 225 + final updatedFavs = (currentProfile.favs ?? []).where((g) => g.uri != galleryUri).toList(); 226 + state = AsyncValue.data( 227 + ProfileWithGalleries( 228 + profile: currentProfile.profile, 229 + galleries: currentProfile.galleries, 230 + favs: updatedFavs, 215 231 ), 216 232 ); 217 233 }
+1 -1
lib/providers/profile_provider.g.dart
··· 6 6 // RiverpodGenerator 7 7 // ************************************************************************** 8 8 9 - String _$profileNotifierHash() => r'2ec9237c3a60bff58175d2d39f37b050eecdba78'; 9 + String _$profileNotifierHash() => r'48159a8319bba2f2ec5462c50d80ba6a5b72d91e'; 10 10 11 11 /// Copied from Dart SDK 12 12 class _SystemHash {