phase 4 foundations: vendor missing lexicons, refreshSession api, toLex no-op purge, de-agent link-meta
This commit is contained in:
@@ -123,6 +123,10 @@
|
|||||||
"app.bsky.notification.unregisterPush",
|
"app.bsky.notification.unregisterPush",
|
||||||
"app.bsky.notification.updateSeen",
|
"app.bsky.notification.updateSeen",
|
||||||
"app.bsky.richtext.facet",
|
"app.bsky.richtext.facet",
|
||||||
|
"app.bsky.unspecced.getSuggestedOnboardingUsers",
|
||||||
|
"app.bsky.unspecced.getSuggestedUsersForDiscover",
|
||||||
|
"app.bsky.unspecced.getSuggestedUsersForExplore",
|
||||||
|
"app.bsky.unspecced.getSuggestedUsersForSeeMore",
|
||||||
"app.bsky.video.defs",
|
"app.bsky.video.defs",
|
||||||
"app.bsky.video.getJobStatus",
|
"app.bsky.video.getJobStatus",
|
||||||
"app.bsky.video.getUploadLimits",
|
"app.bsky.video.getUploadLimits",
|
||||||
@@ -273,6 +277,8 @@
|
|||||||
"com.atproto.sync.notifyOfUpdate",
|
"com.atproto.sync.notifyOfUpdate",
|
||||||
"com.atproto.sync.requestCrawl",
|
"com.atproto.sync.requestCrawl",
|
||||||
"com.atproto.sync.subscribeRepos",
|
"com.atproto.sync.subscribeRepos",
|
||||||
|
"com.atproto.temp.checkHandleAvailability",
|
||||||
|
"com.atproto.temp.checkSignupQueue",
|
||||||
"com.germnetwork.declaration"
|
"com.germnetwork.declaration"
|
||||||
],
|
],
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
@@ -800,6 +806,10 @@
|
|||||||
"uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.getSuggestedFeedsSkeleton",
|
"uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.getSuggestedFeedsSkeleton",
|
||||||
"cid": "bafyreihqvsdre7oxhlpl7yucsmpdupwakipyzsu2gjlkbufgmklcgr5cbq"
|
"cid": "bafyreihqvsdre7oxhlpl7yucsmpdupwakipyzsu2gjlkbufgmklcgr5cbq"
|
||||||
},
|
},
|
||||||
|
"app.bsky.unspecced.getSuggestedOnboardingUsers": {
|
||||||
|
"uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.getSuggestedOnboardingUsers",
|
||||||
|
"cid": "bafyreieot3hdk6h2enuivlp6m2jivd2y4npwbr4h7nsb3kutvnmtpkubm4"
|
||||||
|
},
|
||||||
"app.bsky.unspecced.getSuggestedStarterPacks": {
|
"app.bsky.unspecced.getSuggestedStarterPacks": {
|
||||||
"uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.getSuggestedStarterPacks",
|
"uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.getSuggestedStarterPacks",
|
||||||
"cid": "bafyreih34c76u3vbjaaukyojpsrljslmnptzpnydizyfrjtedzmwosmawy"
|
"cid": "bafyreih34c76u3vbjaaukyojpsrljslmnptzpnydizyfrjtedzmwosmawy"
|
||||||
@@ -812,6 +822,18 @@
|
|||||||
"uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.getSuggestedUsers",
|
"uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.getSuggestedUsers",
|
||||||
"cid": "bafyreib5qavwbqignxipudnk5jzs2inlkjxosckpxakorbk3erlscfn6ba"
|
"cid": "bafyreib5qavwbqignxipudnk5jzs2inlkjxosckpxakorbk3erlscfn6ba"
|
||||||
},
|
},
|
||||||
|
"app.bsky.unspecced.getSuggestedUsersForDiscover": {
|
||||||
|
"uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.getSuggestedUsersForDiscover",
|
||||||
|
"cid": "bafyreienm4jci3ri5umqmdyycpyhtwjbteynqx54tyfjdrilzg6kqr65dm"
|
||||||
|
},
|
||||||
|
"app.bsky.unspecced.getSuggestedUsersForExplore": {
|
||||||
|
"uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.getSuggestedUsersForExplore",
|
||||||
|
"cid": "bafyreidje2onbwlnhm6st54evtxvvsc5n3al4vxq67maah24a2hvwvsd2m"
|
||||||
|
},
|
||||||
|
"app.bsky.unspecced.getSuggestedUsersForSeeMore": {
|
||||||
|
"uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.getSuggestedUsersForSeeMore",
|
||||||
|
"cid": "bafyreidg6zyy4x2cskf7jfdhlmn4nps6ug7tzqhckpx3s264xlxrh5djji"
|
||||||
|
},
|
||||||
"app.bsky.unspecced.getSuggestedUsersSkeleton": {
|
"app.bsky.unspecced.getSuggestedUsersSkeleton": {
|
||||||
"uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.getSuggestedUsersSkeleton",
|
"uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.getSuggestedUsersSkeleton",
|
||||||
"cid": "bafyreibvcocfbsxbf2s2rzuvcovkoyq6m7yz3csxrd6mdeoiwmkjqucxke"
|
"cid": "bafyreibvcocfbsxbf2s2rzuvcovkoyq6m7yz3csxrd6mdeoiwmkjqucxke"
|
||||||
@@ -1456,6 +1478,14 @@
|
|||||||
"uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.sync.subscribeRepos",
|
"uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.sync.subscribeRepos",
|
||||||
"cid": "bafyreic6fm5atifiaq67u44dtxc3ufjbq3z7yysryjrzrw37hkb32yajbi"
|
"cid": "bafyreic6fm5atifiaq67u44dtxc3ufjbq3z7yysryjrzrw37hkb32yajbi"
|
||||||
},
|
},
|
||||||
|
"com.atproto.temp.checkHandleAvailability": {
|
||||||
|
"uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/com.atproto.temp.checkHandleAvailability",
|
||||||
|
"cid": "bafyreifanpe7ixmxampsbl3oaftbo24vzhe5pcunhf3xdsmrmgrgkq5ziq"
|
||||||
|
},
|
||||||
|
"com.atproto.temp.checkSignupQueue": {
|
||||||
|
"uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/com.atproto.temp.checkSignupQueue",
|
||||||
|
"cid": "bafyreignao6slhwqr5kqdiey243oy5wmewfkz4vzseoypdxzoyakwen7bm"
|
||||||
|
},
|
||||||
"com.germnetwork.declaration": {
|
"com.germnetwork.declaration": {
|
||||||
"uri": "at://did:plc:qyqmmncrm6qx33kpy7vqndik/com.atproto.lexicon.schema/com.germnetwork.declaration",
|
"uri": "at://did:plc:qyqmmncrm6qx33kpy7vqndik/com.atproto.lexicon.schema/com.germnetwork.declaration",
|
||||||
"cid": "bafyreiekwjmxshje655olra4mata7npso7bbgytc4fop77ycjtrbewwi3y"
|
"cid": "bafyreiekwjmxshje655olra4mata7npso7bbgytc4fop77ycjtrbewwi3y"
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
{
|
||||||
|
"lexicon": 1,
|
||||||
|
"id": "app.bsky.unspecced.getSuggestedOnboardingUsers",
|
||||||
|
"defs": {
|
||||||
|
"main": {
|
||||||
|
"type": "query",
|
||||||
|
"description": "Get a list of suggested users for onboarding",
|
||||||
|
"parameters": {
|
||||||
|
"type": "params",
|
||||||
|
"properties": {
|
||||||
|
"category": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Category of users to get suggestions for."
|
||||||
|
},
|
||||||
|
"limit": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1,
|
||||||
|
"maximum": 50,
|
||||||
|
"default": 25
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"encoding": "application/json",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["actors"],
|
||||||
|
"properties": {
|
||||||
|
"actors": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "ref",
|
||||||
|
"ref": "app.bsky.actor.defs#profileView"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"recId": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "DEPRECATED: use recIdStr instead."
|
||||||
|
},
|
||||||
|
"recIdStr": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Snowflake for this recommendation, use when submitting recommendation events."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"lexicon": 1,
|
||||||
|
"id": "app.bsky.unspecced.getSuggestedUsersForDiscover",
|
||||||
|
"defs": {
|
||||||
|
"main": {
|
||||||
|
"type": "query",
|
||||||
|
"description": "Get a list of suggested users for the Discover page",
|
||||||
|
"parameters": {
|
||||||
|
"type": "params",
|
||||||
|
"properties": {
|
||||||
|
"limit": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1,
|
||||||
|
"maximum": 50,
|
||||||
|
"default": 25
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"encoding": "application/json",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["actors"],
|
||||||
|
"properties": {
|
||||||
|
"actors": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "ref",
|
||||||
|
"ref": "app.bsky.actor.defs#profileView"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"recIdStr": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Snowflake for this recommendation, use when submitting recommendation events."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
{
|
||||||
|
"lexicon": 1,
|
||||||
|
"id": "app.bsky.unspecced.getSuggestedUsersForDiscoverSkeleton",
|
||||||
|
"defs": {
|
||||||
|
"main": {
|
||||||
|
"type": "query",
|
||||||
|
"description": "Get a skeleton of suggested users for the Discover page. Intended to be called and hydrated by app.bsky.unspecced.getSuggestedUsersForDiscover",
|
||||||
|
"parameters": {
|
||||||
|
"type": "params",
|
||||||
|
"properties": {
|
||||||
|
"viewer": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "did",
|
||||||
|
"description": "DID of the account making the request (not included for public/unauthenticated queries)."
|
||||||
|
},
|
||||||
|
"limit": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1,
|
||||||
|
"maximum": 50,
|
||||||
|
"default": 25
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"encoding": "application/json",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["dids"],
|
||||||
|
"properties": {
|
||||||
|
"dids": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "did"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"recIdStr": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Snowflake for this recommendation, use when submitting recommendation events."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
"lexicon": 1,
|
||||||
|
"id": "app.bsky.unspecced.getSuggestedUsersForExplore",
|
||||||
|
"defs": {
|
||||||
|
"main": {
|
||||||
|
"type": "query",
|
||||||
|
"description": "Get a list of suggested users for the Explore page",
|
||||||
|
"parameters": {
|
||||||
|
"type": "params",
|
||||||
|
"properties": {
|
||||||
|
"category": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Category of users to get suggestions for."
|
||||||
|
},
|
||||||
|
"limit": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1,
|
||||||
|
"maximum": 50,
|
||||||
|
"default": 25
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"encoding": "application/json",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["actors"],
|
||||||
|
"properties": {
|
||||||
|
"actors": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "ref",
|
||||||
|
"ref": "app.bsky.actor.defs#profileView"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"recIdStr": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Snowflake for this recommendation, use when submitting recommendation events."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"lexicon": 1,
|
||||||
|
"id": "app.bsky.unspecced.getSuggestedUsersForExploreSkeleton",
|
||||||
|
"defs": {
|
||||||
|
"main": {
|
||||||
|
"type": "query",
|
||||||
|
"description": "Get a skeleton of suggested users for the Explore page. Intended to be called and hydrated by app.bsky.unspecced.getSuggestedUsersForExplore",
|
||||||
|
"parameters": {
|
||||||
|
"type": "params",
|
||||||
|
"properties": {
|
||||||
|
"viewer": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "did",
|
||||||
|
"description": "DID of the account making the request (not included for public/unauthenticated queries)."
|
||||||
|
},
|
||||||
|
"category": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Category of users to get suggestions for."
|
||||||
|
},
|
||||||
|
"limit": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1,
|
||||||
|
"maximum": 50,
|
||||||
|
"default": 25
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"encoding": "application/json",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["dids"],
|
||||||
|
"properties": {
|
||||||
|
"dids": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "did"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"recIdStr": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Snowflake for this recommendation, use when submitting recommendation events."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
"lexicon": 1,
|
||||||
|
"id": "app.bsky.unspecced.getSuggestedUsersForSeeMore",
|
||||||
|
"defs": {
|
||||||
|
"main": {
|
||||||
|
"type": "query",
|
||||||
|
"description": "Get a list of suggested users for the See More page",
|
||||||
|
"parameters": {
|
||||||
|
"type": "params",
|
||||||
|
"properties": {
|
||||||
|
"category": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Category of users to get suggestions for."
|
||||||
|
},
|
||||||
|
"limit": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1,
|
||||||
|
"maximum": 50,
|
||||||
|
"default": 25
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"encoding": "application/json",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["actors"],
|
||||||
|
"properties": {
|
||||||
|
"actors": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "ref",
|
||||||
|
"ref": "app.bsky.actor.defs#profileView"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"recIdStr": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Snowflake for this recommendation, use when submitting recommendation events."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"lexicon": 1,
|
||||||
|
"id": "app.bsky.unspecced.getSuggestedUsersForSeeMoreSkeleton",
|
||||||
|
"defs": {
|
||||||
|
"main": {
|
||||||
|
"type": "query",
|
||||||
|
"description": "Get a skeleton of suggested users for the See More page. Intended to be called and hydrated by app.bsky.unspecced.getSuggestedUsersForSeeMore",
|
||||||
|
"parameters": {
|
||||||
|
"type": "params",
|
||||||
|
"properties": {
|
||||||
|
"viewer": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "did",
|
||||||
|
"description": "DID of the account making the request (not included for public/unauthenticated queries)."
|
||||||
|
},
|
||||||
|
"category": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Category of users to get suggestions for."
|
||||||
|
},
|
||||||
|
"limit": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1,
|
||||||
|
"maximum": 50,
|
||||||
|
"default": 25
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"encoding": "application/json",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["dids"],
|
||||||
|
"properties": {
|
||||||
|
"dids": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "did"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"recIdStr": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Snowflake for this recommendation, use when submitting recommendation events."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
{
|
||||||
|
"lexicon": 1,
|
||||||
|
"id": "com.atproto.temp.checkHandleAvailability",
|
||||||
|
"defs": {
|
||||||
|
"main": {
|
||||||
|
"type": "query",
|
||||||
|
"description": "Checks whether the provided handle is available. If the handle is not available, available suggestions will be returned. Optional inputs will be used to generate suggestions.",
|
||||||
|
"parameters": {
|
||||||
|
"type": "params",
|
||||||
|
"required": ["handle"],
|
||||||
|
"properties": {
|
||||||
|
"handle": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "handle",
|
||||||
|
"description": "Tentative handle. Will be checked for availability or used to build handle suggestions."
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "User-provided email. Might be used to build handle suggestions."
|
||||||
|
},
|
||||||
|
"birthDate": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "datetime",
|
||||||
|
"description": "User-provided birth date. Might be used to build handle suggestions."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"encoding": "application/json",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["handle", "result"],
|
||||||
|
"properties": {
|
||||||
|
"handle": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "handle",
|
||||||
|
"description": "Echo of the input handle."
|
||||||
|
},
|
||||||
|
"result": {
|
||||||
|
"type": "union",
|
||||||
|
"refs": ["#resultAvailable", "#resultUnavailable"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"errors": [
|
||||||
|
{
|
||||||
|
"name": "InvalidEmail",
|
||||||
|
"description": "An invalid email was provided."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"resultAvailable": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Indicates the provided handle is available.",
|
||||||
|
"properties": {}
|
||||||
|
},
|
||||||
|
"resultUnavailable": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Indicates the provided handle is unavailable and gives suggestions of available handles.",
|
||||||
|
"required": ["suggestions"],
|
||||||
|
"properties": {
|
||||||
|
"suggestions": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "List of suggested handles based on the provided inputs.",
|
||||||
|
"items": {
|
||||||
|
"type": "ref",
|
||||||
|
"ref": "#suggestion"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"suggestion": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["handle", "method"],
|
||||||
|
"properties": {
|
||||||
|
"handle": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "handle"
|
||||||
|
},
|
||||||
|
"method": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Method used to build this suggestion. Should be considered opaque to clients. Can be used for metrics."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"lexicon": 1,
|
||||||
|
"id": "com.atproto.temp.checkSignupQueue",
|
||||||
|
"defs": {
|
||||||
|
"main": {
|
||||||
|
"type": "query",
|
||||||
|
"description": "Check accounts location in signup queue.",
|
||||||
|
"output": {
|
||||||
|
"encoding": "application/json",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["activated"],
|
||||||
|
"properties": {
|
||||||
|
"activated": { "type": "boolean" },
|
||||||
|
"placeInQueue": { "type": "integer" },
|
||||||
|
"estimatedTimeMs": { "type": "integer" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -62,7 +62,6 @@ export function useAutocomplete({
|
|||||||
key: profile.did,
|
key: profile.did,
|
||||||
type: 'profile' as const,
|
type: 'profile' as const,
|
||||||
value: '@' + profile.handle,
|
value: '@' + profile.handle,
|
||||||
// TODO(phase4): drop toLex once searchActorsTypeahead (bridge agent)
|
|
||||||
// emits #/lexicons views
|
// emits #/lexicons views
|
||||||
profile: toLex<AutocompleteProfile['profile']>(profile),
|
profile: toLex<AutocompleteProfile['profile']>(profile),
|
||||||
}))
|
}))
|
||||||
@@ -134,10 +133,7 @@ function moderateProfileItem({
|
|||||||
item: AutocompleteProfile
|
item: AutocompleteProfile
|
||||||
moderationOpts: ModerationOpts
|
moderationOpts: ModerationOpts
|
||||||
}) {
|
}) {
|
||||||
// TODO(phase4): drop toLex once searchActorsTypeahead emits #/lexicons views
|
const modui = moderateProfile(item.profile, moderationOpts).ui('profileList')
|
||||||
const modui = moderateProfile(toLex(item.profile), moderationOpts).ui(
|
|
||||||
'profileList',
|
|
||||||
)
|
|
||||||
const isExactMatch = query && item.profile.handle.toLowerCase() === query
|
const isExactMatch = query && item.profile.handle.toLowerCase() === query
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import {UserAvatar} from '#/view/com/util/UserAvatar'
|
|||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
import {Person_Filled_Corner2_Rounded as PersonIcon} from '#/components/icons/Person'
|
import {Person_Filled_Corner2_Rounded as PersonIcon} from '#/components/icons/Person'
|
||||||
import type * as bsky from '#/types/bsky'
|
import type * as bsky from '#/types/bsky'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
|
|
||||||
type Layout = {
|
type Layout = {
|
||||||
size: number
|
size: number
|
||||||
@@ -163,10 +162,7 @@ function AvatarBubble({
|
|||||||
type="user"
|
type="user"
|
||||||
hideLiveBadge
|
hideLiveBadge
|
||||||
noBorder
|
noBorder
|
||||||
// TODO(phase4): drop toLex once profile props emit #/lexicons views
|
moderation={moderateProfile(profile, moderationOpts).ui('avatar')}
|
||||||
moderation={moderateProfile(toLex(profile), moderationOpts).ui(
|
|
||||||
'avatar',
|
|
||||||
)}
|
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<AvatarPlaceholder size={size} />
|
<AvatarPlaceholder size={size} />
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import {useProfilesQuery} from '#/state/queries/profile'
|
|||||||
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
import type * as bsky from '#/types/bsky'
|
import type * as bsky from '#/types/bsky'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
|
|
||||||
export function AvatarStack({
|
export function AvatarStack({
|
||||||
profiles,
|
profiles,
|
||||||
@@ -35,8 +34,7 @@ export function AvatarStack({
|
|||||||
: profiles.map(item => ({
|
: profiles.map(item => ({
|
||||||
key: item.did,
|
key: item.did,
|
||||||
profile: item,
|
profile: item,
|
||||||
// TODO(phase4): drop toLex once useProfilesQuery emits #/lexicons views
|
moderation: moderateProfile(item, moderationOpts),
|
||||||
moderation: moderateProfile(toLex(item), moderationOpts),
|
|
||||||
}))
|
}))
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import {Link, type LinkProps} from '#/components/Link'
|
|||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {type app} from '#/lexicons'
|
import {type app} from '#/lexicons'
|
||||||
import type * as bsky from '#/types/bsky'
|
import type * as bsky from '#/types/bsky'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
|
|
||||||
const AVI_SIZE = 30
|
const AVI_SIZE = 30
|
||||||
const AVI_SIZE_SMALL = 20
|
const AVI_SIZE_SMALL = 20
|
||||||
@@ -96,8 +95,7 @@ function KnownFollowersInner({
|
|||||||
const textStyle = [a.text_sm, a.leading_snug, t.atoms.text_contrast_medium]
|
const textStyle = [a.text_sm, a.leading_snug, t.atoms.text_contrast_medium]
|
||||||
|
|
||||||
const slice = cachedKnownFollowers.followers.slice(0, 3).map(f => {
|
const slice = cachedKnownFollowers.followers.slice(0, 3).map(f => {
|
||||||
// TODO(phase4): drop toLex once KnownFollowers emits #/lexicons views
|
const moderation = moderateProfile(f, moderationOpts)
|
||||||
const moderation = moderateProfile(toLex(f), moderationOpts)
|
|
||||||
return {
|
return {
|
||||||
profile: {
|
profile: {
|
||||||
...f,
|
...f,
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import * as Hider from '#/components/moderation/Hider'
|
|||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {type app} from '#/lexicons'
|
import {type app} from '#/lexicons'
|
||||||
import type * as bsky from '#/types/bsky'
|
import type * as bsky from '#/types/bsky'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This component is based on `FeedCard` and is tightly coupled with that
|
* This component is based on `FeedCard` and is tightly coupled with that
|
||||||
@@ -55,8 +54,7 @@ export function Default(
|
|||||||
const {view, showPinButton} = props
|
const {view, showPinButton} = props
|
||||||
const moderationOpts = useModerationOpts()
|
const moderationOpts = useModerationOpts()
|
||||||
const moderation = moderationOpts
|
const moderation = moderationOpts
|
||||||
? // TODO(phase4): drop toLex once ListView props emit #/lexicons views
|
? moderateUserList(view, moderationOpts)
|
||||||
moderateUserList(toLex(view), moderationOpts)
|
|
||||||
: undefined
|
: undefined
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import * as StarterPackCard from '#/components/StarterPack/StarterPackCard'
|
|||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {IS_NATIVE} from '#/env'
|
import {IS_NATIVE} from '#/env'
|
||||||
import {type app} from '#/lexicons'
|
import {type app} from '#/lexicons'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
|
|
||||||
export function NewskieDialog({
|
export function NewskieDialog({
|
||||||
profile,
|
profile,
|
||||||
@@ -90,8 +89,7 @@ function DialogInner({
|
|||||||
|
|
||||||
const profileName = useMemo(() => {
|
const profileName = useMemo(() => {
|
||||||
if (!moderationOpts) return profile.displayName || profile.handle
|
if (!moderationOpts) return profile.displayName || profile.handle
|
||||||
// TODO(phase4): drop toLex once ProfileViewDetailed prop emits #/lexicons views
|
const moderation = moderateProfile(profile, moderationOpts)
|
||||||
const moderation = moderateProfile(toLex(profile), moderationOpts)
|
|
||||||
return sanitizeDisplayName(
|
return sanitizeDisplayName(
|
||||||
profile.displayName || profile.handle,
|
profile.displayName || profile.handle,
|
||||||
moderation.ui('displayName'),
|
moderation.ui('displayName'),
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
|||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
import * as FeedCard from '#/components/FeedCard'
|
import * as FeedCard from '#/components/FeedCard'
|
||||||
import {ContentHider} from '#/components/moderation/ContentHider'
|
import {ContentHider} from '#/components/moderation/ContentHider'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
import {type EmbedType} from '#/types/bsky/post'
|
import {type EmbedType} from '#/types/bsky/post'
|
||||||
import {type CommonProps} from './types'
|
import {type CommonProps} from './types'
|
||||||
|
|
||||||
@@ -41,8 +40,7 @@ export function ModeratedFeedEmbed({
|
|||||||
const moderationOpts = useModerationOpts()
|
const moderationOpts = useModerationOpts()
|
||||||
const moderation = useMemo(() => {
|
const moderation = useMemo(() => {
|
||||||
return moderationOpts
|
return moderationOpts
|
||||||
? // TODO(phase4): drop toLex once feed embed view emits #/lexicons views
|
? moderateFeedGenerator(embed.view, moderationOpts)
|
||||||
moderateFeedGenerator(toLex(embed.view), moderationOpts)
|
|
||||||
: undefined
|
: undefined
|
||||||
}, [embed.view, moderationOpts])
|
}, [embed.view, moderationOpts])
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
|||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
import * as ListCard from '#/components/ListCard'
|
import * as ListCard from '#/components/ListCard'
|
||||||
import {ContentHider} from '#/components/moderation/ContentHider'
|
import {ContentHider} from '#/components/moderation/ContentHider'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
import {type EmbedType} from '#/types/bsky/post'
|
import {type EmbedType} from '#/types/bsky/post'
|
||||||
import {type CommonProps} from './types'
|
import {type CommonProps} from './types'
|
||||||
|
|
||||||
@@ -31,8 +30,7 @@ export function ModeratedListEmbed({
|
|||||||
const moderationOpts = useModerationOpts()
|
const moderationOpts = useModerationOpts()
|
||||||
const moderation = useMemo(() => {
|
const moderation = useMemo(() => {
|
||||||
return moderationOpts
|
return moderationOpts
|
||||||
? // TODO(phase4): drop toLex once list embed view emits #/lexicons views
|
? moderateUserList(embed.view, moderationOpts)
|
||||||
moderateUserList(toLex(embed.view), moderationOpts)
|
|
||||||
: undefined
|
: undefined
|
||||||
}, [embed.view, moderationOpts])
|
}, [embed.view, moderationOpts])
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -268,9 +268,7 @@ export function QuoteEmbed({
|
|||||||
[embed],
|
[embed],
|
||||||
)
|
)
|
||||||
const moderation = useMemo(() => {
|
const moderation = useMemo(() => {
|
||||||
return moderationOpts
|
return moderationOpts ? moderatePost(quote, moderationOpts) : undefined
|
||||||
? moderatePost(bsky.toLex(quote), moderationOpts)
|
|
||||||
: undefined
|
|
||||||
}, [quote, moderationOpts])
|
}, [quote, moderationOpts])
|
||||||
|
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import {ProfileBadges} from '#/components/ProfileBadges'
|
|||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {useAnalytics} from '#/analytics'
|
import {useAnalytics} from '#/analytics'
|
||||||
import {type chat} from '#/lexicons'
|
import {type chat} from '#/lexicons'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
|
|
||||||
export function RecentChats({
|
export function RecentChats({
|
||||||
postUri,
|
postUri,
|
||||||
@@ -121,8 +120,7 @@ function RecentChatItem({
|
|||||||
|
|
||||||
const primaryProfile = useProfileShadow(primaryMember)
|
const primaryProfile = useProfileShadow(primaryMember)
|
||||||
|
|
||||||
// TODO(phase4): drop toLex once useProfileShadow emits #/lexicons views
|
const moderation = moderateProfile(primaryProfile, moderationOpts)
|
||||||
const moderation = moderateProfile(toLex(primaryProfile), moderationOpts)
|
|
||||||
const name =
|
const name =
|
||||||
convo.kind === 'group'
|
convo.kind === 'group'
|
||||||
? convo.details.name
|
? convo.details.name
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ import * as Toast from '#/components/Toast'
|
|||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {type Metrics} from '#/analytics'
|
import {type Metrics} from '#/analytics'
|
||||||
import {useActorStatus} from '#/features/liveNow'
|
import {useActorStatus} from '#/features/liveNow'
|
||||||
import * as bsky from '#/types/bsky'
|
import type * as bsky from '#/types/bsky'
|
||||||
|
|
||||||
export function Default({
|
export function Default({
|
||||||
profile,
|
profile,
|
||||||
@@ -170,7 +170,7 @@ export function Avatar({
|
|||||||
liveOverride?: boolean
|
liveOverride?: boolean
|
||||||
size?: number
|
size?: number
|
||||||
}) {
|
}) {
|
||||||
const moderation = moderateProfile(bsky.toLex(profile), moderationOpts)
|
const moderation = moderateProfile(profile, moderationOpts)
|
||||||
|
|
||||||
const {isActive: live} = useActorStatus(profile)
|
const {isActive: live} = useActorStatus(profile)
|
||||||
|
|
||||||
@@ -240,7 +240,7 @@ function InlineNameAndHandle({
|
|||||||
moderationOpts: ModerationOpts
|
moderationOpts: ModerationOpts
|
||||||
}) {
|
}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const moderation = moderateProfile(bsky.toLex(profile), moderationOpts)
|
const moderation = moderateProfile(profile, moderationOpts)
|
||||||
const name = sanitizeDisplayName(
|
const name = sanitizeDisplayName(
|
||||||
profile.displayName || sanitizeHandle(profile.handle),
|
profile.displayName || sanitizeHandle(profile.handle),
|
||||||
moderation.ui('displayName'),
|
moderation.ui('displayName'),
|
||||||
@@ -294,7 +294,7 @@ export function Name({
|
|||||||
style?: StyleProp<ViewStyle>
|
style?: StyleProp<ViewStyle>
|
||||||
textStyle?: StyleProp<TextStyle>
|
textStyle?: StyleProp<TextStyle>
|
||||||
}) {
|
}) {
|
||||||
const moderation = moderateProfile(bsky.toLex(profile), moderationOpts)
|
const moderation = moderateProfile(profile, moderationOpts)
|
||||||
const name = sanitizeDisplayName(
|
const name = sanitizeDisplayName(
|
||||||
profile.displayName || sanitizeHandle(profile.handle),
|
profile.displayName || sanitizeHandle(profile.handle),
|
||||||
moderation.ui('displayName'),
|
moderation.ui('displayName'),
|
||||||
@@ -479,7 +479,7 @@ export function FollowButtonInner({
|
|||||||
}: FollowButtonProps) {
|
}: FollowButtonProps) {
|
||||||
const {t: l} = useLingui()
|
const {t: l} = useLingui()
|
||||||
const profile = useProfileShadow(profileUnshadowed)
|
const profile = useProfileShadow(profileUnshadowed)
|
||||||
const moderation = moderateProfile(bsky.toLex(profile), moderationOpts)
|
const moderation = moderateProfile(profile, moderationOpts)
|
||||||
const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue(
|
const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue(
|
||||||
profile,
|
profile,
|
||||||
logContext,
|
logContext,
|
||||||
@@ -617,7 +617,7 @@ export function Labels({
|
|||||||
profile: bsky.profile.AnyProfileView
|
profile: bsky.profile.AnyProfileView
|
||||||
moderationOpts: ModerationOpts
|
moderationOpts: ModerationOpts
|
||||||
}) {
|
}) {
|
||||||
const moderation = moderateProfile(bsky.toLex(profile), moderationOpts)
|
const moderation = moderateProfile(profile, moderationOpts)
|
||||||
const modui = moderation.ui('profileList')
|
const modui = moderation.ui('profileList')
|
||||||
const followedBy = profile.viewer?.followedBy
|
const followedBy = profile.viewer?.followedBy
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ import {IS_WEB_TOUCH_DEVICE} from '#/env'
|
|||||||
import {useActorStatus} from '#/features/liveNow'
|
import {useActorStatus} from '#/features/liveNow'
|
||||||
import {LiveStatus} from '#/features/liveNow/components/LiveStatusDialog'
|
import {LiveStatus} from '#/features/liveNow/components/LiveStatusDialog'
|
||||||
import {type app} from '#/lexicons'
|
import {type app} from '#/lexicons'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
import {type ProfileHoverCardProps} from './types'
|
import {type ProfileHoverCardProps} from './types'
|
||||||
|
|
||||||
const floatingMiddlewares = [
|
const floatingMiddlewares = [
|
||||||
@@ -424,8 +423,7 @@ function Inner({
|
|||||||
const {_, i18n} = useLingui()
|
const {_, i18n} = useLingui()
|
||||||
const {currentAccount} = useSession()
|
const {currentAccount} = useSession()
|
||||||
const moderation = useMemo(
|
const moderation = useMemo(
|
||||||
// TODO(phase4): drop toLex once ProfileViewDetailed prop emits #/lexicons views
|
() => moderateProfile(profile, moderationOpts),
|
||||||
() => moderateProfile(toLex(profile), moderationOpts),
|
|
||||||
[profile, moderationOpts],
|
[profile, moderationOpts],
|
||||||
)
|
)
|
||||||
const [descriptionRT] = useRichText(profile.description ?? '')
|
const [descriptionRT] = useRichText(profile.description ?? '')
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import {Text} from '#/components/Typography'
|
|||||||
import {useAnalytics} from '#/analytics'
|
import {useAnalytics} from '#/analytics'
|
||||||
import {type app} from '#/lexicons'
|
import {type app} from '#/lexicons'
|
||||||
import type * as bsky from '#/types/bsky'
|
import type * as bsky from '#/types/bsky'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
|
|
||||||
function WizardListCard({
|
function WizardListCard({
|
||||||
type,
|
type,
|
||||||
@@ -140,10 +139,7 @@ export function WizardProfileCard({
|
|||||||
const included = isTarget || state.profiles.some(p => p.did === profile.did)
|
const included = isTarget || state.profiles.some(p => p.did === profile.did)
|
||||||
const disabled =
|
const disabled =
|
||||||
isTarget || (!included && state.profiles.length >= STARTER_PACK_MAX_SIZE)
|
isTarget || (!included && state.profiles.length >= STARTER_PACK_MAX_SIZE)
|
||||||
// TODO(phase4): drop toLex once profile prop emits #/lexicons views
|
const moderationUi = moderateProfile(profile, moderationOpts).ui('avatar')
|
||||||
const moderationUi = moderateProfile(toLex(profile), moderationOpts).ui(
|
|
||||||
'avatar',
|
|
||||||
)
|
|
||||||
const displayName = profile.displayName
|
const displayName = profile.displayName
|
||||||
? sanitizeDisplayName(profile.displayName)
|
? sanitizeDisplayName(profile.displayName)
|
||||||
: `@${sanitizeHandle(profile.handle)}`
|
: `@${sanitizeHandle(profile.handle)}`
|
||||||
@@ -194,11 +190,9 @@ export function WizardFeedCard({
|
|||||||
const isDiscover = generator.uri === DISCOVER_FEED_URI
|
const isDiscover = generator.uri === DISCOVER_FEED_URI
|
||||||
const included = isDiscover || state.feeds.some(f => f.uri === generator.uri)
|
const included = isDiscover || state.feeds.some(f => f.uri === generator.uri)
|
||||||
const disabled = isDiscover || (!included && state.feeds.length >= 3)
|
const disabled = isDiscover || (!included && state.feeds.length >= 3)
|
||||||
// TODO(phase4): drop toLex once GeneratorView prop emits #/lexicons views
|
const moderationUi = moderateFeedGenerator(generator, moderationOpts).ui(
|
||||||
const moderationUi = moderateFeedGenerator(
|
'avatar',
|
||||||
toLex(generator),
|
)
|
||||||
moderationOpts,
|
|
||||||
).ui('avatar')
|
|
||||||
|
|
||||||
const onPress = () => {
|
const onPress = () => {
|
||||||
if (disabled) return
|
if (disabled) return
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ import * as ProfileCard from '#/components/ProfileCard'
|
|||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {IS_WEB} from '#/env'
|
import {IS_WEB} from '#/env'
|
||||||
import type * as bsky from '#/types/bsky'
|
import type * as bsky from '#/types/bsky'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
import {AvatarBubbles} from '../AvatarBubbles'
|
import {AvatarBubbles} from '../AvatarBubbles'
|
||||||
import {Error} from '../Error'
|
import {Error} from '../Error'
|
||||||
import {ProfileBadges} from '../ProfileBadges'
|
import {ProfileBadges} from '../ProfileBadges'
|
||||||
@@ -411,8 +410,7 @@ function DefaultProfileCard({
|
|||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {t: l} = useLingui()
|
const {t: l} = useLingui()
|
||||||
const enabled = canBeMessaged(profile)
|
const enabled = canBeMessaged(profile)
|
||||||
// TODO(phase4): drop toLex once profile prop emits #/lexicons views
|
const moderation = moderateProfile(profile, moderationOpts)
|
||||||
const moderation = moderateProfile(toLex(profile), moderationOpts)
|
|
||||||
const handle = sanitizeHandle(profile.handle, '@')
|
const handle = sanitizeHandle(profile.handle, '@')
|
||||||
const displayName = createSanitizedDisplayName(
|
const displayName = createSanitizedDisplayName(
|
||||||
profile,
|
profile,
|
||||||
@@ -488,8 +486,7 @@ function ExistingChatCard({
|
|||||||
: createSanitizedDisplayName(
|
: createSanitizedDisplayName(
|
||||||
convo.primaryMember,
|
convo.primaryMember,
|
||||||
true,
|
true,
|
||||||
// TODO(phase4): drop toLex once convo primaryMember emits #/lexicons views
|
moderateProfile(convo.primaryMember, moderationOpts).ui(
|
||||||
moderateProfile(toLex(convo.primaryMember), moderationOpts).ui(
|
|
||||||
'displayName',
|
'displayName',
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import * as Toast from '#/components/Toast'
|
|||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {IS_WEB} from '#/env'
|
import {IS_WEB} from '#/env'
|
||||||
import {type app} from '#/lexicons'
|
import {type app} from '#/lexicons'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
|
|
||||||
const DISPLAY_NAME_MAX_GRAPHEMES = 64
|
const DISPLAY_NAME_MAX_GRAPHEMES = 64
|
||||||
const DESCRIPTION_MAX_GRAPHEMES = 300
|
const DESCRIPTION_MAX_GRAPHEMES = 300
|
||||||
@@ -165,9 +164,8 @@ function DialogInner({
|
|||||||
|
|
||||||
// We want to be working with a blank state here, so let's get the
|
// We want to be working with a blank state here, so let's get the
|
||||||
// serialized version and turn it back into a RichText
|
// serialized version and turn it back into a RichText
|
||||||
// TODO(phase4): drop toLex once the list view producer emits #/lexicons facets
|
|
||||||
const serialized = richTextToString(
|
const serialized = richTextToString(
|
||||||
new RichTextAPI({text, facets: toLex(facets)}),
|
new RichTextAPI({text, facets: facets}),
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import {TimesLarge_Stroke2_Corner0_Rounded as XIcon} from '#/components/icons/Ti
|
|||||||
import * as ProfileCard from '#/components/ProfileCard'
|
import * as ProfileCard from '#/components/ProfileCard'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import type * as bsky from '#/types/bsky'
|
import type * as bsky from '#/types/bsky'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
testID?: string
|
testID?: string
|
||||||
@@ -90,8 +89,7 @@ function Tab({
|
|||||||
const {t: l} = useLingui()
|
const {t: l} = useLingui()
|
||||||
const moderationOpts = useModerationOpts()
|
const moderationOpts = useModerationOpts()
|
||||||
|
|
||||||
// TODO(phase4): drop toLex once profile prop emits #/lexicons views
|
const moderation = moderateProfile(profile, moderationOpts!)
|
||||||
const moderation = moderateProfile(toLex(profile), moderationOpts!)
|
|
||||||
const displayName = sanitizeDisplayName(
|
const displayName = sanitizeDisplayName(
|
||||||
profile.displayName || sanitizeHandle(profile.handle),
|
profile.displayName || sanitizeHandle(profile.handle),
|
||||||
moderation.ui('displayName'),
|
moderation.ui('displayName'),
|
||||||
|
|||||||
@@ -54,7 +54,6 @@ import {Text} from '#/components/Typography'
|
|||||||
import {useAgeAssurance} from '#/ageAssurance'
|
import {useAgeAssurance} from '#/ageAssurance'
|
||||||
import {IS_NATIVE, IS_WEB} from '#/env'
|
import {IS_NATIVE, IS_WEB} from '#/env'
|
||||||
import type * as bsky from '#/types/bsky'
|
import type * as bsky from '#/types/bsky'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
|
|
||||||
type NewGroupChatItem = {
|
type NewGroupChatItem = {
|
||||||
type: 'newGroupChat'
|
type: 'newGroupChat'
|
||||||
@@ -1071,8 +1070,7 @@ function DefaultProfileCard({
|
|||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {t: l} = useLingui()
|
const {t: l} = useLingui()
|
||||||
const enabled = canBeMessaged(profile)
|
const enabled = canBeMessaged(profile)
|
||||||
// TODO(phase4): drop toLex once profile prop emits #/lexicons views
|
const moderation = moderateProfile(profile, moderationOpts)
|
||||||
const moderation = moderateProfile(toLex(profile), moderationOpts)
|
|
||||||
const handle = sanitizeHandle(profile.handle, '@')
|
const handle = sanitizeHandle(profile.handle, '@')
|
||||||
const displayName = sanitizeDisplayName(
|
const displayName = sanitizeDisplayName(
|
||||||
profile.displayName || sanitizeHandle(profile.handle),
|
profile.displayName || sanitizeHandle(profile.handle),
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import {useAnalytics} from '#/analytics'
|
|||||||
import {IS_NATIVE} from '#/env'
|
import {IS_NATIVE} from '#/env'
|
||||||
import {type chat} from '#/lexicons'
|
import {type chat} from '#/lexicons'
|
||||||
import type * as bsky from '#/types/bsky'
|
import type * as bsky from '#/types/bsky'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
import {EmojiReactionPicker} from './EmojiReactionPicker'
|
import {EmojiReactionPicker} from './EmojiReactionPicker'
|
||||||
import {canReact, hasReachedReactionLimit} from './util'
|
import {canReact, hasReachedReactionLimit} from './util'
|
||||||
|
|
||||||
@@ -87,8 +86,7 @@ export let MessageContextMenu = ({
|
|||||||
const str = richTextToString(
|
const str = richTextToString(
|
||||||
new RichText({
|
new RichText({
|
||||||
text: message.text,
|
text: message.text,
|
||||||
// TODO(phase4): drop toLex once the message producer emits #/lexicons facets
|
facets: message.facets,
|
||||||
facets: toLex(message.facets),
|
|
||||||
}),
|
}),
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -344,9 +344,7 @@ let MessageItem = ({
|
|||||||
size={AVATAR_SIZE}
|
size={AVATAR_SIZE}
|
||||||
type={profile.associated?.labeler ? 'labeler' : 'user'}
|
type={profile.associated?.labeler ? 'labeler' : 'user'}
|
||||||
onBeforePress={() => unstableCacheProfileView(queryClient, profile)}
|
onBeforePress={() => unstableCacheProfileView(queryClient, profile)}
|
||||||
moderation={moderateProfile(bsky.toLex(profile), moderationOpts).ui(
|
moderation={moderateProfile(profile, moderationOpts).ui('avatar')}
|
||||||
'avatar',
|
|
||||||
)}
|
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<ProfileCard.AvatarPlaceholder size={AVATAR_SIZE} />
|
<ProfileCard.AvatarPlaceholder size={AVATAR_SIZE} />
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import {Link} from '#/components/Link'
|
|||||||
import {ProfileBadges} from '#/components/ProfileBadges'
|
import {ProfileBadges} from '#/components/ProfileBadges'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {IS_LIQUID_GLASS} from '#/env'
|
import {IS_LIQUID_GLASS} from '#/env'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
import {type ConvoWithDetails} from './util'
|
import {type ConvoWithDetails} from './util'
|
||||||
|
|
||||||
const PFP_SIZE = 40
|
const PFP_SIZE = 40
|
||||||
@@ -86,8 +85,7 @@ function ProfileHeaderReady({
|
|||||||
const {t: l} = useLingui()
|
const {t: l} = useLingui()
|
||||||
const profile = useProfileShadow(convo.primaryMember)
|
const profile = useProfileShadow(convo.primaryMember)
|
||||||
|
|
||||||
// TODO(phase4): drop toLex once useProfileShadow emits #/lexicons views
|
const moderation = moderateProfile(profile, moderationOpts)
|
||||||
const moderation = moderateProfile(toLex(profile), moderationOpts)
|
|
||||||
|
|
||||||
const blockInfo = useMemo(() => {
|
const blockInfo = useMemo(() => {
|
||||||
const modui = moderation.ui('profileView')
|
const modui = moderation.ui('profileView')
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import * as Toggle from '#/components/forms/Toggle'
|
|||||||
import * as ProfileCard from '#/components/ProfileCard'
|
import * as ProfileCard from '#/components/ProfileCard'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import type * as bsky from '#/types/bsky'
|
import type * as bsky from '#/types/bsky'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
|
|
||||||
export function GroupChatProfileCard({
|
export function GroupChatProfileCard({
|
||||||
profile,
|
profile,
|
||||||
@@ -21,8 +20,7 @@ export function GroupChatProfileCard({
|
|||||||
}) {
|
}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const enabled = canBeAddedToGroup(profile)
|
const enabled = canBeAddedToGroup(profile)
|
||||||
// TODO(phase4): drop toLex once profile prop emits #/lexicons views
|
const moderation = moderateProfile(profile, moderationOpts)
|
||||||
const moderation = moderateProfile(toLex(profile), moderationOpts)
|
|
||||||
const handle = sanitizeHandle(profile.handle, '@')
|
const handle = sanitizeHandle(profile.handle, '@')
|
||||||
const displayName = sanitizeDisplayName(
|
const displayName = sanitizeDisplayName(
|
||||||
profile.displayName || sanitizeHandle(profile.handle),
|
profile.displayName || sanitizeHandle(profile.handle),
|
||||||
|
|||||||
@@ -154,10 +154,7 @@ export function canReact({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (primaryMember && moderationOpts) {
|
if (primaryMember && moderationOpts) {
|
||||||
const moderation = moderateProfile(
|
const moderation = moderateProfile(primaryMember, moderationOpts)
|
||||||
bsky.toLex(primaryMember),
|
|
||||||
moderationOpts,
|
|
||||||
)
|
|
||||||
if (convoState.convo.kind === 'direct') {
|
if (convoState.convo.kind === 'direct') {
|
||||||
// Either direction (blocking or blocked-by) hides reactions in 1-1s
|
// Either direction (blocking or blocked-by) hides reactions in 1-1s
|
||||||
if (moderation.blocked) return false
|
if (moderation.blocked) return false
|
||||||
|
|||||||
@@ -395,11 +395,9 @@ function GroupChatJoinDialogContent({code}: {code?: string}) {
|
|||||||
{createSanitizedDisplayName(
|
{createSanitizedDisplayName(
|
||||||
joinLinkPreview.owner,
|
joinLinkPreview.owner,
|
||||||
true,
|
true,
|
||||||
// TODO(phase4): drop toLex once join link preview emits #/lexicons views
|
moderateProfile(joinLinkPreview.owner, moderationOpts).ui(
|
||||||
moderateProfile(
|
'displayName',
|
||||||
bsky.toLex(joinLinkPreview.owner),
|
),
|
||||||
moderationOpts,
|
|
||||||
).ui('displayName'),
|
|
||||||
)}
|
)}
|
||||||
</InlineLinkText>
|
</InlineLinkText>
|
||||||
</Trans>
|
</Trans>
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import {
|
|||||||
} from '#/components/moderation/LabelsOnMeDialog'
|
} from '#/components/moderation/LabelsOnMeDialog'
|
||||||
import * as Pills from '#/components/Pills'
|
import * as Pills from '#/components/Pills'
|
||||||
import {type app, type com} from '#/lexicons'
|
import {type app, type com} from '#/lexicons'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
|
|
||||||
export function PostAlerts({
|
export function PostAlerts({
|
||||||
post,
|
post,
|
||||||
@@ -68,8 +67,7 @@ export function PostAlerts({
|
|||||||
*/
|
*/
|
||||||
const shownCauses = [...alerts, ...informs, ...modui.blurs]
|
const shownCauses = [...alerts, ...informs, ...modui.blurs]
|
||||||
const additionalLabels = filterUserFacingLabels(
|
const additionalLabels = filterUserFacingLabels(
|
||||||
// TODO(phase4): drop toLex once PostView labels are #/lexicons-typed
|
allLabels,
|
||||||
toLex(allLabels),
|
|
||||||
currentAccount?.did,
|
currentAccount?.did,
|
||||||
).filter(label =>
|
).filter(label =>
|
||||||
shownCauses.every(
|
shownCauses.every(
|
||||||
|
|||||||
@@ -24,21 +24,7 @@ export function parseReportSubject(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
const subject = rawSubject
|
||||||
* TODO(phase4): drop toLex once ReportSubject is a #/lexicons union. The view
|
|
||||||
* subjects are structurally the #/lexicons shapes; we bridge here so the
|
|
||||||
* `isType` schema guards below narrow against the lexicon `$type`s.
|
|
||||||
*/
|
|
||||||
const subject = bsky.toLex<
|
|
||||||
| app.bsky.actor.defs.ProfileViewBasic
|
|
||||||
| app.bsky.actor.defs.ProfileView
|
|
||||||
| app.bsky.actor.defs.ProfileViewDetailed
|
|
||||||
| app.bsky.actor.defs.StatusView
|
|
||||||
| app.bsky.graph.defs.ListView
|
|
||||||
| app.bsky.feed.defs.GeneratorView
|
|
||||||
| app.bsky.graph.defs.StarterPackView
|
|
||||||
| app.bsky.feed.defs.PostView
|
|
||||||
>(rawSubject)
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
bsky.isType(app.bsky.actor.defs.profileViewBasic, subject) ||
|
bsky.isType(app.bsky.actor.defs.profileViewBasic, subject) ||
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import {Loader} from '#/components/Loader'
|
|||||||
import * as Toast from '#/components/Toast'
|
import * as Toast from '#/components/Toast'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {type app, com, tools} from '#/lexicons'
|
import {type app, com, tools} from '#/lexicons'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
|
|
||||||
export function GoLiveDisabledDialog({
|
export function GoLiveDisabledDialog({
|
||||||
control,
|
control,
|
||||||
@@ -60,7 +59,7 @@ export function DialogInner({
|
|||||||
} else {
|
} else {
|
||||||
await pdsClient.call(
|
await pdsClient.call(
|
||||||
com.atproto.moderation.createReport,
|
com.atproto.moderation.createReport,
|
||||||
toLex<com.atproto.moderation.createReport.$InputBody>({
|
{
|
||||||
reasonType: tools.ozone.report.defs.reasonAppeal.value,
|
reasonType: tools.ozone.report.defs.reasonAppeal.value,
|
||||||
subject: {
|
subject: {
|
||||||
$type: 'com.atproto.repo.strongRef',
|
$type: 'com.atproto.repo.strongRef',
|
||||||
@@ -68,7 +67,7 @@ export function DialogInner({
|
|||||||
cid: status.cid,
|
cid: status.cid,
|
||||||
},
|
},
|
||||||
reason: details,
|
reason: details,
|
||||||
}),
|
},
|
||||||
{
|
{
|
||||||
service: api.moderation.service,
|
service: api.moderation.service,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import {Text} from '#/components/Typography'
|
|||||||
import {useAnalytics} from '#/analytics'
|
import {useAnalytics} from '#/analytics'
|
||||||
import {LiveIndicator} from '#/features/liveNow/components/LiveIndicator'
|
import {LiveIndicator} from '#/features/liveNow/components/LiveIndicator'
|
||||||
import {type app} from '#/lexicons'
|
import {type app} from '#/lexicons'
|
||||||
import * as bsky from '#/types/bsky'
|
import type * as bsky from '#/types/bsky'
|
||||||
|
|
||||||
export function LiveStatusDialog({
|
export function LiveStatusDialog({
|
||||||
control,
|
control,
|
||||||
@@ -115,8 +115,7 @@ export function LiveStatus({
|
|||||||
const dialogContext = Dialog.useDialogContext()
|
const dialogContext = Dialog.useDialogContext()
|
||||||
const moderation = useMemo(() => {
|
const moderation = useMemo(() => {
|
||||||
if (!moderationOpts) return undefined
|
if (!moderationOpts) return undefined
|
||||||
// TODO(phase4): drop toLex once profile producers emit #/lexicons views
|
return moderateStatus(profile, moderationOpts)
|
||||||
return moderateStatus(bsky.toLex(profile), moderationOpts)
|
|
||||||
}, [profile, moderationOpts])
|
}, [profile, moderationOpts])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import {
|
|||||||
useMaybeProfileShadow,
|
useMaybeProfileShadow,
|
||||||
} from '#/state/cache/profile-shadow'
|
} from '#/state/cache/profile-shadow'
|
||||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||||
import {useAgent, usePdsClient, useSession} from '#/state/session'
|
import {usePdsClient, useSession} from '#/state/session'
|
||||||
import {useTickEveryMinute} from '#/state/shell'
|
import {useTickEveryMinute} from '#/state/shell'
|
||||||
import {useDialogContext} from '#/components/Dialog'
|
import {useDialogContext} from '#/components/Dialog'
|
||||||
import * as Toast from '#/components/Toast'
|
import * as Toast from '#/components/Toast'
|
||||||
@@ -105,8 +105,7 @@ export function useActorStatus(actor?: bsky.profile.AnyProfileView) {
|
|||||||
const moderation = useMemo(() => {
|
const moderation = useMemo(() => {
|
||||||
if (!actor || !('status' in actor && actor.status)) return undefined
|
if (!actor || !('status' in actor && actor.status)) return undefined
|
||||||
if (!moderationOpts) return undefined
|
if (!moderationOpts) return undefined
|
||||||
// TODO(phase4): drop toLex once profile producers emit #/lexicons views
|
return moderateStatus(actor, moderationOpts)
|
||||||
return moderateStatus(bsky.toLex(actor), moderationOpts)
|
|
||||||
}, [actor, moderationOpts])
|
}, [actor, moderationOpts])
|
||||||
|
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
@@ -120,12 +119,7 @@ export function useActorStatus(actor?: bsky.profile.AnyProfileView) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (shadowed && 'status' in shadowed && shadowed.status) {
|
if (shadowed && 'status' in shadowed && shadowed.status) {
|
||||||
/*
|
const status = shadowed.status
|
||||||
* TODO(phase4): drop toLex once profile-shadow emits #/lexicons views.
|
|
||||||
* The shadow store still holds old `@atproto/api` StatusViews, so brand
|
|
||||||
* it once here to feed the new-world validation and returned view.
|
|
||||||
*/
|
|
||||||
const status = bsky.toLex<app.bsky.actor.defs.StatusView>(shadowed.status)
|
|
||||||
const isValid = isStatusValidForViewers(status, config)
|
const isValid = isStatusValidForViewers(status, config)
|
||||||
const isDisabled = status.isDisabled || false
|
const isDisabled = status.isDisabled || false
|
||||||
const isActive = isStatusStillActive(status.expiresAt)
|
const isActive = isStatusStillActive(status.expiresAt)
|
||||||
@@ -195,7 +189,6 @@ export function useLiveLinkMetaQuery(url: string | null) {
|
|||||||
const liveNowConfig = useLiveNowConfig()
|
const liveNowConfig = useLiveNowConfig()
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
|
|
||||||
const agent = useAgent()
|
|
||||||
return useQuery({
|
return useQuery({
|
||||||
enabled: !!url,
|
enabled: !!url,
|
||||||
queryKey: ['link-meta', url],
|
queryKey: ['link-meta', url],
|
||||||
@@ -213,7 +206,7 @@ export function useLiveLinkMetaQuery(url: string | null) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return await getLinkMeta(agent, url)
|
return await getLinkMeta(url)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import {type Client} from '@atproto/lex-client'
|
|||||||
|
|
||||||
import {DEMO_FEED} from '#/lib/demo'
|
import {DEMO_FEED} from '#/lib/demo'
|
||||||
import {type app} from '#/lexicons'
|
import {type app} from '#/lexicons'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
import {type FeedAPI, type FeedAPIResponse} from './types'
|
import {type FeedAPI, type FeedAPIResponse} from './types'
|
||||||
|
|
||||||
export class DemoFeedAPI implements FeedAPI {
|
export class DemoFeedAPI implements FeedAPI {
|
||||||
@@ -12,17 +11,13 @@ export class DemoFeedAPI implements FeedAPI {
|
|||||||
this.client = client
|
this.client = client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/require-await
|
||||||
async peekLatest(): Promise<app.bsky.feed.defs.FeedViewPost> {
|
async peekLatest(): Promise<app.bsky.feed.defs.FeedViewPost> {
|
||||||
/*
|
return DEMO_FEED.feed[0]
|
||||||
* TODO(phase4): drop this cast once `#/lib/demo` (DEMO_FEED) sources its
|
|
||||||
* feed items from `#/lexicons`. Its records are still typed against the old
|
|
||||||
* `@atproto/api` FeedViewPost, which does not assign to the branded lexicon
|
|
||||||
* type this method must return.
|
|
||||||
*/
|
|
||||||
return toLex(DEMO_FEED.feed[0])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/require-await
|
||||||
async fetch(): Promise<FeedAPIResponse> {
|
async fetch(): Promise<FeedAPIResponse> {
|
||||||
return toLex(DEMO_FEED)
|
return DEMO_FEED
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import {feedUriToHref} from '#/lib/strings/url-helpers'
|
|||||||
import {getContentLanguages} from '#/state/preferences/languages'
|
import {getContentLanguages} from '#/state/preferences/languages'
|
||||||
import {type FeedParams} from '#/state/queries/post-feed'
|
import {type FeedParams} from '#/state/queries/post-feed'
|
||||||
import {app} from '#/lexicons'
|
import {app} from '#/lexicons'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
import {FeedTuner} from '../feed-manip'
|
import {FeedTuner} from '../feed-manip'
|
||||||
import {type FeedTunerFn} from '../feed-manip'
|
import {type FeedTunerFn} from '../feed-manip'
|
||||||
import {
|
import {
|
||||||
@@ -264,13 +263,7 @@ class MergeFeedSource_Following extends MergeFeedSource {
|
|||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
cursor: res.cursor,
|
cursor: res.cursor,
|
||||||
/*
|
feed: slices.map(slice => slice._feedPost),
|
||||||
* TODO(phase4): drop the toLex once `#/lib/api/feed-manip` (FeedTuner)
|
|
||||||
* flips its FeedViewPost source from `@atproto/api` to `#/lexicons`. Its
|
|
||||||
* `_feedPost` is still the old-world view type, which does not assign to
|
|
||||||
* the branded lexicon type this page carries.
|
|
||||||
*/
|
|
||||||
feed: slices.map(slice => toLex(slice._feedPost)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-35
@@ -91,16 +91,7 @@ export async function post(
|
|||||||
for (let i = 0; i < thread.posts.length; i++) {
|
for (let i = 0; i < thread.posts.length; i++) {
|
||||||
const draft = thread.posts[i]
|
const draft = thread.posts[i]
|
||||||
|
|
||||||
/*
|
const rtPromise = resolveRT(resolveClients.appview, draft.richtext)
|
||||||
* Not awaited to avoid waterfalls. `draft.richtext` is still an
|
|
||||||
* `@atproto/api` RichText (composer state is migrated by Task 7); the SDK
|
|
||||||
* RichText is structurally the same transplant, so bridge it here.
|
|
||||||
* TODO(phase4): drop toLex once composer state migrates to SDK RichText.
|
|
||||||
*/
|
|
||||||
const rtPromise = resolveRT(
|
|
||||||
resolveClients.appview,
|
|
||||||
bsky.toLex<RichText>(draft.richtext),
|
|
||||||
)
|
|
||||||
const embedPromise = resolveEmbed(
|
const embedPromise = resolveEmbed(
|
||||||
clients,
|
clients,
|
||||||
queryClient,
|
queryClient,
|
||||||
@@ -138,17 +129,11 @@ export async function post(
|
|||||||
langs,
|
langs,
|
||||||
labels,
|
labels,
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* `value` is typed `LexMap` (a loose index-signature map). A generated
|
|
||||||
* record type is a valid LexMap at runtime but a strict interface is not
|
|
||||||
* assignable to an index-signature type, so widen with `toLex` at this
|
|
||||||
* boundary. Not a brand cast - the record is already fully typed.
|
|
||||||
*/
|
|
||||||
writes.push({
|
writes.push({
|
||||||
$type: 'com.atproto.repo.applyWrites#create',
|
$type: 'com.atproto.repo.applyWrites#create',
|
||||||
collection: 'app.bsky.feed.post',
|
collection: 'app.bsky.feed.post',
|
||||||
rkey: rkey,
|
rkey: rkey,
|
||||||
value: bsky.toLex(record),
|
value: record,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (i === 0 && thread.threadgate.some(tg => tg.type !== 'everybody')) {
|
if (i === 0 && thread.threadgate.some(tg => tg.type !== 'everybody')) {
|
||||||
@@ -156,14 +141,10 @@ export async function post(
|
|||||||
$type: 'com.atproto.repo.applyWrites#create',
|
$type: 'com.atproto.repo.applyWrites#create',
|
||||||
collection: 'app.bsky.feed.threadgate',
|
collection: 'app.bsky.feed.threadgate',
|
||||||
rkey: rkey,
|
rkey: rkey,
|
||||||
value: bsky.toLex(
|
value: createThreadgateRecord({
|
||||||
createThreadgateRecord({
|
post: uri,
|
||||||
post: uri,
|
allow: threadgateAllowUISettingToAllowRecordValue(thread.threadgate),
|
||||||
allow: threadgateAllowUISettingToAllowRecordValue(
|
}),
|
||||||
thread.threadgate,
|
|
||||||
),
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,12 +156,12 @@ export async function post(
|
|||||||
$type: 'com.atproto.repo.applyWrites#create',
|
$type: 'com.atproto.repo.applyWrites#create',
|
||||||
collection: 'app.bsky.feed.postgate',
|
collection: 'app.bsky.feed.postgate',
|
||||||
rkey: rkey,
|
rkey: rkey,
|
||||||
value: bsky.toLex({
|
value: {
|
||||||
...thread.postgate,
|
...thread.postgate,
|
||||||
$type: 'app.bsky.feed.postgate',
|
$type: 'app.bsky.feed.postgate',
|
||||||
createdAt: now.toISOString(),
|
createdAt: now.toISOString(),
|
||||||
post: uri,
|
post: uri,
|
||||||
}),
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -426,7 +407,7 @@ async function resolveMedia(
|
|||||||
* structural shape matches the lexicon blob field; the CID hasher handles
|
* structural shape matches the lexicon blob field; the CID hasher handles
|
||||||
* both class instances and plain lex blobs (see computeCid).
|
* both class instances and plain lex blobs (see computeCid).
|
||||||
*/
|
*/
|
||||||
video: bsky.toLex(videoDraft.pendingPublish.blobRef),
|
video: videoDraft.pendingPublish.blobRef,
|
||||||
alt: videoDraft.altText || undefined,
|
alt: videoDraft.altText || undefined,
|
||||||
captions: captions.length === 0 ? undefined : captions,
|
captions: captions.length === 0 ? undefined : captions,
|
||||||
aspectRatio,
|
aspectRatio,
|
||||||
@@ -475,13 +456,7 @@ async function resolveMedia(
|
|||||||
title: resolvedLink.title,
|
title: resolvedLink.title,
|
||||||
description: resolvedLink.description,
|
description: resolvedLink.description,
|
||||||
thumb: blob,
|
thumb: blob,
|
||||||
/*
|
associatedRefs: resolvedLink.associatedRefs,
|
||||||
* associatedRefs comes from getLinkMeta, still typed with the old
|
|
||||||
* `@atproto/api` StrongRef (link-meta.ts is out of scope). The shape
|
|
||||||
* is identical; bridge with toLex.
|
|
||||||
* TODO(phase4): drop toLex once link-meta migrates.
|
|
||||||
*/
|
|
||||||
associatedRefs: bsky.toLex(resolvedLink.associatedRefs),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-15
@@ -23,7 +23,6 @@ import {
|
|||||||
import {type ComposerImage} from '#/state/gallery'
|
import {type ComposerImage} from '#/state/gallery'
|
||||||
import {createComposerImage} from '#/state/gallery'
|
import {createComposerImage} from '#/state/gallery'
|
||||||
import {type ChatInvitePreview} from '#/state/queries/join-links'
|
import {type ChatInvitePreview} from '#/state/queries/join-links'
|
||||||
import {type SessionAgent} from '#/state/session'
|
|
||||||
import {type Gif} from '#/features/gifPicker/types'
|
import {type Gif} from '#/features/gifPicker/types'
|
||||||
import {app, chat, com} from '#/lexicons'
|
import {app, chat, com} from '#/lexicons'
|
||||||
import {createGIFDescription} from '../gif-alt-text'
|
import {createGIFDescription} from '../gif-alt-text'
|
||||||
@@ -31,13 +30,10 @@ import {createGIFDescription} from '../gif-alt-text'
|
|||||||
/**
|
/**
|
||||||
* Clients the link resolver needs. `appview` serves the `app.bsky.*` feed/graph
|
* Clients the link resolver needs. `appview` serves the `app.bsky.*` feed/graph
|
||||||
* reads plus handle resolution; `chat` serves the group join-link previews.
|
* reads plus handle resolution; `chat` serves the group join-link previews.
|
||||||
* `agent` is still threaded through to {@link getLinkMeta}, which has not yet
|
|
||||||
* migrated off the bridge - it only reads the (unused) service URL from it.
|
|
||||||
*/
|
*/
|
||||||
export type ResolveClients = {
|
export type ResolveClients = {
|
||||||
appview: Client
|
appview: Client
|
||||||
chat: Client
|
chat: Client
|
||||||
agent: SessionAgent
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ResolvedExternalLink = {
|
type ResolvedExternalLink = {
|
||||||
@@ -195,7 +191,7 @@ export async function resolveLink(
|
|||||||
view: res.starterPack,
|
view: res.starterPack,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return resolveExternal(clients, uri)
|
return resolveExternal(uri)
|
||||||
|
|
||||||
// Forked from useGetPost. TODO: move into RQ.
|
// Forked from useGetPost. TODO: move into RQ.
|
||||||
async function getPost({uri}: {uri: string}) {
|
async function getPost({uri}: {uri: string}) {
|
||||||
@@ -267,16 +263,8 @@ function getFileSlug(url: string | undefined): string | undefined {
|
|||||||
return dotIndex > 0 ? filename.slice(0, dotIndex) : undefined
|
return dotIndex > 0 ? filename.slice(0, dotIndex) : undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
async function resolveExternal(
|
async function resolveExternal(uri: string): Promise<ResolvedExternalLink> {
|
||||||
clients: ResolveClients,
|
const result = await getLinkMeta(uri)
|
||||||
uri: string,
|
|
||||||
): Promise<ResolvedExternalLink> {
|
|
||||||
/*
|
|
||||||
* getLinkMeta still takes the bridge agent (not yet migrated); it only reads
|
|
||||||
* a service URL from it that LINK_META_PROXY ignores. Keep threading the
|
|
||||||
* agent here until link-meta migrates.
|
|
||||||
*/
|
|
||||||
const result = await getLinkMeta(clients.agent, uri)
|
|
||||||
return {
|
return {
|
||||||
type: 'external',
|
type: 'external',
|
||||||
uri: result.url,
|
uri: result.url,
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import {LINK_META_PROXY} from '#/lib/constants'
|
import {LINK_META_PROXY} from '#/lib/constants'
|
||||||
import {getGiphyMetaUri} from '#/lib/strings/embed-player'
|
import {getGiphyMetaUri} from '#/lib/strings/embed-player'
|
||||||
import {parseStarterPackUri} from '#/lib/strings/starter-pack'
|
import {parseStarterPackUri} from '#/lib/strings/starter-pack'
|
||||||
import {type SessionAgent} from '#/state/session'
|
|
||||||
import {type app} from '#/lexicons'
|
import {type app} from '#/lexicons'
|
||||||
import {isBskyAppUrl} from '../strings/url-helpers'
|
import {isBskyAppUrl} from '../strings/url-helpers'
|
||||||
|
|
||||||
@@ -31,7 +30,6 @@ export interface LinkMeta {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getLinkMeta(
|
export async function getLinkMeta(
|
||||||
agent: SessionAgent,
|
|
||||||
url: string,
|
url: string,
|
||||||
timeout = 15e3,
|
timeout = 15e3,
|
||||||
): Promise<LinkMeta> {
|
): Promise<LinkMeta> {
|
||||||
@@ -80,9 +78,7 @@ export async function getLinkMeta(
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`${LINK_META_PROXY(agent.serviceUrl.toString() || '')}${encodeURIComponent(
|
`${LINK_META_PROXY('')}${encodeURIComponent(url)}`,
|
||||||
url,
|
|
||||||
)}`,
|
|
||||||
{signal: controller.signal},
|
{signal: controller.signal},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import {
|
|||||||
} from '#/lib/moderation/useGlobalLabelStrings'
|
} from '#/lib/moderation/useGlobalLabelStrings'
|
||||||
import {useLabelDefinitions} from '#/state/preferences'
|
import {useLabelDefinitions} from '#/state/preferences'
|
||||||
import {type app, type com} from '#/lexicons'
|
import {type app, type com} from '#/lexicons'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
|
|
||||||
export interface LabelInfo {
|
export interface LabelInfo {
|
||||||
label: com.atproto.label.defs.Label
|
label: com.atproto.label.defs.Label
|
||||||
@@ -23,26 +22,14 @@ export interface LabelInfo {
|
|||||||
|
|
||||||
export function useLabelInfo(label: com.atproto.label.defs.Label): LabelInfo {
|
export function useLabelInfo(label: com.atproto.label.defs.Label): LabelInfo {
|
||||||
const {i18n} = useLingui()
|
const {i18n} = useLingui()
|
||||||
/*
|
|
||||||
* TODO(phase4): drop the `toLex` casts once `useLabelDefinitions`
|
|
||||||
* (state/preferences/label-defs) emits `#/lexicons` / `@bsky.app/sdk`
|
|
||||||
* moderation types. It still returns old `@atproto/api`
|
|
||||||
* `InterpretedLabelValueDefinition` / `LabelerViewDetailed`, which are
|
|
||||||
* structurally identical to the SDK/lexicon ones modulo branded strings.
|
|
||||||
*/
|
|
||||||
const {labelDefs, labelers} = useLabelDefinitions()
|
const {labelDefs, labelers} = useLabelDefinitions()
|
||||||
const def = getDefinition(
|
const def = getDefinition(labelDefs, label)
|
||||||
toLex<Record<string, InterpretedLabelValueDefinition[]>>(labelDefs),
|
|
||||||
label,
|
|
||||||
)
|
|
||||||
const globalLabelStrings = useGlobalLabelStrings()
|
const globalLabelStrings = useGlobalLabelStrings()
|
||||||
return {
|
return {
|
||||||
label,
|
label,
|
||||||
def,
|
def,
|
||||||
strings: getLabelStrings(i18n.locale, globalLabelStrings, def),
|
strings: getLabelStrings(i18n.locale, globalLabelStrings, def),
|
||||||
labeler: toLex<app.bsky.labeler.defs.LabelerViewDetailed[]>(labelers).find(
|
labeler: labelers.find(labeler => label.src === labeler.creator.did),
|
||||||
labeler => label.src === labeler.creator.did,
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,8 +13,6 @@ import {type Props as SVGIconProps} from '#/components/icons/common'
|
|||||||
import {EyeSlash_Stroke2_Corner0_Rounded as EyeSlash} from '#/components/icons/EyeSlash'
|
import {EyeSlash_Stroke2_Corner0_Rounded as EyeSlash} from '#/components/icons/EyeSlash'
|
||||||
import {Warning_Stroke2_Corner0_Rounded as Warning} from '#/components/icons/Warning'
|
import {Warning_Stroke2_Corner0_Rounded as Warning} from '#/components/icons/Warning'
|
||||||
import {type AppModerationCause} from '#/components/Pills'
|
import {type AppModerationCause} from '#/components/Pills'
|
||||||
import {type com} from '#/lexicons'
|
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
import {useGlobalLabelStrings} from './useGlobalLabelStrings'
|
import {useGlobalLabelStrings} from './useGlobalLabelStrings'
|
||||||
import {getDefinition, getLabelStrings} from './useLabelInfo'
|
import {getDefinition, getLabelStrings} from './useLabelInfo'
|
||||||
|
|
||||||
@@ -129,18 +127,7 @@ export function useModerationCauseDescription(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cause.type === 'label') {
|
if (cause.type === 'label') {
|
||||||
/*
|
const def = cause.labelDef || getDefinition(labelDefs, cause.label)
|
||||||
* TODO(phase4): drop `toLex` once `useLabelDefinitions` and the label
|
|
||||||
* cause type share the `#/lexicons` label shape. `labelDefs` still comes
|
|
||||||
* from the old `@atproto/api`-typed producer and `cause.label` is the SDK
|
|
||||||
* label; both are structurally identical to the `#/lexicons` label.
|
|
||||||
*/
|
|
||||||
const def =
|
|
||||||
cause.labelDef ||
|
|
||||||
getDefinition(
|
|
||||||
toLex<Parameters<typeof getDefinition>[0]>(labelDefs),
|
|
||||||
toLex<com.atproto.label.defs.Label>(cause.label),
|
|
||||||
)
|
|
||||||
const strings = getLabelStrings(i18n.locale, globalLabelStrings, def)
|
const strings = getLabelStrings(i18n.locale, globalLabelStrings, def)
|
||||||
const labeler = labelers.find(l => l.creator.did === cause.label.src)
|
const labeler = labelers.find(l => l.creator.did === cause.label.src)
|
||||||
let source = labeler
|
let source = labeler
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ import {Error} from '#/components/Error'
|
|||||||
import * as Layout from '#/components/Layout'
|
import * as Layout from '#/components/Layout'
|
||||||
import {IS_LIQUID_GLASS} from '#/env'
|
import {IS_LIQUID_GLASS} from '#/env'
|
||||||
import {chat} from '#/lexicons'
|
import {chat} from '#/lexicons'
|
||||||
import {isType, toLex} from '#/types/bsky'
|
import {isType} from '#/types/bsky'
|
||||||
import {ChatDisabled} from './components/ChatDisabled'
|
import {ChatDisabled} from './components/ChatDisabled'
|
||||||
import {ChatEnded} from './components/ChatEnded'
|
import {ChatEnded} from './components/ChatEnded'
|
||||||
import {ChatLocked} from './components/ChatLocked'
|
import {ChatLocked} from './components/ChatLocked'
|
||||||
@@ -228,8 +228,7 @@ function InnerReady({
|
|||||||
const moderationOpts = useModerationOpts()
|
const moderationOpts = useModerationOpts()
|
||||||
const primaryMemberModeration = useMemo(() => {
|
const primaryMemberModeration = useMemo(() => {
|
||||||
if (!primaryMember || !moderationOpts) return null
|
if (!primaryMember || !moderationOpts) return null
|
||||||
// TODO(phase4): drop toLex once useMaybeProfileShadow emits #/lexicons views
|
return moderateProfile(primaryMember, moderationOpts)
|
||||||
return moderateProfile(toLex(primaryMember), moderationOpts)
|
|
||||||
}, [primaryMember, moderationOpts])
|
}, [primaryMember, moderationOpts])
|
||||||
|
|
||||||
const header = <MessagesListHeader convo={convo} />
|
const header = <MessagesListHeader convo={convo} />
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import * as ProfileCard from '#/components/ProfileCard'
|
|||||||
import * as Prompt from '#/components/Prompt'
|
import * as Prompt from '#/components/Prompt'
|
||||||
import * as Toast from '#/components/Toast'
|
import * as Toast from '#/components/Toast'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
import {MemberMenu} from './MemberMenu'
|
import {MemberMenu} from './MemberMenu'
|
||||||
import {RemoveMemberPrompt} from './prompts'
|
import {RemoveMemberPrompt} from './prompts'
|
||||||
import {StatusBadge} from './StatusBadge'
|
import {StatusBadge} from './StatusBadge'
|
||||||
@@ -81,8 +80,7 @@ export function Member({
|
|||||||
return <MemberPlaceholder />
|
return <MemberPlaceholder />
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(phase4): drop toLex once useProfileShadow emits #/lexicons views
|
const moderation = moderateProfile(profile, moderationOpts)
|
||||||
const moderation = moderateProfile(toLex(profile), moderationOpts)
|
|
||||||
|
|
||||||
const isDeletedAccount = profile.handle === 'missing.invalid'
|
const isDeletedAccount = profile.handle === 'missing.invalid'
|
||||||
const displayName = isDeletedAccount
|
const displayName = isDeletedAccount
|
||||||
@@ -108,13 +106,10 @@ export function Member({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const joinedReason = profile.kind?.addedBy
|
const joinedReason = profile.kind?.addedBy
|
||||||
? // TODO(phase4): drop toLex once addedBy emits #/lexicons views
|
? l`Added by ${createSanitizedDisplayName(
|
||||||
l`Added by ${createSanitizedDisplayName(
|
|
||||||
profile.kind.addedBy,
|
profile.kind.addedBy,
|
||||||
true,
|
true,
|
||||||
moderateProfile(toLex(profile.kind.addedBy), moderationOpts).ui(
|
moderateProfile(profile.kind.addedBy, moderationOpts).ui('displayName'),
|
||||||
'displayName',
|
|
||||||
),
|
|
||||||
)}`
|
)}`
|
||||||
: l`Added by invite link`
|
: l`Added by invite link`
|
||||||
|
|
||||||
|
|||||||
@@ -187,9 +187,8 @@ export function JoinRequest({setScreenState}: Props) {
|
|||||||
{createSanitizedDisplayName(
|
{createSanitizedDisplayName(
|
||||||
joinLinkPreview.owner,
|
joinLinkPreview.owner,
|
||||||
true,
|
true,
|
||||||
// TODO(phase4): drop toLex once join link preview emits #/lexicons views
|
|
||||||
moderateProfile(
|
moderateProfile(
|
||||||
bsky.toLex(joinLinkPreview.owner),
|
joinLinkPreview.owner,
|
||||||
moderationOpts,
|
moderationOpts,
|
||||||
).ui('displayName'),
|
).ui('displayName'),
|
||||||
)}
|
)}
|
||||||
@@ -224,14 +223,12 @@ export function JoinRequest({setScreenState}: Props) {
|
|||||||
? l`Sign in to request access to this group chat.`
|
? l`Sign in to request access to this group chat.`
|
||||||
: l`Sign in to accept invite.`}{' '}
|
: l`Sign in to accept invite.`}{' '}
|
||||||
{joinLinkPreview.joinRule === 'followedByOwner' &&
|
{joinLinkPreview.joinRule === 'followedByOwner' &&
|
||||||
// TODO(phase4): drop toLex once join link preview emits #/lexicons views
|
|
||||||
l`Only people ${createSanitizedDisplayName(
|
l`Only people ${createSanitizedDisplayName(
|
||||||
joinLinkPreview.owner,
|
joinLinkPreview.owner,
|
||||||
true,
|
true,
|
||||||
moderateProfile(
|
moderateProfile(joinLinkPreview.owner, moderationOpts).ui(
|
||||||
bsky.toLex(joinLinkPreview.owner),
|
'displayName',
|
||||||
moderationOpts,
|
),
|
||||||
).ui('displayName'),
|
|
||||||
)} follows can join.`}
|
)} follows can join.`}
|
||||||
</Text>
|
</Text>
|
||||||
<ActionButtons setScreenState={setScreenState} />
|
<ActionButtons setScreenState={setScreenState} />
|
||||||
|
|||||||
@@ -125,8 +125,7 @@ function DirectChatItem({
|
|||||||
const {isWithinLeftPanel} = useIsWithinSplitView()
|
const {isWithinLeftPanel} = useIsWithinSplitView()
|
||||||
|
|
||||||
const moderation = useMemo(
|
const moderation = useMemo(
|
||||||
// TODO(phase4): drop toLex once useProfileShadow emits #/lexicons views
|
() => moderateProfile(profile, moderationOpts),
|
||||||
() => moderateProfile(bsky.toLex(profile), moderationOpts),
|
|
||||||
[profile, moderationOpts],
|
[profile, moderationOpts],
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -193,10 +192,7 @@ function GroupChatItem({
|
|||||||
|
|
||||||
const moderation = useMemo(
|
const moderation = useMemo(
|
||||||
() =>
|
() =>
|
||||||
groupOwner
|
groupOwner ? moderateProfile(groupOwner, moderationOpts) : undefined,
|
||||||
? // TODO(phase4): drop toLex once useMaybeProfileShadow emits #/lexicons views
|
|
||||||
moderateProfile(bsky.toLex(groupOwner), moderationOpts)
|
|
||||||
: undefined,
|
|
||||||
[groupOwner, moderationOpts],
|
[groupOwner, moderationOpts],
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -423,15 +419,7 @@ function BaseChatItem({
|
|||||||
for (const member of convo.view.members) {
|
for (const member of convo.view.members) {
|
||||||
unstableCacheProfileView(queryClient, member)
|
unstableCacheProfileView(queryClient, member)
|
||||||
}
|
}
|
||||||
/*
|
precacheConvoQuery(queryClient, convo.view)
|
||||||
* `convo.view` comes from the still-old-typed `#/components/dms/util`
|
|
||||||
* (migrates in a later task) while the convo cache is now keyed on the
|
|
||||||
* lexicon ConvoView. TODO(phase4): drop toLex once dms/util migrates.
|
|
||||||
*/
|
|
||||||
precacheConvoQuery(
|
|
||||||
queryClient,
|
|
||||||
bsky.toLex<chat.bsky.convo.defs.ConvoView>(convo.view),
|
|
||||||
)
|
|
||||||
void decrementBadgeCount(convo.view.unreadCount)
|
void decrementBadgeCount(convo.view.unreadCount)
|
||||||
if (isDeletedAccount) {
|
if (isDeletedAccount) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
@@ -525,10 +513,7 @@ function BaseChatItem({
|
|||||||
}
|
}
|
||||||
onPressIn={() =>
|
onPressIn={() =>
|
||||||
// see onPress: old-typed dms/util view into the new-typed cache
|
// see onPress: old-typed dms/util view into the new-typed cache
|
||||||
precacheConvoQuery(
|
precacheConvoQuery(queryClient, convo.view)
|
||||||
queryClient,
|
|
||||||
bsky.toLex<chat.bsky.convo.defs.ConvoView>(convo.view),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
onPress={onPress}
|
onPress={onPress}
|
||||||
onLongPress={showMenu && IS_NATIVE ? onLongPress : undefined}
|
onLongPress={showMenu && IS_NATIVE ? onLongPress : undefined}
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import {ProfileBadges} from '#/components/ProfileBadges'
|
|||||||
import {usePromptControl} from '#/components/Prompt'
|
import {usePromptControl} from '#/components/Prompt'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import type * as bsky from '#/types/bsky'
|
import type * as bsky from '#/types/bsky'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
import {AcceptChatButton, DeleteChatButton, RejectMenu} from './RequestButtons'
|
import {AcceptChatButton, DeleteChatButton, RejectMenu} from './RequestButtons'
|
||||||
|
|
||||||
export function ChatStatusInfo({convoState}: {convoState: ActiveConvoStates}) {
|
export function ChatStatusInfo({convoState}: {convoState: ActiveConvoStates}) {
|
||||||
@@ -115,8 +114,7 @@ function InviterHeader({
|
|||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const profile = useProfileShadow(profileUnshadowed)
|
const profile = useProfileShadow(profileUnshadowed)
|
||||||
const moderation = useMemo(
|
const moderation = useMemo(
|
||||||
// TODO(phase4): drop toLex once useProfileShadow emits #/lexicons views
|
() => moderateProfile(profile, moderationOpts),
|
||||||
() => moderateProfile(toLex(profile), moderationOpts),
|
|
||||||
[profile, moderationOpts],
|
[profile, moderationOpts],
|
||||||
)
|
)
|
||||||
const displayName = createSanitizedDisplayName(
|
const displayName = createSanitizedDisplayName(
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import {Text} from '#/components/Typography'
|
|||||||
import {useAnalytics} from '#/analytics'
|
import {useAnalytics} from '#/analytics'
|
||||||
import {IS_WEB} from '#/env'
|
import {IS_WEB} from '#/env'
|
||||||
import {type chat} from '#/lexicons'
|
import {type chat} from '#/lexicons'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
import {CopyTextButton} from './CopyTextButton'
|
import {CopyTextButton} from './CopyTextButton'
|
||||||
import {EditTextButton} from './EditTextButton'
|
import {EditTextButton} from './EditTextButton'
|
||||||
|
|
||||||
@@ -69,8 +68,7 @@ export function InviteLinkDialog({
|
|||||||
const ownerName = createSanitizedDisplayName(
|
const ownerName = createSanitizedDisplayName(
|
||||||
owner,
|
owner,
|
||||||
false,
|
false,
|
||||||
// TODO(phase4): drop toLex once GroupConvoMember emits #/lexicons views
|
moderateProfile(owner, moderationOpts).ui('displayName'),
|
||||||
moderateProfile(toLex(owner), moderationOpts).ui('displayName'),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const {joinLink} = convo.details
|
const {joinLink} = convo.details
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ import {Loader} from '#/components/Loader'
|
|||||||
import * as Toast from '#/components/Toast'
|
import * as Toast from '#/components/Toast'
|
||||||
import {IS_ANDROID, IS_IOS, IS_LIQUID_GLASS, IS_NATIVE, IS_WEB} from '#/env'
|
import {IS_ANDROID, IS_IOS, IS_LIQUID_GLASS, IS_NATIVE, IS_WEB} from '#/env'
|
||||||
import {type chat} from '#/lexicons'
|
import {type chat} from '#/lexicons'
|
||||||
import * as bsky from '#/types/bsky'
|
|
||||||
import {type MessageEmbedState} from './MessageInputEmbed'
|
import {type MessageEmbedState} from './MessageInputEmbed'
|
||||||
|
|
||||||
const MIN_HEIGHT = 40
|
const MIN_HEIGHT = 40
|
||||||
@@ -70,15 +69,7 @@ export function MessageComposer({
|
|||||||
const {getDraft, clearDraft} = useMessageDraft()
|
const {getDraft, clearDraft} = useMessageDraft()
|
||||||
const composerInternalApiRef = useComposerInternalApiRef()
|
const composerInternalApiRef = useComposerInternalApiRef()
|
||||||
const {replyTo: replyToOld, clearReply} = useMessageReplies()
|
const {replyTo: replyToOld, clearReply} = useMessageReplies()
|
||||||
/*
|
const replyTo = replyToOld
|
||||||
* `useMessageReplies` (`#/components/dms`, migrates in a later task) still
|
|
||||||
* emits the old `@atproto/api` MessageView; the send path is typed on the
|
|
||||||
* lexicon view. Structurally identical modulo branded strings.
|
|
||||||
* TODO(phase4): drop toLex once dms/MessageReplies migrates.
|
|
||||||
*/
|
|
||||||
const replyTo = bsky.toLex<chat.bsky.convo.defs.MessageView | null>(
|
|
||||||
replyToOld,
|
|
||||||
)
|
|
||||||
|
|
||||||
const [text, setText] = useState(getDraft)
|
const [text, setText] = useState(getDraft)
|
||||||
useSaveMessageDraft(text)
|
useSaveMessageDraft(text)
|
||||||
|
|||||||
@@ -569,24 +569,18 @@ export function MessagesList({
|
|||||||
try {
|
try {
|
||||||
const post = await getPost({uri: embedState.uri})
|
const post = await getPost({uri: embedState.uri})
|
||||||
if (post) {
|
if (post) {
|
||||||
/*
|
embed = {
|
||||||
* `post` comes from the still-old-typed `useGetPost` producer
|
|
||||||
* (migrates in a later task), so its uri/view shapes carry plain
|
|
||||||
* strings where the lexicon types are branded. TODO(phase4): drop
|
|
||||||
* toLex once that producer migrates.
|
|
||||||
*/
|
|
||||||
embed = bsky.toLex<$Typed<app.bsky.embed.record.Main>>({
|
|
||||||
$type: 'app.bsky.embed.record',
|
$type: 'app.bsky.embed.record',
|
||||||
record: {
|
record: {
|
||||||
uri: post.uri,
|
uri: post.uri,
|
||||||
cid: post.cid,
|
cid: post.cid,
|
||||||
},
|
},
|
||||||
})
|
}
|
||||||
|
|
||||||
embedView = bsky.toLex<$Typed<app.bsky.embed.record.View>>({
|
embedView = {
|
||||||
$type: 'app.bsky.embed.record#view',
|
$type: 'app.bsky.embed.record#view',
|
||||||
record: createEmbedViewRecordFromPost(post),
|
record: createEmbedViewRecordFromPost(post),
|
||||||
})
|
}
|
||||||
|
|
||||||
stripLinkFacet(uri => {
|
stripLinkFacet(uri => {
|
||||||
if (!isBskyPostUrl(uri)) return false
|
if (!isBskyPostUrl(uri)) return false
|
||||||
@@ -611,14 +605,10 @@ export function MessagesList({
|
|||||||
|
|
||||||
const joinLinkPreview = await getJoinLinkPreview({code, hasSession})
|
const joinLinkPreview = await getJoinLinkPreview({code, hasSession})
|
||||||
if (joinLinkPreview) {
|
if (joinLinkPreview) {
|
||||||
/*
|
embedView = {
|
||||||
* The preview comes from the still-old-typed `join-links.ts` query
|
|
||||||
* (migrates in a later task). TODO(phase4): drop toLex once it does.
|
|
||||||
*/
|
|
||||||
embedView = bsky.toLex<$Typed<chat.bsky.embed.joinLink.View>>({
|
|
||||||
$type: 'chat.bsky.embed.joinLink#view',
|
$type: 'chat.bsky.embed.joinLink#view',
|
||||||
joinLinkPreview,
|
joinLinkPreview,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stripLinkFacet(uri => getChatInviteCodeFromUrl(uri) === code)
|
stripLinkFacet(uri => getChatInviteCodeFromUrl(uri) === code)
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import {Person_Stroke2_Corner2_Rounded as PersonIcon} from '#/components/icons/P
|
|||||||
import {ProfileBadges} from '#/components/ProfileBadges'
|
import {ProfileBadges} from '#/components/ProfileBadges'
|
||||||
import * as ProfileCard from '#/components/ProfileCard'
|
import * as ProfileCard from '#/components/ProfileCard'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
|
|
||||||
export function MessagesListInfoPanel({
|
export function MessagesListInfoPanel({
|
||||||
convo,
|
convo,
|
||||||
@@ -35,11 +34,10 @@ export function MessagesListInfoPanel({
|
|||||||
)[0]
|
)[0]
|
||||||
const handle = sanitizeHandle(profile.handle, '@')
|
const handle = sanitizeHandle(profile.handle, '@')
|
||||||
const displayName = moderationOpts
|
const displayName = moderationOpts
|
||||||
? // TODO(phase4): drop toLex once convo members emit #/lexicons views
|
? createSanitizedDisplayName(
|
||||||
createSanitizedDisplayName(
|
|
||||||
profile,
|
profile,
|
||||||
true,
|
true,
|
||||||
moderateProfile(toLex(profile), moderationOpts).ui('displayName'),
|
moderateProfile(profile, moderationOpts).ui('displayName'),
|
||||||
)
|
)
|
||||||
: handle
|
: handle
|
||||||
const profileLink =
|
const profileLink =
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ import * as Menu from '#/components/Menu'
|
|||||||
import {ReportDialog} from '#/components/moderation/ReportDialog'
|
import {ReportDialog} from '#/components/moderation/ReportDialog'
|
||||||
import * as Toast from '#/components/Toast'
|
import * as Toast from '#/components/Toast'
|
||||||
import {type chat} from '#/lexicons'
|
import {type chat} from '#/lexicons'
|
||||||
import * as bsky from '#/types/bsky'
|
|
||||||
|
|
||||||
export function RejectMenu({
|
export function RejectMenu({
|
||||||
convo,
|
convo,
|
||||||
@@ -229,18 +228,10 @@ export function AcceptChatButton({
|
|||||||
onMutate: () => {
|
onMutate: () => {
|
||||||
onAcceptConvo?.()
|
onAcceptConvo?.()
|
||||||
if (currentScreen === 'list') {
|
if (currentScreen === 'list') {
|
||||||
/*
|
precacheConvoQuery(queryClient, {
|
||||||
* `convo` is the old-typed view threaded from `#/components/dms/util`
|
...convo,
|
||||||
* consumers while the convo cache is now keyed on the lexicon
|
status: 'accepted',
|
||||||
* ConvoView. TODO(phase4): drop toLex once this file's props flip.
|
})
|
||||||
*/
|
|
||||||
precacheConvoQuery(
|
|
||||||
queryClient,
|
|
||||||
bsky.toLex<chat.bsky.convo.defs.ConvoView>({
|
|
||||||
...convo,
|
|
||||||
status: 'accepted',
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
navigation.navigate('MessagesConversation', {
|
navigation.navigate('MessagesConversation', {
|
||||||
conversation: convo.id,
|
conversation: convo.id,
|
||||||
accept: true,
|
accept: true,
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import {ProfileHoverCard} from '#/components/ProfileHoverCard'
|
|||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {useAnalytics} from '#/analytics'
|
import {useAnalytics} from '#/analytics'
|
||||||
import {type app} from '#/lexicons'
|
import {type app} from '#/lexicons'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
|
|
||||||
const AVI_SIZE = 20
|
const AVI_SIZE = 20
|
||||||
|
|
||||||
@@ -94,8 +93,7 @@ export function KnownLikers({post}: {post: AppBskyFeedDefs.PostView}) {
|
|||||||
.map(like => like.actor)
|
.map(like => like.actor)
|
||||||
.map(actor => ({
|
.map(actor => ({
|
||||||
actor,
|
actor,
|
||||||
// TODO(phase4): drop toLex once useLikedBySampleQuery emits #/lexicons views
|
moderation: moderateProfile(actor, moderationOpts),
|
||||||
moderation: moderateProfile(toLex(actor), moderationOpts),
|
|
||||||
}))
|
}))
|
||||||
.filter(({actor, moderation}) => {
|
.filter(({actor, moderation}) => {
|
||||||
const modui = moderation.ui('profileList')
|
const modui = moderation.ui('profileList')
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ import {Text} from '#/components/Typography'
|
|||||||
import {useAnalytics} from '#/analytics'
|
import {useAnalytics} from '#/analytics'
|
||||||
import {IS_IOS} from '#/env'
|
import {IS_IOS} from '#/env'
|
||||||
import {type app} from '#/lexicons'
|
import {type app} from '#/lexicons'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
import {ProfileHeaderDisplayName} from './DisplayName'
|
import {ProfileHeaderDisplayName} from './DisplayName'
|
||||||
import {EditProfileDialog} from './EditProfileDialog'
|
import {EditProfileDialog} from './EditProfileDialog'
|
||||||
import {ProfileHeaderHandle} from './Handle'
|
import {ProfileHeaderHandle} from './Handle'
|
||||||
@@ -67,7 +66,7 @@ let ProfileHeaderLabeler = ({
|
|||||||
const isSelf = currentAccount?.did === profile.did
|
const isSelf = currentAccount?.did === profile.did
|
||||||
|
|
||||||
const moderation = useMemo(
|
const moderation = useMemo(
|
||||||
() => moderateProfile(toLex(profile), moderationOpts),
|
() => moderateProfile(profile, moderationOpts),
|
||||||
[profile, moderationOpts],
|
[profile, moderationOpts],
|
||||||
)
|
)
|
||||||
const {mutateAsync: likeMod, isPending: isLikePending} = useLikeMutation()
|
const {mutateAsync: likeMod, isPending: isLikePending} = useLikeMutation()
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ import {IS_IOS, IS_NATIVE} from '#/env'
|
|||||||
import {InviteFriendsDialog} from '#/features/inviteFriends'
|
import {InviteFriendsDialog} from '#/features/inviteFriends'
|
||||||
import {useActorStatus} from '#/features/liveNow'
|
import {useActorStatus} from '#/features/liveNow'
|
||||||
import {type app} from '#/lexicons'
|
import {type app} from '#/lexicons'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
import {GermButton} from '../components/GermButton'
|
import {GermButton} from '../components/GermButton'
|
||||||
import {ProfileHeaderDisplayName} from './DisplayName'
|
import {ProfileHeaderDisplayName} from './DisplayName'
|
||||||
import {EditProfileDialog} from './EditProfileDialog'
|
import {EditProfileDialog} from './EditProfileDialog'
|
||||||
@@ -69,7 +68,7 @@ let ProfileHeaderStandard = ({
|
|||||||
const {currentAccount} = useSession()
|
const {currentAccount} = useSession()
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
const moderation = useMemo(
|
const moderation = useMemo(
|
||||||
() => moderateProfile(toLex(profile), moderationOpts),
|
() => moderateProfile(profile, moderationOpts),
|
||||||
[profile, moderationOpts],
|
[profile, moderationOpts],
|
||||||
)
|
)
|
||||||
const [, queueUnblock] = useProfileBlockMutationQueue(profile)
|
const [, queueUnblock] = useProfileBlockMutationQueue(profile)
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import {Header} from '#/components/Layout'
|
|||||||
import * as ProfileCard from '#/components/ProfileCard'
|
import * as ProfileCard from '#/components/ProfileCard'
|
||||||
import {IS_NATIVE} from '#/env'
|
import {IS_NATIVE} from '#/env'
|
||||||
import {type app} from '#/lexicons'
|
import {type app} from '#/lexicons'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
import {
|
import {
|
||||||
HeaderLabelerButtons,
|
HeaderLabelerButtons,
|
||||||
ProfileHeaderLabeler,
|
ProfileHeaderLabeler,
|
||||||
@@ -112,8 +111,7 @@ const MinimalHeader = memo(function MinimalHeader({
|
|||||||
const profile = useProfileShadow(profileUnshadowed)
|
const profile = useProfileShadow(profileUnshadowed)
|
||||||
const moderationOpts = useModerationOpts()
|
const moderationOpts = useModerationOpts()
|
||||||
const moderation = useMemo(
|
const moderation = useMemo(
|
||||||
() =>
|
() => (moderationOpts ? moderateProfile(profile, moderationOpts) : null),
|
||||||
moderationOpts ? moderateProfile(toLex(profile), moderationOpts) : null,
|
|
||||||
[moderationOpts, profile],
|
[moderationOpts, profile],
|
||||||
)
|
)
|
||||||
const [visible, setVisible] = useState(false)
|
const [visible, setVisible] = useState(false)
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import {RichText} from '#/components/RichText'
|
|||||||
import * as Toast from '#/components/Toast'
|
import * as Toast from '#/components/Toast'
|
||||||
import {useAnalytics} from '#/analytics'
|
import {useAnalytics} from '#/analytics'
|
||||||
import {type app} from '#/lexicons'
|
import {type app} from '#/lexicons'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
import {MoreOptionsMenu} from './MoreOptionsMenu'
|
import {MoreOptionsMenu} from './MoreOptionsMenu'
|
||||||
import {SubscribeMenu} from './SubscribeMenu'
|
import {SubscribeMenu} from './SubscribeMenu'
|
||||||
|
|
||||||
@@ -130,8 +129,7 @@ export function Header({
|
|||||||
list.description
|
list.description
|
||||||
? new RichTextAPI({
|
? new RichTextAPI({
|
||||||
text: list.description,
|
text: list.description,
|
||||||
// TODO(phase4): drop toLex once the list view producer emits #/lexicons facets
|
facets: list.descriptionFacets,
|
||||||
facets: toLex(list.descriptionFacets),
|
|
||||||
})
|
})
|
||||||
: undefined,
|
: undefined,
|
||||||
[list],
|
[list],
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ import {Loader} from '#/components/Loader'
|
|||||||
import * as Hider from '#/components/moderation/Hider'
|
import * as Hider from '#/components/moderation/Hider'
|
||||||
import {IS_WEB} from '#/env'
|
import {IS_WEB} from '#/env'
|
||||||
import {type app} from '#/lexicons'
|
import {type app} from '#/lexicons'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
import {AboutSection} from './AboutSection'
|
import {AboutSection} from './AboutSection'
|
||||||
import {ErrorScreen} from './components/ErrorScreen'
|
import {ErrorScreen} from './components/ErrorScreen'
|
||||||
import {Header} from './components/Header'
|
import {Header} from './components/Header'
|
||||||
@@ -167,8 +166,7 @@ function ProfileListScreenLoaded({
|
|||||||
const [headerHeight, setHeaderHeight] = useState<number | null>(null)
|
const [headerHeight, setHeaderHeight] = useState<number | null>(null)
|
||||||
|
|
||||||
const moderation = useMemo(() => {
|
const moderation = useMemo(() => {
|
||||||
// TODO(phase4): drop toLex once ListView prop emits #/lexicons views
|
return moderateUserList(list, moderationOpts)
|
||||||
return moderateUserList(toLex(list), moderationOpts)
|
|
||||||
}, [list, moderationOpts])
|
}, [list, moderationOpts])
|
||||||
|
|
||||||
useSetTitle(isHidden ? _(msg`List Hidden`) : list.name)
|
useSetTitle(isHidden ? _(msg`List Hidden`) : list.name)
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import {ProfileBadges} from '#/components/ProfileBadges'
|
|||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {useAnalytics} from '#/analytics'
|
import {useAnalytics} from '#/analytics'
|
||||||
import type * as bsky from '#/types/bsky'
|
import type * as bsky from '#/types/bsky'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
|
|
||||||
export function SearchHistory({
|
export function SearchHistory({
|
||||||
searchHistory,
|
searchHistory,
|
||||||
@@ -207,8 +206,7 @@ function RecentProfileItem({
|
|||||||
const {t: l} = useLingui()
|
const {t: l} = useLingui()
|
||||||
const width = 80
|
const width = 80
|
||||||
|
|
||||||
// TODO(phase4): drop toLex once profile prop emits #/lexicons views
|
const moderation = moderateProfile(profile, moderationOpts)
|
||||||
const moderation = moderateProfile(toLex(profile), moderationOpts)
|
|
||||||
const name = sanitizeDisplayName(
|
const name = sanitizeDisplayName(
|
||||||
profile.displayName || sanitizeHandle(profile.handle),
|
profile.displayName || sanitizeHandle(profile.handle),
|
||||||
moderation.ui('displayName'),
|
moderation.ui('displayName'),
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import {Text} from '#/components/Typography'
|
|||||||
import {useAnalytics} from '#/analytics'
|
import {useAnalytics} from '#/analytics'
|
||||||
import {type app} from '#/lexicons'
|
import {type app} from '#/lexicons'
|
||||||
import * as ModuleHeader from '../components/ModuleHeader'
|
import * as ModuleHeader from '../components/ModuleHeader'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
|
|
||||||
const IMAGE_SIZE = 56
|
const IMAGE_SIZE = 56
|
||||||
|
|
||||||
@@ -307,8 +306,7 @@ function useModerateTrendingActors(
|
|||||||
|
|
||||||
return actors
|
return actors
|
||||||
.filter(actor => {
|
.filter(actor => {
|
||||||
// TODO(phase4): drop toLex once TrendView actors emit #/lexicons views
|
const decision = moderateProfile(actor, moderationOpts)
|
||||||
const decision = moderateProfile(toLex(actor), moderationOpts)
|
|
||||||
return !decision.ui('avatar').filter && !decision.ui('avatar').blur
|
return !decision.ui('avatar').filter && !decision.ui('avatar').blur
|
||||||
})
|
})
|
||||||
.slice(0, 3)
|
.slice(0, 3)
|
||||||
|
|||||||
@@ -70,7 +70,6 @@ import {useActorStatus} from '#/features/liveNow'
|
|||||||
import {type app} from '#/lexicons'
|
import {type app} from '#/lexicons'
|
||||||
import {device, useStorage} from '#/storage'
|
import {device, useStorage} from '#/storage'
|
||||||
import {useActivitySubscriptionsNudged} from '#/storage/hooks/activity-subscriptions-nudged'
|
import {useActivitySubscriptionsNudged} from '#/storage/hooks/activity-subscriptions-nudged'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
|
|
||||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'Settings'>
|
type Props = NativeStackScreenProps<CommonNavigatorParams, 'Settings'>
|
||||||
export function SettingsScreen({}: Props) {
|
export function SettingsScreen({}: Props) {
|
||||||
@@ -331,8 +330,7 @@ function ProfilePreview({
|
|||||||
|
|
||||||
if (!moderationOpts) return null
|
if (!moderationOpts) return null
|
||||||
|
|
||||||
// TODO(phase4): drop toLex once ProfileViewDetailed prop emits #/lexicons views
|
const moderation = moderateProfile(profile, moderationOpts)
|
||||||
const moderation = moderateProfile(toLex(profile), moderationOpts)
|
|
||||||
const displayName = sanitizeDisplayName(
|
const displayName = sanitizeDisplayName(
|
||||||
profile.displayName || sanitizeHandle(profile.handle),
|
profile.displayName || sanitizeHandle(profile.handle),
|
||||||
moderation.ui('displayName'),
|
moderation.ui('displayName'),
|
||||||
@@ -639,10 +637,7 @@ function AccountRow({
|
|||||||
<UserAvatar
|
<UserAvatar
|
||||||
size={28}
|
size={28}
|
||||||
avatar={profile.avatar}
|
avatar={profile.avatar}
|
||||||
// TODO(phase4): drop toLex once ProfileViewDetailed prop emits #/lexicons views
|
moderation={moderateProfile(profile, moderationOpts).ui('avatar')}
|
||||||
moderation={moderateProfile(toLex(profile), moderationOpts).ui(
|
|
||||||
'avatar',
|
|
||||||
)}
|
|
||||||
type={profile.associated?.labeler ? 'labeler' : 'user'}
|
type={profile.associated?.labeler ? 'labeler' : 'user'}
|
||||||
live={live}
|
live={live}
|
||||||
hideLiveBadge
|
hideLiveBadge
|
||||||
|
|||||||
@@ -411,8 +411,7 @@ function Header({
|
|||||||
const richText = record.description
|
const richText = record.description
|
||||||
? new RichTextAPI({
|
? new RichTextAPI({
|
||||||
text: record.description,
|
text: record.description,
|
||||||
// TODO(phase4): drop toLex once the starterpack record producer emits #/lexicons facets
|
facets: record.descriptionFacets,
|
||||||
facets: bsky.toLex(record.descriptionFacets),
|
|
||||||
})
|
})
|
||||||
: undefined
|
: undefined
|
||||||
|
|
||||||
|
|||||||
@@ -808,8 +808,7 @@ function Overlay({
|
|||||||
: undefined
|
: undefined
|
||||||
const richText = new RichTextAPI({
|
const richText = new RichTextAPI({
|
||||||
text: record?.text || '',
|
text: record?.text || '',
|
||||||
// TODO(phase4): drop toLex once the post record producer emits #/lexicons facets
|
facets: record?.facets,
|
||||||
facets: bsky.toLex(record?.facets),
|
|
||||||
})
|
})
|
||||||
const handle = sanitizeHandle(post.author.handle, '@')
|
const handle = sanitizeHandle(post.author.handle, '@')
|
||||||
|
|
||||||
|
|||||||
@@ -205,12 +205,8 @@ export function useFeedPreviews(
|
|||||||
if (item.isFallbackMarker) continue
|
if (item.isFallbackMarker) continue
|
||||||
|
|
||||||
const moderations = item.items.map(item =>
|
const moderations = item.items.map(item =>
|
||||||
// TODO(phase4): drop toLex once feed-manip is migrated off
|
|
||||||
// @atproto/api and yields lex-typed slice items.
|
// @atproto/api and yields lex-typed slice items.
|
||||||
moderatePost(
|
moderatePost(item.post, moderationOpts!),
|
||||||
bsky.toLex<app.bsky.feed.defs.PostView>(item.post),
|
|
||||||
moderationOpts!,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// apply moderation filters
|
// apply moderation filters
|
||||||
@@ -236,19 +232,12 @@ export function useFeedPreviews(
|
|||||||
const feedPostSliceItem: FeedPostSliceItem = {
|
const feedPostSliceItem: FeedPostSliceItem = {
|
||||||
_reactKey: `${item._reactKey}-${i}-${subItem.post.uri}`,
|
_reactKey: `${item._reactKey}-${i}-${subItem.post.uri}`,
|
||||||
uri: subItem.post.uri,
|
uri: subItem.post.uri,
|
||||||
// TODO(phase4): drop toLex once feed-manip is migrated
|
|
||||||
// off @atproto/api and yields lex-typed slice items.
|
// off @atproto/api and yields lex-typed slice items.
|
||||||
post: bsky.toLex<app.bsky.feed.defs.PostView>(
|
post: subItem.post,
|
||||||
subItem.post,
|
record: subItem.record,
|
||||||
),
|
|
||||||
record: bsky.toLex<app.bsky.feed.post.Main>(
|
|
||||||
subItem.record,
|
|
||||||
),
|
|
||||||
moderation: moderations[i],
|
moderation: moderations[i],
|
||||||
parentAuthor: subItem.parentAuthor
|
parentAuthor: subItem.parentAuthor
|
||||||
? bsky.toLex<app.bsky.actor.defs.ProfileViewBasic>(
|
? subItem.parentAuthor
|
||||||
subItem.parentAuthor,
|
|
||||||
)
|
|
||||||
: undefined,
|
: undefined,
|
||||||
isParentBlocked: subItem.isParentBlocked,
|
isParentBlocked: subItem.isParentBlocked,
|
||||||
isParentNotFound: subItem.isParentNotFound,
|
isParentNotFound: subItem.isParentNotFound,
|
||||||
|
|||||||
@@ -57,33 +57,24 @@ export function useAddGroupMembers(
|
|||||||
chat.bsky.actor.defs.ProfileViewBasic[]
|
chat.bsky.actor.defs.ProfileViewBasic[]
|
||||||
>(listConvoMembersQueryKey(convoId))
|
>(listConvoMembersQueryKey(convoId))
|
||||||
|
|
||||||
/*
|
|
||||||
* The profile views come from producers that still emit the old
|
|
||||||
* `@atproto/api` shapes (useProfileQuery migrates in a later task), while
|
|
||||||
* the chat caches are now typed on the lexicon views. Structurally
|
|
||||||
* identical modulo branded strings. TODO(phase4): drop toLex once those
|
|
||||||
* producers migrate.
|
|
||||||
*/
|
|
||||||
const addedBy: chat.bsky.actor.defs.ProfileViewBasic | undefined =
|
const addedBy: chat.bsky.actor.defs.ProfileViewBasic | undefined =
|
||||||
myProfile
|
myProfile
|
||||||
? bsky.toLex<chat.bsky.actor.defs.ProfileViewBasic>({
|
? {
|
||||||
...myProfile,
|
...myProfile,
|
||||||
$type: 'chat.bsky.actor.defs#profileViewBasic',
|
$type: 'chat.bsky.actor.defs#profileViewBasic',
|
||||||
})
|
}
|
||||||
: undefined
|
: undefined
|
||||||
|
|
||||||
const optimisticMembers: chat.bsky.actor.defs.ProfileViewBasic[] =
|
const optimisticMembers: chat.bsky.actor.defs.ProfileViewBasic[] =
|
||||||
profiles.map(profile =>
|
profiles.map(profile => ({
|
||||||
bsky.toLex<chat.bsky.actor.defs.ProfileViewBasic>({
|
...profile,
|
||||||
...profile,
|
$type: 'chat.bsky.actor.defs#profileViewBasic',
|
||||||
$type: 'chat.bsky.actor.defs#profileViewBasic',
|
kind: {
|
||||||
kind: {
|
$type: 'chat.bsky.actor.defs#groupConvoMember',
|
||||||
$type: 'chat.bsky.actor.defs#groupConvoMember',
|
role: 'standard',
|
||||||
role: 'standard',
|
addedBy,
|
||||||
addedBy,
|
},
|
||||||
},
|
}))
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
queryClient.setQueryData<chat.bsky.convo.defs.ConvoView>(
|
queryClient.setQueryData<chat.bsky.convo.defs.ConvoView>(
|
||||||
CONVO_KEY(convoId),
|
CONVO_KEY(convoId),
|
||||||
|
|||||||
@@ -297,11 +297,8 @@ export function* findAllPostsInQueryData(
|
|||||||
if (bsky.isType(app.bsky.feed.defs.postView, item.subject)) {
|
if (bsky.isType(app.bsky.feed.defs.postView, item.subject)) {
|
||||||
const quotedPost = getEmbeddedPost(item.subject?.embed)
|
const quotedPost = getEmbeddedPost(item.subject?.embed)
|
||||||
if (quotedPost && didOrHandleUriMatches(atUri, quotedPost)) {
|
if (quotedPost && didOrHandleUriMatches(atUri, quotedPost)) {
|
||||||
// TODO(phase4): drop toLex once ../util is migrated and
|
|
||||||
// embedViewRecordToPostView returns the lexicon PostView.
|
// embedViewRecordToPostView returns the lexicon PostView.
|
||||||
yield bsky.toLex<app.bsky.feed.defs.PostView>(
|
yield embedViewRecordToPostView(quotedPost)
|
||||||
embedViewRecordToPostView(quotedPost),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -288,9 +288,8 @@ export function usePostFeedQuery(
|
|||||||
.map(slice => {
|
.map(slice => {
|
||||||
const moderations = slice.items.map(item =>
|
const moderations = slice.items.map(item =>
|
||||||
moderatePost(
|
moderatePost(
|
||||||
// TODO(phase4): drop toLex once feed-manip is migrated
|
|
||||||
// off @atproto/api and yields lex-typed slice items.
|
// off @atproto/api and yields lex-typed slice items.
|
||||||
bsky.toLex<app.bsky.feed.defs.PostView>(item.post),
|
item.post,
|
||||||
moderationOpts!,
|
moderationOpts!,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -342,19 +341,12 @@ export function usePostFeedQuery(
|
|||||||
const feedPostSliceItem: FeedPostSliceItem = {
|
const feedPostSliceItem: FeedPostSliceItem = {
|
||||||
_reactKey: `${slice._reactKey}-${i}-${item.post.uri}`,
|
_reactKey: `${slice._reactKey}-${i}-${item.post.uri}`,
|
||||||
uri: item.post.uri,
|
uri: item.post.uri,
|
||||||
// TODO(phase4): drop toLex once feed-manip is migrated
|
|
||||||
// off @atproto/api and yields lex-typed slice items.
|
// off @atproto/api and yields lex-typed slice items.
|
||||||
post: bsky.toLex<app.bsky.feed.defs.PostView>(
|
post: item.post,
|
||||||
item.post,
|
record: item.record,
|
||||||
),
|
|
||||||
record: bsky.toLex<app.bsky.feed.post.Main>(
|
|
||||||
item.record,
|
|
||||||
),
|
|
||||||
moderation: moderations[i],
|
moderation: moderations[i],
|
||||||
parentAuthor: item.parentAuthor
|
parentAuthor: item.parentAuthor
|
||||||
? bsky.toLex<app.bsky.actor.defs.ProfileViewBasic>(
|
? item.parentAuthor
|
||||||
item.parentAuthor,
|
|
||||||
)
|
|
||||||
: undefined,
|
: undefined,
|
||||||
isParentBlocked: item.isParentBlocked,
|
isParentBlocked: item.isParentBlocked,
|
||||||
isParentNotFound: item.isParentNotFound,
|
isParentNotFound: item.isParentNotFound,
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ import {useAgeAssurance} from '#/ageAssurance'
|
|||||||
import {makeAgeRestrictedModerationPrefs} from '#/ageAssurance/util'
|
import {makeAgeRestrictedModerationPrefs} from '#/ageAssurance/util'
|
||||||
import {useAnalytics} from '#/analytics'
|
import {useAnalytics} from '#/analytics'
|
||||||
import {app} from '#/lexicons'
|
import {app} from '#/lexicons'
|
||||||
import {toLex} from '#/types/bsky'
|
|
||||||
|
|
||||||
export * from '#/state/queries/preferences/const'
|
export * from '#/state/queries/preferences/const'
|
||||||
export * from '#/state/queries/preferences/moderation'
|
export * from '#/state/queries/preferences/moderation'
|
||||||
@@ -110,16 +109,8 @@ export function usePreferencesQuery() {
|
|||||||
) {
|
) {
|
||||||
data = {
|
data = {
|
||||||
...data,
|
...data,
|
||||||
/*
|
moderationPrefs: makeAgeRestrictedModerationPrefs(
|
||||||
* TODO(phase4): drop the toLex bridges once
|
data.moderationPrefs,
|
||||||
* `#/ageAssurance/util` (makeAgeRestrictedModerationPrefs) sources
|
|
||||||
* `ModerationPrefs` from `@bsky.app/sdk/moderation` instead of
|
|
||||||
* `@atproto/api`. The two shapes differ only in scalar branding
|
|
||||||
* (e.g. MutedWord.actorTarget's UnknownString), so the values are
|
|
||||||
* structurally interchangeable at this boundary.
|
|
||||||
*/
|
|
||||||
moderationPrefs: toLex(
|
|
||||||
makeAgeRestrictedModerationPrefs(toLex(data.moderationPrefs)),
|
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
resolveLink,
|
resolveLink,
|
||||||
} from '#/lib/api/resolve'
|
} from '#/lib/api/resolve'
|
||||||
import {STALE} from '#/state/queries/index'
|
import {STALE} from '#/state/queries/index'
|
||||||
import {useAgent, useChatClient, useLexClient} from '#/state/session'
|
import {useChatClient, useLexClient} from '#/state/session'
|
||||||
import {type Gif} from '#/features/gifPicker/types'
|
import {type Gif} from '#/features/gifPicker/types'
|
||||||
|
|
||||||
export const RQKEY_LINK_ROOT = 'resolve-link'
|
export const RQKEY_LINK_ROOT = 'resolve-link'
|
||||||
@@ -26,15 +26,13 @@ export function resolveLinkQueryOptions(clients: ResolveClients, url: string) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Bundle the clients the link resolver needs from the session hooks. The
|
* Bundle the clients the link resolver needs from the session hooks. The
|
||||||
* appview client serves the `app.bsky.*` reads and handle resolution, the chat
|
* appview client serves the `app.bsky.*` reads and handle resolution, and the
|
||||||
* client serves group join-link previews, and the bridge agent is still passed
|
* chat client serves group join-link previews.
|
||||||
* through to the not-yet-migrated `getLinkMeta`.
|
|
||||||
*/
|
*/
|
||||||
export function useResolveClients(): ResolveClients {
|
export function useResolveClients(): ResolveClients {
|
||||||
const appview = useLexClient()
|
const appview = useLexClient()
|
||||||
const chat = useChatClient()
|
const chat = useChatClient()
|
||||||
const agent = useAgent()
|
return {appview, chat}
|
||||||
return {appview, chat, agent}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useResolveLinkQuery(url: string) {
|
export function useResolveLinkQuery(url: string) {
|
||||||
|
|||||||
@@ -255,27 +255,23 @@ export function* getThreadPlaceholderCandidates(
|
|||||||
for (let post of findAllPostsInNotifsQueryData(queryClient, uri)) {
|
for (let post of findAllPostsInNotifsQueryData(queryClient, uri)) {
|
||||||
yield postViewToThreadPlaceholder(post)
|
yield postViewToThreadPlaceholder(post)
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* TODO(phase4): drop toLex once the feed/quote/search/bookmarks/explore
|
|
||||||
* `findAllPostsInQueryData` generators are migrated to `#/lexicons` types.
|
|
||||||
*/
|
|
||||||
for (let post of findAllPostsInFeedQueryData(queryClient, uri)) {
|
for (let post of findAllPostsInFeedQueryData(queryClient, uri)) {
|
||||||
yield postViewToThreadPlaceholder(bsky.toLex(post))
|
yield postViewToThreadPlaceholder(post)
|
||||||
}
|
}
|
||||||
for (let post of findAllPostsInQuoteQueryData(queryClient, uri)) {
|
for (let post of findAllPostsInQuoteQueryData(queryClient, uri)) {
|
||||||
yield postViewToThreadPlaceholder(bsky.toLex(post))
|
yield postViewToThreadPlaceholder(post)
|
||||||
}
|
}
|
||||||
for (let post of findAllPostsInSearchQueryData(queryClient, uri)) {
|
for (let post of findAllPostsInSearchQueryData(queryClient, uri)) {
|
||||||
yield postViewToThreadPlaceholder(bsky.toLex(post))
|
yield postViewToThreadPlaceholder(post)
|
||||||
}
|
}
|
||||||
for (let post of findAllPostsInBookmarksQueryData(queryClient, uri)) {
|
for (let post of findAllPostsInBookmarksQueryData(queryClient, uri)) {
|
||||||
yield postViewToThreadPlaceholder(bsky.toLex(post))
|
yield postViewToThreadPlaceholder(post)
|
||||||
}
|
}
|
||||||
for (let post of findAllPostsInExploreFeedPreviewsQueryData(
|
for (let post of findAllPostsInExploreFeedPreviewsQueryData(
|
||||||
queryClient,
|
queryClient,
|
||||||
uri,
|
uri,
|
||||||
)) {
|
)) {
|
||||||
yield postViewToThreadPlaceholder(bsky.toLex(post))
|
yield postViewToThreadPlaceholder(post)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,11 +298,7 @@ export function* findAllPostsInQueryData(
|
|||||||
|
|
||||||
const qp = getEmbeddedPost(item.value.post.embed)
|
const qp = getEmbeddedPost(item.value.post.embed)
|
||||||
if (qp && didOrHandleUriMatches(atUri, qp)) {
|
if (qp && didOrHandleUriMatches(atUri, qp)) {
|
||||||
/*
|
yield embedViewRecordToPostView(qp)
|
||||||
* TODO(phase4): drop toLex once `embedViewRecordToPostView` in
|
|
||||||
* `#/state/queries/util` is migrated to `#/lexicons` types.
|
|
||||||
*/
|
|
||||||
yield bsky.toLex(embedViewRecordToPostView(qp))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -335,11 +327,7 @@ export function* findAllProfilesInQueryData(
|
|||||||
|
|
||||||
const qp = getEmbeddedPost(item.value.post.embed)
|
const qp = getEmbeddedPost(item.value.post.embed)
|
||||||
if (qp && qp.author.did === did) {
|
if (qp && qp.author.did === did) {
|
||||||
/*
|
yield qp.author
|
||||||
* TODO(phase4): drop toLex once `getEmbeddedPost` in
|
|
||||||
* `#/state/queries/util` is migrated to `#/lexicons` types.
|
|
||||||
*/
|
|
||||||
yield bsky.toLex(qp.author)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ const ApiContext = createContext<SessionApiContext>({
|
|||||||
resumeSession: async () => {},
|
resumeSession: async () => {},
|
||||||
removeAccount: () => {},
|
removeAccount: () => {},
|
||||||
partialRefreshSession: async () => {},
|
partialRefreshSession: async () => {},
|
||||||
|
refreshSession: () => Promise.resolve(undefined),
|
||||||
})
|
})
|
||||||
ApiContext.displayName = 'SessionApiContext'
|
ApiContext.displayName = 'SessionApiContext'
|
||||||
|
|
||||||
@@ -344,6 +345,28 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
|||||||
})
|
})
|
||||||
}, [store, state, cancelPendingTask])
|
}, [store, state, cancelPendingTask])
|
||||||
|
|
||||||
|
const refreshSession = useCallback<
|
||||||
|
SessionApiContext['refreshSession']
|
||||||
|
>(async () => {
|
||||||
|
const bundle = store.getState().currentAgentState.agent as unknown as
|
||||||
|
| SessionBundle
|
||||||
|
| PublicSessionBundle
|
||||||
|
if (!bundle.session) return undefined // logged out: nothing to refresh
|
||||||
|
/*
|
||||||
|
* PasswordSession.refresh() re-runs com.atproto.server.refreshSession +
|
||||||
|
* getSession. On success the session's onUpdated hook fires, which the
|
||||||
|
* armed makeSessionHooks wiring maps to an 'update' event; the reducer
|
||||||
|
* snapshots the refreshed account. No explicit dispatch is needed here.
|
||||||
|
* The returned snapshot lets callers read post-refresh fields without
|
||||||
|
* waiting on the (async) reducer update.
|
||||||
|
*/
|
||||||
|
await bundle.session.refresh()
|
||||||
|
return sessionDataToSessionAccount(
|
||||||
|
bundle.session.session,
|
||||||
|
bundle.session.session.service,
|
||||||
|
)
|
||||||
|
}, [store])
|
||||||
|
|
||||||
const removeAccount = useCallback<SessionApiContext['removeAccount']>(
|
const removeAccount = useCallback<SessionApiContext['removeAccount']>(
|
||||||
account => {
|
account => {
|
||||||
addSessionDebugLog({
|
addSessionDebugLog({
|
||||||
@@ -443,6 +466,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
|||||||
resumeSession,
|
resumeSession,
|
||||||
removeAccount,
|
removeAccount,
|
||||||
partialRefreshSession,
|
partialRefreshSession,
|
||||||
|
refreshSession,
|
||||||
}),
|
}),
|
||||||
[
|
[
|
||||||
createAccount,
|
createAccount,
|
||||||
@@ -452,6 +476,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
|||||||
resumeSession,
|
resumeSession,
|
||||||
removeAccount,
|
removeAccount,
|
||||||
partialRefreshSession,
|
partialRefreshSession,
|
||||||
|
refreshSession,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -51,4 +51,15 @@ export type SessionApiContext = {
|
|||||||
* `persistSessionHandler`.
|
* `persistSessionHandler`.
|
||||||
*/
|
*/
|
||||||
partialRefreshSession: () => Promise<void>
|
partialRefreshSession: () => Promise<void>
|
||||||
|
/**
|
||||||
|
* Force a full session refresh (re-runs `com.atproto.server.refreshSession`
|
||||||
|
* plus `getSession`) and return the refreshed account snapshot, or
|
||||||
|
* `undefined` when logged out.
|
||||||
|
*
|
||||||
|
* The refresh routes through the session's own `refresh()`, whose success
|
||||||
|
* hook propagates the updated account into state; the returned snapshot lets
|
||||||
|
* callers read post-refresh fields synchronously without waiting on the
|
||||||
|
* (async) reducer update. Rejections propagate to the caller.
|
||||||
|
*/
|
||||||
|
refreshSession: () => Promise<SessionAccount | undefined>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import {mimeToExt} from '#/lib/media/video/util'
|
|||||||
import {shortenLinks} from '#/lib/strings/rich-text-manip'
|
import {shortenLinks} from '#/lib/strings/rich-text-manip'
|
||||||
import {type ComposerImage} from '#/state/gallery'
|
import {type ComposerImage} from '#/state/gallery'
|
||||||
import {threadgateAllowUISettingToAllowRecordValue} from '#/state/queries/threadgate/util'
|
import {threadgateAllowUISettingToAllowRecordValue} from '#/state/queries/threadgate/util'
|
||||||
import {createPublicAgent} from '#/state/session/agent'
|
|
||||||
import {getPublicLexClient} from '#/state/session/clients'
|
import {getPublicLexClient} from '#/state/session/clients'
|
||||||
import {
|
import {
|
||||||
type ComposerState,
|
type ComposerState,
|
||||||
@@ -141,10 +140,9 @@ async function postDraftToServerPost(
|
|||||||
|
|
||||||
// Add quote record embed
|
// Add quote record embed
|
||||||
if (post.embed.quote) {
|
if (post.embed.quote) {
|
||||||
const agent = createPublicAgent()
|
|
||||||
const publicClient = getPublicLexClient()
|
const publicClient = getPublicLexClient()
|
||||||
const resolved = await resolveLink(
|
const resolved = await resolveLink(
|
||||||
{appview: publicClient, chat: publicClient, agent},
|
{appview: publicClient, chat: publicClient},
|
||||||
post.embed.quote.uri,
|
post.embed.quote.uri,
|
||||||
)
|
)
|
||||||
if (resolved && resolved.type === 'record') {
|
if (resolved && resolved.type === 'record') {
|
||||||
|
|||||||
@@ -148,15 +148,12 @@ let NotificationFeedItem = ({
|
|||||||
{
|
{
|
||||||
profile: item.notification.author,
|
profile: item.notification.author,
|
||||||
href: makeProfileLink(item.notification.author),
|
href: makeProfileLink(item.notification.author),
|
||||||
moderation: moderateProfile(
|
moderation: moderateProfile(item.notification.author, moderationOpts),
|
||||||
bsky.toLex(item.notification.author),
|
|
||||||
moderationOpts,
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
...(item.additional?.map(({author}) => ({
|
...(item.additional?.map(({author}) => ({
|
||||||
profile: author,
|
profile: author,
|
||||||
href: makeProfileLink(author),
|
href: makeProfileLink(author),
|
||||||
moderation: moderateProfile(bsky.toLex(author), moderationOpts),
|
moderation: moderateProfile(author, moderationOpts),
|
||||||
})) || []),
|
})) || []),
|
||||||
].filter(
|
].filter(
|
||||||
(author, index, arr) =>
|
(author, index, arr) =>
|
||||||
|
|||||||
@@ -73,8 +73,7 @@ export function PostQuotes({uri}: {uri: string}) {
|
|||||||
) {
|
) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
// TODO(phase4): drop toLex once usePostQuotesQuery emits #/lexicons views
|
const moderation = moderatePost(post, moderationOpts)
|
||||||
const moderation = moderatePost(bsky.toLex(post), moderationOpts)
|
|
||||||
return {post, record: post.record, moderation}
|
return {post, record: post.record, moderation}
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -61,17 +61,13 @@ export function Post({
|
|||||||
record
|
record
|
||||||
? new RichTextAPI({
|
? new RichTextAPI({
|
||||||
text: record.text,
|
text: record.text,
|
||||||
// TODO(phase4): drop toLex once the post record producer emits #/lexicons facets
|
facets: record.facets,
|
||||||
facets: bsky.toLex(record.facets),
|
|
||||||
})
|
})
|
||||||
: undefined,
|
: undefined,
|
||||||
[record],
|
[record],
|
||||||
)
|
)
|
||||||
const moderation = useMemo(
|
const moderation = useMemo(
|
||||||
() =>
|
() => (moderationOpts ? moderatePost(post, moderationOpts) : undefined),
|
||||||
moderationOpts
|
|
||||||
? moderatePost(bsky.toLex(post), moderationOpts)
|
|
||||||
: undefined,
|
|
||||||
[moderationOpts, post],
|
[moderationOpts, post],
|
||||||
)
|
)
|
||||||
if (postShadowed === POST_TOMBSTONE) {
|
if (postShadowed === POST_TOMBSTONE) {
|
||||||
@@ -135,8 +131,7 @@ function PostInner({
|
|||||||
text: record.text,
|
text: record.text,
|
||||||
author: post.author,
|
author: post.author,
|
||||||
embed: post.embed,
|
embed: post.embed,
|
||||||
// TODO(phase4): drop toLex once the composer state accepts SDK ModerationDecision
|
moderation: moderation,
|
||||||
moderation: bsky.toLex(moderation),
|
|
||||||
langs: record.langs,
|
langs: record.langs,
|
||||||
},
|
},
|
||||||
logContext: 'PostReply',
|
logContext: 'PostReply',
|
||||||
|
|||||||
@@ -99,8 +99,7 @@ export function PostFeedItem({
|
|||||||
() =>
|
() =>
|
||||||
new RichTextAPI({
|
new RichTextAPI({
|
||||||
text: record.text,
|
text: record.text,
|
||||||
// TODO(phase4): drop toLex once the post record producer emits #/lexicons facets
|
facets: record.facets,
|
||||||
facets: bsky.toLex(record.facets),
|
|
||||||
}),
|
}),
|
||||||
[record],
|
[record],
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user