mirror of
https://github.com/CompassConnections/Compass.git
synced 2026-07-30 09:48:47 -04:00
Add Signal support for social links, including URL handling, placeholder text, and icon rendering. Update version to 1.30.0.
This commit is contained in:
@@ -11,8 +11,8 @@ android {
|
||||
applicationId "com.compassconnections.app"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 125
|
||||
versionName "1.29.1"
|
||||
versionCode 126
|
||||
versionName "1.30.0"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
aaptOptions {
|
||||
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
|
||||
|
||||
@@ -1067,6 +1067,7 @@
|
||||
"profile.optional.subtitle": "Optionale Informationen",
|
||||
"profile.optional.title": "Mehr Informationen über mich",
|
||||
"profile.optional.university": "Universität",
|
||||
"profile.optional.signal_placeholder": "Telefonnummer oder signal.me-Link",
|
||||
"profile.optional.username_or_url": "Benutzername oder URL",
|
||||
"profile.optional.want_kids": "Ich möchte Kinder haben",
|
||||
"profile.optional.work": "Arbeit",
|
||||
|
||||
@@ -1066,6 +1066,7 @@
|
||||
"profile.optional.subtitle": "Informations optionnelles",
|
||||
"profile.optional.title": "Plus d'informations à mon sujet",
|
||||
"profile.optional.university": "Université",
|
||||
"profile.optional.signal_placeholder": "Numéro de téléphone ou lien signal.me",
|
||||
"profile.optional.username_or_url": "Nom d'utilisateur ou URL",
|
||||
"profile.optional.want_kids": "Je souhaite avoir des enfants",
|
||||
"profile.optional.work": "Domaine de travail",
|
||||
|
||||
@@ -5,6 +5,7 @@ export const SITE_ORDER = [
|
||||
'site', // personal site
|
||||
'x', // twitter
|
||||
'discord',
|
||||
'signal',
|
||||
'bluesky',
|
||||
'mastodon',
|
||||
'substack',
|
||||
@@ -55,6 +56,8 @@ const stripper: {[key in Site]: (input: string) => string} = {
|
||||
.replace(/^@/, '')
|
||||
.replace(/\/$/, ''),
|
||||
discord: (s) => s,
|
||||
// strip a signal.me deep link down to the phone number / handle for display
|
||||
signal: (s) => s.replace(/^(https?:\/\/)?(www\.)?signal\.me\/#[a-z]+\//i, '').replace(/\/$/, ''),
|
||||
paypal: (s) =>
|
||||
s.replace(/^(https?:\/\/)?(www\.)?(\w+\.)?paypal\.com\/paypalme\//, '').replace(/\/$/, ''),
|
||||
patreon: (s) => s.replace(/^(https?:\/\/)?(www\.)?(\w+\.)?patreon\.com\//, '').replace(/\/$/, ''),
|
||||
@@ -100,6 +103,16 @@ const urler: {[key in Site]: (handle: string) => string} = {
|
||||
(s.length === 17 || s.length === 18) && !isNaN(parseInt(s, 10))
|
||||
? `https://discord.com/users/${s}` // discord user id
|
||||
: discordLink, // our server
|
||||
// signal.me deep links open the Signal app directly. Phone numbers use #p/,
|
||||
// a full pasted signal.me link (e.g. a username link, #eu/) is kept as-is.
|
||||
signal: (s) => {
|
||||
if (s.startsWith('http')) return s
|
||||
const cleaned = s.replace(/[\s()\-.]/g, '')
|
||||
if (/^\+?\d{7,15}$/.test(cleaned)) {
|
||||
return `https://signal.me/#p/${cleaned.startsWith('+') ? cleaned : `+${cleaned}`}`
|
||||
}
|
||||
return `https://signal.me/#p/${s}`
|
||||
},
|
||||
bluesky: (s) => `https://bsky.app/profile/${s}`,
|
||||
mastodon: (s) => (s.includes('@') ? `https://${s.split('@')[1]}/@${s.split('@')[0]}` : s),
|
||||
substack: (s) => (s.startsWith('http') ? s : `https://${s}.substack.com`),
|
||||
@@ -121,6 +134,7 @@ export const PLATFORM_LABELS: {[key in Site]: string} = {
|
||||
site: 'Website',
|
||||
x: 'Twitter/X',
|
||||
discord: 'Discord',
|
||||
signal: 'Signal',
|
||||
bluesky: 'Bluesky',
|
||||
mastodon: 'Mastodon',
|
||||
substack: 'Substack',
|
||||
|
||||
@@ -55,6 +55,15 @@ describe('strip', () => {
|
||||
expect(strip('linkedin', 'username')).toBe('username')
|
||||
})
|
||||
})
|
||||
|
||||
describe('signal', () => {
|
||||
it('should strip signal.me deep links', () => {
|
||||
expect(strip('signal', 'https://signal.me/#p/+15551234567')).toBe('+15551234567')
|
||||
expect(strip('signal', 'signal.me/#p/+15551234567')).toBe('+15551234567')
|
||||
expect(strip('signal', 'https://signal.me/#eu/abc123')).toBe('abc123')
|
||||
expect(strip('signal', '+15551234567')).toBe('+15551234567')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('getSocialUrl', () => {
|
||||
@@ -69,6 +78,15 @@ describe('getSocialUrl', () => {
|
||||
expect(getSocialUrl('spotify', 'username')).toBe('https://open.spotify.com/user/username')
|
||||
})
|
||||
|
||||
it('should build signal.me deep links from phone numbers', () => {
|
||||
expect(getSocialUrl('signal', '+15551234567')).toBe('https://signal.me/#p/+15551234567')
|
||||
expect(getSocialUrl('signal', '15551234567')).toBe('https://signal.me/#p/+15551234567')
|
||||
expect(getSocialUrl('signal', '+1 (555) 123-4567')).toBe('https://signal.me/#p/+15551234567')
|
||||
expect(getSocialUrl('signal', 'https://signal.me/#eu/abc123')).toBe(
|
||||
'https://signal.me/#eu/abc123',
|
||||
)
|
||||
})
|
||||
|
||||
it('should handle custom website URLs', () => {
|
||||
expect(getSocialUrl('site', 'example.com')).toBe('https://example.com')
|
||||
expect(getSocialUrl('site', 'https://example.com')).toBe('https://example.com')
|
||||
|
||||
@@ -107,9 +107,11 @@ export function SocialLinksSection({profile, setProfile}: SocialLinksSectionProp
|
||||
<Input
|
||||
type="text"
|
||||
placeholder={
|
||||
SITE_ORDER.includes(newLinkPlatform as any) && newLinkPlatform != 'site'
|
||||
? t('profile.optional.username_or_url', 'Username or URL')
|
||||
: t('profile.optional.site_url', 'Site URL')
|
||||
newLinkPlatform === 'signal'
|
||||
? t('profile.optional.signal_placeholder', 'Phone (+32777777777)')
|
||||
: SITE_ORDER.includes(newLinkPlatform as any) && newLinkPlatform != 'site'
|
||||
? t('profile.optional.username_or_url', 'Username or URL')
|
||||
: t('profile.optional.site_url', 'Site URL')
|
||||
}
|
||||
value={newLinkValue}
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => setNewLinkValue(e.target.value)}
|
||||
|
||||
@@ -2,6 +2,7 @@ import {DocumentTextIcon, LinkIcon} from '@heroicons/react/24/solid'
|
||||
import {Site} from 'common/socials'
|
||||
import {ReactNode} from 'react'
|
||||
import {LuBookmark, LuHandshake, LuHeart, LuUsers} from 'react-icons/lu'
|
||||
import {SiSignal} from 'react-icons/si'
|
||||
import {
|
||||
TbBrandBluesky,
|
||||
TbBrandDiscord,
|
||||
@@ -23,6 +24,7 @@ export const PLATFORM_ICONS: {
|
||||
site: LinkIcon,
|
||||
x: TbBrandX,
|
||||
discord: TbBrandDiscord,
|
||||
signal: SiSignal,
|
||||
bluesky: TbBrandBluesky,
|
||||
mastodon: TbBrandMastodon,
|
||||
substack: LuBookmark,
|
||||
|
||||
@@ -13,6 +13,7 @@ import {Row} from '../layout/row'
|
||||
import {SocialIcon} from './social'
|
||||
|
||||
const LABELS_TO_RENDER = [
|
||||
'signal',
|
||||
'okcupid',
|
||||
'calendly',
|
||||
'datingdoc',
|
||||
|
||||
Reference in New Issue
Block a user