Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into eric/nova
Browse files Browse the repository at this point in the history
* origin/main: (67 commits)
  Localize options in "Thread Preferences" screen (#2373)
  Bump ios build number and android version code
  Remove the KeyboardAvoidingView in account creation (close #2333) (#2366)
  1.62
  Create account tweaks (#2365)
  Fix sizing of the leftnav new post btn (#2248)
  Use memory caching for android lightbox (#2354)
  Disable page-transition animations on android (#2352)
  Disable BlurView on android (#2351)
  Handle birth dates as UTC, handle locale formatting (#2363)
  Fix desktop styles a bit
  Disable spanish translation until it's more thoroughly reviewed (#2362)
  minor search screen ux improvements (#2264)
  Temporarily disable the german translation (#2360)
  Web dropdowns (#2358)
  Mark more text as translatable (#2284)
  Remove patched color scheme code (#2340)
  support multiple og:image tags (#2305)
  Fix missing avatar moderation in replies (#2325)
  Fixes to feed load triggers (#2323)
  ...
  • Loading branch information
estrattonbailey committed Jan 1, 2024
2 parents c58a4d0 + 4e9e92f commit af5c048
Show file tree
Hide file tree
Showing 130 changed files with 11,902 additions and 2,473 deletions.
167 changes: 140 additions & 27 deletions __tests__/lib/string.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {RichText} from '@atproto/api'
import {
getYoutubeVideoId,
makeRecordUri,
toNiceDomain,
toShortUrl,
Expand All @@ -12,6 +11,7 @@ import {detectLinkables} from '../../src/lib/strings/rich-text-detection'
import {shortenLinks} from '../../src/lib/strings/rich-text-manip'
import {makeValidHandle, createFullHandle} from '../../src/lib/strings/handles'
import {cleanError} from '../../src/lib/strings/errors'
import {parseEmbedPlayerFromUrl} from 'lib/strings/embed-player'

describe('detectLinkables', () => {
const inputs = [
Expand Down Expand Up @@ -335,32 +335,6 @@ describe('toShareUrl', () => {
})
})

describe('getYoutubeVideoId', () => {
it(' should return undefined for invalid youtube links', () => {
expect(getYoutubeVideoId('')).toBeUndefined()
expect(getYoutubeVideoId('https://www.google.com')).toBeUndefined()
expect(getYoutubeVideoId('https://www.youtube.com')).toBeUndefined()
expect(
getYoutubeVideoId('https://www.youtube.com/channelName'),
).toBeUndefined()
expect(
getYoutubeVideoId('https://www.youtube.com/channel/channelName'),
).toBeUndefined()
})

it('getYoutubeVideoId should return video id for valid youtube links', () => {
expect(getYoutubeVideoId('https://www.youtube.com/watch?v=videoId')).toBe(
'videoId',
)
expect(
getYoutubeVideoId(
'https://www.youtube.com/watch?v=videoId&feature=share',
),
).toBe('videoId')
expect(getYoutubeVideoId('https://youtu.be/videoId')).toBe('videoId')
})
})

describe('shortenLinks', () => {
const inputs = [
'start https://middle.com/foo/bar?baz=bux#hash end',
Expand Down Expand Up @@ -396,6 +370,7 @@ describe('shortenLinks', () => {
],
],
]

it('correctly shortens rich text while preserving facet URIs', () => {
for (let i = 0; i < inputs.length; i++) {
const input = inputs[i]
Expand All @@ -410,3 +385,141 @@ describe('shortenLinks', () => {
}
})
})

describe('parseEmbedPlayerFromUrl', () => {
const inputs = [
'https://youtu.be/videoId',
'https://www.youtube.com/watch?v=videoId',
'https://www.youtube.com/watch?v=videoId&feature=share',
'https://youtube.com/watch?v=videoId',
'https://youtube.com/watch?v=videoId&feature=share',
'https://youtube.com/shorts/videoId',

'https://youtube.com/shorts/',
'https://youtube.com/',
'https://youtube.com/random',

'https://twitch.tv/channelName',
'https://www.twitch.tv/channelName',

'https://open.spotify.com/playlist/playlistId',
'https://open.spotify.com/playlist/playlistId?param=value',

'https://open.spotify.com/track/songId',
'https://open.spotify.com/track/songId?param=value',

'https://open.spotify.com/album/albumId',
'https://open.spotify.com/album/albumId?param=value',

'https://soundcloud.com/user/track',
'https://soundcloud.com/user/sets/set',
'https://soundcloud.com/user/',
]

const outputs = [
{
type: 'youtube_video',
videoId: 'videoId',
playerUri: 'https://www.youtube.com/embed/videoId?autoplay=1',
},
{
type: 'youtube_video',
videoId: 'videoId',
playerUri: 'https://www.youtube.com/embed/videoId?autoplay=1',
},
{
type: 'youtube_video',
videoId: 'videoId',
playerUri: 'https://www.youtube.com/embed/videoId?autoplay=1',
},
{
type: 'youtube_video',
videoId: 'videoId',
playerUri: 'https://www.youtube.com/embed/videoId?autoplay=1',
},
{
type: 'youtube_video',
videoId: 'videoId',
playerUri: 'https://www.youtube.com/embed/videoId?autoplay=1',
},
{
type: 'youtube_video',
videoId: 'videoId',
playerUri: 'https://www.youtube.com/embed/videoId?autoplay=1',
},
undefined,
undefined,
undefined,

{
type: 'twitch_live',
channelId: 'channelName',
playerUri: `https://player.twitch.tv/?volume=0.5&!muted&autoplay&channel=channelName&parent=localhost`,
},
{
type: 'twitch_live',
channelId: 'channelName',
playerUri: `https://player.twitch.tv/?volume=0.5&!muted&autoplay&channel=channelName&parent=localhost`,
},

{
type: 'spotify_playlist',
playlistId: 'playlistId',
playerUri: `https://open.spotify.com/embed/playlist/playlistId`,
},
{
type: 'spotify_playlist',
playlistId: 'playlistId',
playerUri: `https://open.spotify.com/embed/playlist/playlistId`,
},

{
type: 'spotify_song',
songId: 'songId',
playerUri: `https://open.spotify.com/embed/track/songId`,
},
{
type: 'spotify_song',
songId: 'songId',
playerUri: `https://open.spotify.com/embed/track/songId`,
},

{
type: 'spotify_album',
albumId: 'albumId',
playerUri: `https://open.spotify.com/embed/album/albumId`,
},
{
type: 'spotify_album',
albumId: 'albumId',
playerUri: `https://open.spotify.com/embed/album/albumId`,
},

{
type: 'soundcloud_track',
user: 'user',
track: 'track',
playerUri: `https://w.soundcloud.com/player/?url=https://soundcloud.com/user/track&auto_play=true&visual=false&hide_related=true`,
},
{
type: 'soundcloud_set',
user: 'user',
set: 'set',
playerUri: `https://w.soundcloud.com/player/?url=https://soundcloud.com/user/sets/set&auto_play=true&visual=false&hide_related=true`,
},
undefined,
]

it('correctly grabs the correct id from uri', () => {
for (let i = 0; i < inputs.length; i++) {
const input = inputs[i]
const output = outputs[i]

const res = parseEmbedPlayerFromUrl(input)

console.log(input)

expect(res).toEqual(output)
}
})
})
7 changes: 5 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 = '4'
const IOS_BUILD_NUMBER = '2'

/**
* Android build number. Must be incremented for each release.
*/
const ANDROID_VERSION_CODE = 50
const ANDROID_VERSION_CODE = 53

/**
* Uses built-in Expo env vars
Expand Down Expand Up @@ -110,6 +110,9 @@ module.exports = function () {
[
'expo-build-properties',
{
ios: {
deploymentTarget: '13.4',
},
android: {
compileSdkVersion: 34,
targetSdkVersion: 34,
Expand Down
Binary file modified assets/icon-android-background.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ module.exports = function (api) {
platform: './src/platform',
state: './src/state',
view: './src/view',
crypto: './src/platform/crypto.ts',
},
},
],
Expand Down
57 changes: 47 additions & 10 deletions bskyweb/cmd/bskyweb/rss.go
Original file line number Diff line number Diff line change
@@ -1,24 +1,32 @@
package main

import (
"encoding/xml"
"fmt"
"net/http"
"strings"
"time"

appbsky "github.com/bluesky-social/indigo/api/bsky"
"github.com/bluesky-social/indigo/atproto/syntax"

"github.com/labstack/echo/v4"
)

type ItemGUID struct {
XMLName xml.Name `xml:"guid"`
Value string `xml:",chardata"`
IsPerma bool `xml:"isPermaLink,attr"`
}

// We don't actually populate the title for "posts".
// Some background: https://book.micro.blog/rss-for-microblogs/
type Item struct {
Title string `xml:"title,omitempty"`
Link string `xml:"link,omitempty"`
Description string `xml:"description,omitempty"`
PubDate string `xml:"pubDate,omitempty"`
Author string `xml:"author,omitempty"`
GUID string `xml:"guid,omitempty"`
GUID ItemGUID
}

type rss struct {
Expand All @@ -32,11 +40,33 @@ type rss struct {

func (srv *Server) WebProfileRSS(c echo.Context) error {
ctx := c.Request().Context()
req := c.Request()

identParam := c.Param("ident")

// if not a DID, try parsing as a handle and doing a redirect
if !strings.HasPrefix(identParam, "did:") {
handle, err := syntax.ParseHandle(identParam)
if err != nil {
return echo.NewHTTPError(400, fmt.Sprintf("not a valid handle: %s", identParam))
}

didParam := c.Param("did")
did, err := syntax.ParseDID(didParam)
// check that public view is Ok, and resolve DID
pv, err := appbsky.ActorGetProfile(ctx, srv.xrpcc, handle.String())
if err != nil {
return echo.NewHTTPError(404, fmt.Sprintf("account not found: %s", handle))
}
for _, label := range pv.Labels {
if label.Src == pv.Did && label.Val == "!no-unauthenticated" {
return echo.NewHTTPError(403, fmt.Sprintf("account does not allow public views: %s", handle))
}
}
return c.Redirect(http.StatusFound, fmt.Sprintf("/profile/%s/rss", pv.Did))
}

did, err := syntax.ParseDID(identParam)
if err != nil {
return echo.NewHTTPError(400, fmt.Sprintf("not a valid DID: %s", didParam))
return echo.NewHTTPError(400, fmt.Sprintf("not a valid DID: %s", identParam))
}

// check that public view is Ok
Expand Down Expand Up @@ -71,12 +101,19 @@ func (srv *Server) WebProfileRSS(c echo.Context) error {
if rec.Reply != nil {
continue
}
pubDate := ""
createdAt, err := syntax.ParseDatetimeLenient(rec.CreatedAt)
if nil == err {
pubDate = createdAt.Time().Format(time.RFC822Z)
}
posts = append(posts, Item{
Link: fmt.Sprintf("https://bsky.app/profile/%s/post/%s", pv.Handle, aturi.RecordKey().String()),
Link: fmt.Sprintf("https://%s/profile/%s/post/%s", req.Host, pv.Handle, aturi.RecordKey().String()),
Description: rec.Text,
PubDate: rec.CreatedAt,
Author: "@" + pv.Handle,
GUID: aturi.String(),
PubDate: pubDate,
GUID: ItemGUID{
Value: aturi.String(),
IsPerma: false,
},
})
}

Expand All @@ -91,7 +128,7 @@ func (srv *Server) WebProfileRSS(c echo.Context) error {
feed := &rss{
Version: "2.0",
Description: desc,
Link: fmt.Sprintf("https://bsky.app/profile/%s", pv.Handle),
Link: fmt.Sprintf("https://%s/profile/%s", req.Host, pv.Handle),
Title: title,
Item: posts,
}
Expand Down
9 changes: 7 additions & 2 deletions bskyweb/cmd/bskyweb/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ func serve(cctx *cli.Context) error {
e.GET("/profile/:handle/feed/:rkey/liked-by", server.WebGeneric)

// profile RSS feed (DID not handle)
e.GET("/profile/:did/rss", server.WebProfileRSS)
e.GET("/profile/:ident/rss", server.WebProfileRSS)

// post endpoints; only first populates info
e.GET("/profile/:handle/post/:rkey", server.WebPost)
Expand Down Expand Up @@ -336,7 +336,11 @@ func (srv *Server) WebPost(c echo.Context) error {
data["postView"] = postView
data["requestURI"] = fmt.Sprintf("https://%s%s", req.Host, req.URL.Path)
if postView.Embed != nil && postView.Embed.EmbedImages_View != nil {
data["imgThumbUrl"] = postView.Embed.EmbedImages_View.Images[0].Thumb
var thumbUrls []string
for i := range postView.Embed.EmbedImages_View.Images {
thumbUrls = append(thumbUrls, postView.Embed.EmbedImages_View.Images[i].Thumb)
}
data["imgThumbUrls"] = thumbUrls
}
return c.Render(http.StatusOK, "post.html", data)
}
Expand Down Expand Up @@ -370,6 +374,7 @@ func (srv *Server) WebProfile(c echo.Context) error {
req := c.Request()
data["profileView"] = pv
data["requestURI"] = fmt.Sprintf("https://%s%s", req.Host, req.URL.Path)
data["requestHost"] = req.Host
return c.Render(http.StatusOK, "profile.html", data)
}

Expand Down
Binary file modified bskyweb/static/apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified bskyweb/static/favicon-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified bskyweb/static/favicon-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed bskyweb/static/favicon.ico
Binary file not shown.
Binary file modified bskyweb/static/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified bskyweb/static/social-card-default.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion bskyweb/templates/post.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@
<meta name="description" content="{{ postView.Record.Val.Text }}">
<meta property="og:description" content="{{ postView.Record.Val.Text }}">
{% endif -%}
{%- if imgThumbUrl %}
{%- if imgThumbUrls %}
{% for imgThumbUrl in imgThumbUrls %}
<meta property="og:image" content="{{ imgThumbUrl }}">
{% endfor %}
<meta name="twitter:card" content="summary_large_image">
{%- elif postView.Author.Avatar %}
{# Don't use avatar image in cards; usually looks bad #}
Expand Down
4 changes: 3 additions & 1 deletion bskyweb/templates/profile.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@
{% endif %}
<meta name="twitter:label1" content="Account DID">
<meta name="twitter:value1" content="{{ profileView.Did }}">
<link rel="alternate" type="application/rss+xml" href="/profile/{{ profileView.Did }}/rss">
{%- if requestHost %}
<link rel="alternate" type="application/rss+xml" href="https://{{ requestHost }}/profile/{{ profileView.Did }}/rss">
{% endif %}
{% endif -%}
{%- endblock %}

Expand Down
Loading

0 comments on commit af5c048

Please sign in to comment.