Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into internationalization-…
Browse files Browse the repository at this point in the history
…japanese

* origin/main: (32 commits)
  i18n settings improvements (#2184)
  1.58
  Double the footer on the list members flatlist
  Fix links in profiles (#2178)
  Patch bad migration, sanitize bad value (#2179)
  Hide the mobile reply control if outside the threadgate (#2177)
  Revise FeedSourceCard load state to allow deletion for failures (#2172)
  Handle failed pinned feed fetches when rendering list of pinned feeds (#2173)
  Don't validate embeds when traversing cache (#2174)
  dismiss keyboard when threadgate settings are opened (#2161)
  Clarify MyList filter intent (#2167)
  Additional reductions in request traffic (#2169)
  Fix scroll on native (#2170)
  Fix scroll on profile lists/feeds (#2168)
  Reduce calls to getFeedGenerator and getFeed (#2166)
  Bump ios and android build numbers
  Fix mock-server init
  Add "Who can reply" controls [WIP] (#1954)
  Bump ios build
  Fix empty state width (#2157)
  ...
  • Loading branch information
estrattonbailey committed Dec 12, 2023
2 parents 853dd8b + c6ab6e8 commit 4be2527
Show file tree
Hide file tree
Showing 75 changed files with 9,170 additions and 793 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-and-push-bskyweb-aws.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ on:
push:
branches:
- main
- jake/bskyweb-additions
- traffic-reduction
env:
REGISTRY: ${{ secrets.AWS_ECR_REGISTRY_USEAST2_PACKAGES_REGISTRY }}
USERNAME: ${{ secrets.AWS_ECR_REGISTRY_USEAST2_PACKAGES_USERNAME }}
Expand Down
4 changes: 2 additions & 2 deletions app.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ module.exports = function () {
/**
* iOS build number. Must be incremented for each TestFlight version.
*/
const IOS_BUILD_NUMBER = '10'
const IOS_BUILD_NUMBER = '1'

/**
* Android build number. Must be incremented for each release.
*/
const ANDROID_VERSION_CODE = 46
const ANDROID_VERSION_CODE = 48

/**
* Uses built-in Expo env vars
Expand Down
1 change: 0 additions & 1 deletion jest/test-pds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ export async function createServer(
pds: {
port,
hostname: 'localhost',
dbPostgresSchema: `pds_${id}`,
inviteRequired,
},
bsky: {
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "bsky.app",
"version": "1.57.0",
"version": "1.58.0",
"private": true,
"scripts": {
"prepare": "is-ci || husky install",
Expand Down Expand Up @@ -35,7 +35,7 @@
"intl:compile": "lingui compile"
},
"dependencies": {
"@atproto/api": "^0.7.0",
"@atproto/api": "^0.7.2",
"@bam.tech/react-native-image-resizer": "^3.0.4",
"@braintree/sanitize-url": "^6.0.2",
"@emoji-mart/react": "^1.1.1",
Expand Down Expand Up @@ -169,7 +169,7 @@
"zod": "^3.20.2"
},
"devDependencies": {
"@atproto/dev-env": "^0.2.16",
"@atproto/dev-env": "^0.2.19",
"@babel/core": "^7.23.2",
"@babel/preset-env": "^7.20.0",
"@babel/runtime": "^7.20.0",
Expand Down
5 changes: 4 additions & 1 deletion src/App.native.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ SplashScreen.preventAutoHideAsync()

function InnerApp() {
const colorMode = useColorMode()
const {currentAccount} = useSession()
const {isInitialLoad, currentAccount} = useSession()
const {resumeSession} = useSessionApi()

// init
Expand All @@ -53,6 +53,9 @@ function InnerApp() {
resumeSession(account)
}, [resumeSession])

// wait for session to resume
if (isInitialLoad) return null

return (
<React.Fragment
// Resets the entire tree below when it changes:
Expand Down
5 changes: 4 additions & 1 deletion src/App.web.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import {Provider as UnreadNotifsProvider} from 'state/queries/notifications/unre
import * as persisted from '#/state/persisted'

function InnerApp() {
const {currentAccount} = useSession()
const {isInitialLoad, currentAccount} = useSession()
const {resumeSession} = useSessionApi()
const colorMode = useColorMode()

Expand All @@ -40,6 +40,9 @@ function InnerApp() {
resumeSession(account)
}, [resumeSession])

// wait for session to resume
if (isInitialLoad) return null

return (
<React.Fragment
// Resets the entire tree below when it changes:
Expand Down
3 changes: 0 additions & 3 deletions src/lib/analytics/analytics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ function getClient(): SegmentClient {
}

export const track: TrackEvent = async (...args) => {
logger.info('analytics: track', {args})
await getClient().track(...args)
}

Expand All @@ -40,11 +39,9 @@ export function useAnalytics(): AnalyticsMethods {
if (hasSession) {
return {
async screen(...args) {
logger.info('analytics: screen', {args})
await getClient().screen(...args)
},
async track(...args) {
logger.info('analytics: track', {args})
await getClient().track(...args)
},
}
Expand Down
3 changes: 0 additions & 3 deletions src/lib/analytics/analytics.web.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ function getClient(): SegmentClient {
}

export const track: TrackEvent = async (...args) => {
logger.info('analytics: track', {args})
await getClient().track(...args)
}

Expand All @@ -40,11 +39,9 @@ export function useAnalytics(): AnalyticsMethods {
if (hasSession) {
return {
async screen(...args) {
logger.info('analytics: screen', {args})
await getClient().screen(...args)
},
async track(...args) {
logger.info('analytics: track', {args})
await getClient().track(...args)
},
}
Expand Down
1 change: 1 addition & 0 deletions src/lib/analytics/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ interface TrackPropertiesMap {
'Composer:PastedPhotos': {}
'Composer:CameraOpened': {}
'Composer:GalleryOpened': {}
'Composer:ThreadgateOpened': {}
'HomeScreen:PressCompose': {}
'ProfileScreen:PressCompose': {}
// EDIT PROFILE events
Expand Down
2 changes: 1 addition & 1 deletion src/lib/api/feed/author.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export class AuthorFeedAPI implements FeedAPI {
}

_filter(feed: AppBskyFeedDefs.FeedViewPost[]) {
if (this.params.filter === 'posts_no_replies') {
if (this.params.filter === 'posts_and_author_threads') {
return feed.filter(post => {
const isReply = post.reply
const isRepost = AppBskyFeedDefs.isReasonRepost(post.reason)
Expand Down
28 changes: 10 additions & 18 deletions src/lib/api/feed/merge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export class MergeFeedAPI implements FeedAPI {

// always keep following topped up
if (this.following.numReady < limit) {
promises.push(this.following.fetchNext(60))
await this.following.fetchNext(60)
}

// pick the next feeds to sample from
Expand All @@ -73,9 +73,13 @@ export class MergeFeedAPI implements FeedAPI {
}

// top up the feeds
for (const feed of feeds) {
if (feed.numReady < 5) {
promises.push(feed.fetchNext(10))
const outOfFollows =
!this.following.hasMore && this.following.numReady < limit
if (this.params.mergeFeedEnabled || outOfFollows) {
for (const feed of feeds) {
if (feed.numReady < 5) {
promises.push(feed.fetchNext(10))
}
}
}

Expand Down Expand Up @@ -216,22 +220,10 @@ class MergeFeedSource_Custom extends MergeFeedSource {
super(feedTuners)
this.sourceInfo = {
$type: 'reasonFeedSource',
displayName: feedUri.split('/').pop() || '',
uri: feedUriToHref(feedUri),
uri: feedUri,
href: feedUriToHref(feedUri),
}
this.minDate = new Date(Date.now() - POST_AGE_CUTOFF)
getAgent()
.app.bsky.feed.getFeedGenerator({
feed: feedUri,
})
.then(
res => {
if (this.sourceInfo) {
this.sourceInfo.displayName = res.data.view.displayName
}
},
_err => {},
)
}

protected async _getFeed(
Expand Down
2 changes: 1 addition & 1 deletion src/lib/api/feed/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export interface FeedAPI {
export interface ReasonFeedSource {
$type: 'reasonFeedSource'
uri: string
displayName: string
href: string
}

export function isReasonFeedSource(v: unknown): v is ReasonFeedSource {
Expand Down
52 changes: 51 additions & 1 deletion src/lib/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
AppBskyEmbedExternal,
AppBskyEmbedRecord,
AppBskyEmbedRecordWithMedia,
AppBskyFeedThreadgate,
AppBskyRichtextFacet,
BskyAgent,
ComAtprotoLabelDefs,
Expand All @@ -16,6 +17,7 @@ import {isWeb} from 'platform/detection'
import {ImageModel} from 'state/models/media/image'
import {shortenLinks} from 'lib/strings/rich-text-manip'
import {logger} from '#/logger'
import {ThreadgateSetting} from '#/state/queries/threadgate'

export interface ExternalEmbedDraft {
uri: string
Expand Down Expand Up @@ -54,6 +56,7 @@ interface PostOpts {
extLink?: ExternalEmbedDraft
images?: ImageModel[]
labels?: string[]
threadgate?: ThreadgateSetting[]
onStateChange?: (state: string) => void
langs?: string[]
}
Expand Down Expand Up @@ -227,9 +230,10 @@ export async function post(agent: BskyAgent, opts: PostOpts) {
langs = opts.langs.slice(0, 3)
}

let res
try {
opts.onStateChange?.('Posting...')
return await agent.post({
res = await agent.post({
text: rt.text,
facets: rt.facets,
reply,
Expand All @@ -247,6 +251,52 @@ export async function post(agent: BskyAgent, opts: PostOpts) {
throw e
}
}

try {
// TODO: this needs to be batch-created with the post!
if (opts.threadgate?.length) {
await createThreadgate(agent, res.uri, opts.threadgate)
}
} catch (e: any) {
console.error(`Failed to create threadgate: ${e.toString()}`)
throw new Error(
'Post reply-controls failed to be set. Your post was created but anyone can reply to it.',
)
}

return res
}

async function createThreadgate(
agent: BskyAgent,
postUri: string,
threadgate: ThreadgateSetting[],
) {
let allow: (
| AppBskyFeedThreadgate.MentionRule
| AppBskyFeedThreadgate.FollowingRule
| AppBskyFeedThreadgate.ListRule
)[] = []
if (!threadgate.find(v => v.type === 'nobody')) {
for (const rule of threadgate) {
if (rule.type === 'mention') {
allow.push({$type: 'app.bsky.feed.threadgate#mentionRule'})
} else if (rule.type === 'following') {
allow.push({$type: 'app.bsky.feed.threadgate#followingRule'})
} else if (rule.type === 'list') {
allow.push({
$type: 'app.bsky.feed.threadgate#listRule',
list: rule.list,
})
}
}
}

const postUrip = new AtUri(postUri)
await agent.api.app.bsky.feed.threadgate.create(
{repo: agent.session!.did, rkey: postUrip.rkey},
{post: postUri, createdAt: new Date().toISOString(), allow},
)
}

// helpers
Expand Down
3 changes: 1 addition & 2 deletions src/lib/notifications/notifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,14 @@ export function registerTokenChangeHandler(

export function init(queryClient: QueryClient) {
// handle notifications that are received, both in the foreground or background
// NOTE: currently just here for debug logging
Notifications.addNotificationReceivedListener(event => {
logger.debug(
'Notifications: received',
{event},
logger.DebugContext.notifications,
)
if (event.request.trigger.type === 'push') {
// refresh notifications in the background
truncateAndInvalidate(queryClient, RQKEY_NOTIFS())
// handle payload-based deeplinks
let payload
if (isIOS) {
Expand Down
12 changes: 12 additions & 0 deletions src/locale/__tests__/helpers.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {test, expect} from '@jest/globals'

import {sanitizeAppLanguageSetting} from '#/locale/helpers'
import {AppLanguage} from '#/locale/languages'

test('sanitizeAppLanguageSetting', () => {
expect(sanitizeAppLanguageSetting('en')).toBe(AppLanguage.en)
expect(sanitizeAppLanguageSetting('hi')).toBe(AppLanguage.hi)
expect(sanitizeAppLanguageSetting('foo')).toBe(AppLanguage.en)
expect(sanitizeAppLanguageSetting('en,fr')).toBe(AppLanguage.en)
expect(sanitizeAppLanguageSetting('fr,en')).toBe(AppLanguage.en)
})
37 changes: 36 additions & 1 deletion src/locale/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import {AppBskyFeedDefs, AppBskyFeedPost} from '@atproto/api'
import lande from 'lande'
import {hasProp} from 'lib/type-guards'
import * as bcp47Match from 'bcp-47-match'
import {LANGUAGES_MAP_CODE2, LANGUAGES_MAP_CODE3} from './languages'
import {
AppLanguage,
LANGUAGES_MAP_CODE2,
LANGUAGES_MAP_CODE3,
} from './languages'

export function code2ToCode3(lang: string): string {
if (lang.length === 2) {
Expand Down Expand Up @@ -84,3 +88,34 @@ export function getTranslatorLink(text: string, lang: string): string {
text,
)}`
}

/**
* Returns a valid `appLanguage` value from an arbitrary string.
*
* Contenxt: post-refactor, we populated some user's `appLanguage` setting with
* `postLanguage`, which can be a comma-separated list of values. This breaks
* `appLanguage` handling in the app, so we introduced this util to parse out a
* valid `appLanguage` from the pre-populated `postLanguage` values.
*
* The `appLanguage` will continue to be incorrect until the user returns to
* language settings and selects a new option, at which point we'll re-save
* their choice, which should then be a valid option. Since we don't know when
* this will happen, we should leave this here until we feel it's safe to
* remove, or we re-migrate their storage.
*/
export function sanitizeAppLanguageSetting(appLanguage: string): AppLanguage {
const langs = appLanguage.split(',').filter(Boolean)

for (const lang of langs) {
switch (lang) {
case 'en':
return AppLanguage.en
case 'hi':
return AppLanguage.hi
default:
continue
}
}

return AppLanguage.en
}
Loading

0 comments on commit 4be2527

Please sign in to comment.