adding clickable urls in mobile

This commit is contained in:
Roland Osborne 2023-04-03 11:00:09 -07:00
parent dc8c535793
commit 9f5647fa57
3 changed files with 36 additions and 13 deletions

View File

@ -13,7 +13,6 @@
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
46D8108CBA031189090AFC14 /* Pods_Databag_DatabagTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1181227D40684F18A9414840 /* Pods_Databag_DatabagTests.framework */; };
7B13A774299E21170048D0DD /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7B13A773299E21170048D0DD /* GoogleService-Info.plist */; };
7B6135A329B439B80094A6E7 /* login.png in Resources */ = {isa = PBXBuildFile; fileRef = 7B6135A229B439B80094A6E7 /* login.png */; };
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
A0B1EC4533FCFC5940B5FD7F /* Pods_Databag.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9462C028F47F083241BB7941 /* Pods_Databag.framework */; };
/* End PBXBuildFile section */
@ -43,7 +42,6 @@
5709B34CF0A7D63546082F79 /* Pods-Databag.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Databag.release.xcconfig"; path = "Target Support Files/Pods-Databag/Pods-Databag.release.xcconfig"; sourceTree = "<group>"; };
5B7EB9410499542E8C5724F5 /* Pods-Databag-DatabagTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Databag-DatabagTests.debug.xcconfig"; path = "Target Support Files/Pods-Databag-DatabagTests/Pods-Databag-DatabagTests.debug.xcconfig"; sourceTree = "<group>"; };
7B13A773299E21170048D0DD /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
7B6135A229B439B80094A6E7 /* login.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = login.png; sourceTree = "<group>"; };
7B6135A429B68A7B0094A6E7 /* Databag.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = Databag.entitlements; path = Databag/Databag.entitlements; sourceTree = "<group>"; };
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = Databag/LaunchScreen.storyboard; sourceTree = "<group>"; };
89C6BE57DB24E9ADA2F236DE /* Pods-Databag-DatabagTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Databag-DatabagTests.release.xcconfig"; path = "Target Support Files/Pods-Databag-DatabagTests/Pods-Databag-DatabagTests.release.xcconfig"; sourceTree = "<group>"; };
@ -97,7 +95,6 @@
13B07FB51A68108700A75B9A /* Images.xcassets */,
13B07FB61A68108700A75B9A /* Info.plist */,
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */,
7B6135A229B439B80094A6E7 /* login.png */,
13B07FB71A68108700A75B9A /* main.m */,
);
name = Databag;
@ -253,7 +250,6 @@
buildActionMask = 2147483647;
files = (
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */,
7B6135A329B439B80094A6E7 /* login.png in Resources */,
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
7B13A774299E21170048D0DD /* GoogleService-Info.plist in Resources */,
);
@ -575,7 +571,7 @@
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
@ -647,7 +643,7 @@
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;

View File

@ -131,8 +131,8 @@ export function TopicItem({ item, focused, focus, hosting, remove, update, block
return (
<View style={{ ...styles.wrapper, transform: [{rotate: '180deg'}]}}>
<TouchableOpacity activeOpacity={1} style={styles.item} onPress={focus}>
<View style={styles.header}>
<View style={styles.item}>
<TouchableOpacity activeOpacity={1} onPress={focus} style={styles.header}>
{ state.logo !== 'avatar' && state.logo && (
<Image source={{ uri: state.logo }} style={{ width: 28, height: 28, borderRadius: 6 }} />
)}
@ -141,7 +141,7 @@ export function TopicItem({ item, focused, focus, hosting, remove, update, block
)}
<Text style={{ ...styles.name, color: state.nameSet ? Colors.text : Colors.grey }}>{ state.name }</Text>
<Text style={styles.timestamp}>{ state.timestamp }</Text>
</View>
</TouchableOpacity>
{ state.status === 'confirmed' && (
<>
{ state.transform === 'complete' && state.assets && (
@ -175,7 +175,7 @@ export function TopicItem({ item, focused, focus, hosting, remove, update, block
<MatIcons name="cloud-refresh" size={32} color={Colors.divider} />
</View>
)}
</TouchableOpacity>
</View>
{ focused && (
<View style={styles.focused}>
{ state.editable && (

View File

@ -1,13 +1,15 @@
import { useState, useEffect, useContext } from 'react';
import { Linking } from 'react-native';
import { ConversationContext } from 'context/ConversationContext';
import { CardContext } from 'context/CardContext';
import { ProfileContext } from 'context/ProfileContext';
import { AccountContext } from 'context/AccountContext';
import moment from 'moment';
import { useWindowDimensions } from 'react-native';
import { useWindowDimensions, Text } from 'react-native';
import Colors from 'constants/Colors';
import { getCardByGuid } from 'context/cardUtil';
import { decryptTopicSubject } from 'context/sealUtil';
import * as DOMPurify from 'dompurify';
export function useTopicItem(item, hosting, remove, contentKey) {
@ -95,7 +97,7 @@ export function useTopicItem(item, hosting, remove, contentKey) {
try {
sealed = false;
parsed = JSON.parse(data);
message = parsed.text;
message = clickableText(parsed.text);
assets = parsed.assets;
if (parsed.textSize === 'small') {
fontSize = 10;
@ -138,7 +140,7 @@ export function useTopicItem(item, hosting, remove, contentKey) {
if (unsealed) {
sealed = false;
parsed = unsealed.message;
message = parsed?.text;
message = clickableText(parsed?.text);
if (parsed?.textSize === 'small') {
fontSize = 10;
}
@ -194,6 +196,31 @@ export function useTopicItem(item, hosting, remove, contentKey) {
}
};
const clickableText = (text) => {
var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name
'((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
'(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
'(\\#[-a-z\\d_]*)?$','i'); // fragment locator
let clickable = [];
let group = '';
const words = text == null ? '' : text.split(' ');
words.forEach((word, index) => {
if (!!pattern.test(word)) {
clickable.push(<Text key={index}>{ group }</Text>);
group = '';
clickable.push(<Text key={'link-' + index} onPress={() => Linking.openURL(word)} style={{ fontStyle: 'italic' }}>{ word + ' ' }</Text>);
}
else {
group += `${word} `;
}
})
clickable.push(<Text key={words.length}>{ group }</Text>);
return <Text>{ clickable }</Text>;
};
const actions = {
showCarousel: (index) => {
updateState({ carousel: true, carouselIndex: index });