diff --git a/.gitignore b/.gitignore
index 01994883..a2022620 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,15 +1,3 @@
-node_modules/
-.expo/
-.expo-shared/
-npm-debug.*
-*.jks
-*.p8
-*.p12
-*.key
-*.mobileprovision
-*.orig.*
-web-build/
-
# macOS
.DS_Store
@@ -17,46 +5,13 @@ web-build/
coverage/
builds/
-fastlane/id_rsa
-
# @generated expo-cli sync-28e2ab0e9ece60556eaf932abe52d017ec33db50
# The following patterns were generated by expo-cli
# OSX
-#
.DS_Store
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-project.xcworkspace
-
-# Android/IntelliJ
-#
-build/
-.idea
-.gradle
-local.properties
-*.iml
-*.hprof
-
# node.js
-#
node_modules/
npm-debug.log
yarn-error.log
@@ -67,25 +22,12 @@ buck-out/
*.keystore
!debug.keystore
-# fastlane
-#
-# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
-# screenshots whenever they are needed.
-# For more information about the recommended setup visit:
-# https://docs.fastlane.tools/best-practices/source-control/
-
-*/fastlane/report.xml
-*/fastlane/Preview.html
-*/fastlane/screenshots
-
# Bundle artifacts
*.jsbundle
-# CocoaPods
-/ios/Pods/
-
# Expo
.expo/*
+.expo-shared/*
web-build/
# @end expo-cli
\ No newline at end of file
diff --git a/android/.gitignore b/android/.gitignore
new file mode 100644
index 00000000..a972881d
--- /dev/null
+++ b/android/.gitignore
@@ -0,0 +1,6 @@
+build/
+.idea
+.gradle
+local.properties
+*.iml
+*.hprof
\ No newline at end of file
diff --git a/app.config.ts b/app.config.ts
index 795d0306..8956ddcc 100644
--- a/app.config.ts
+++ b/app.config.ts
@@ -7,7 +7,7 @@ export default (): ExpoConfig => ({
slug: 'tooot',
privacy: 'hidden',
sdkVersion: '40.0.0',
- version: '0.1.0',
+ version: '0.8',
platforms: ['ios', 'android'],
orientation: 'portrait',
userInterfaceStyle: 'automatic',
diff --git a/fastlane/.gitignore b/fastlane/.gitignore
new file mode 100644
index 00000000..a6b52973
--- /dev/null
+++ b/fastlane/.gitignore
@@ -0,0 +1,8 @@
+*.key
+*.jks
+*.p8
+*.p12
+
+/report.xml
+Preview.html
+screenshots
\ No newline at end of file
diff --git a/fastlane/Appfile b/fastlane/Appfile
new file mode 100644
index 00000000..d2a7a9de
--- /dev/null
+++ b/fastlane/Appfile
@@ -0,0 +1 @@
+app_identifier "com.xmflsct.app.tooot"
\ No newline at end of file
diff --git a/fastlane/Fastfile b/fastlane/Fastfile
index 2bd74629..0ecfa0e2 100644
--- a/fastlane/Fastfile
+++ b/fastlane/Fastfile
@@ -1,28 +1,12 @@
$ExpoSDK = '40.0.0'
-$ExpoRelease = '40'
+$NativeVersion = '210201' # Update when there is native module change
fastlane_version '2.172.0'
platform :ios do
desc 'Build and deploy'
private_lane :build do |options|
- branch = 'RELEASE-TYPE'.gsub('RELEASE', $ExpoRelease).gsub('TYPE', options[:type])
-
- case options[:type]
- when 'staging', 'production'
- ensure_git_branch(
- branch: branch
- )
- ensure_git_status_clean
- build_number = Time.new.strftime('%y%m%d%k')
- increment_build_number build_number: build_number
- end
-
- match(
- type: options[:type],
- readonly: true
- )
-
+ branch = 'NATIVEVERSION-TYPE'.gsub('NATIVEVERSION', $NativeVersion).gsub('TYPE', options[:type])
set_info_plist_value(
path: './ios/tooot/Supporting/Expo.plist',
key: 'EXUpdatesSDKVersion',
@@ -34,6 +18,25 @@ platform :ios do
value: branch
)
+ case options[:type]
+ when 'staging', 'production'
+ ensure_git_branch(
+ branch: options[:type]
+ )
+ ensure_git_status_clean
+ increment_build_number(
+ build_number: $NativeVersion
+ )
+ app_store_connect_api_key(
+ key_filepath: "appstore.p8"
+ )
+ end
+
+ match(
+ type: options[:type],
+ readonly: true
+ )
+
case options[:type]
when 'development'
build_ios_app(
@@ -41,13 +44,10 @@ platform :ios do
silent: true,
include_bitcode: true,
workspace: './ios/tooot.xcworkspace',
- output_directory: './build/ios',
- output_name: 'development',
export_method: 'development'
)
install_on_device(
- skip_wifi: true,
- ipa: './build/ios/development.ipa'
+ skip_wifi: true
)
when 'staging'
build_ios_app(
@@ -55,8 +55,8 @@ platform :ios do
workspace: './ios/tooot.xcworkspace'
)
upload_to_testflight(
- api_key: '{"key_id": "KEY_ID", "issuer_id": "ISSUER_ID", "key_filepath": "appstore.p8"}'.gsub('KEY_ID', ENV['APP_STORE_KEY_ID']).gsub('ISSUER_ID', ENV['APP_STORE_ISSUER_ID']),
- skip_submission: true
+ skip_submission: true,
+ notify_external_testers: false
)
end
end
diff --git a/fastlane/Matchfile b/fastlane/Matchfile
index 37097a2e..664483e0 100644
--- a/fastlane/Matchfile
+++ b/fastlane/Matchfile
@@ -1,10 +1,3 @@
-git_url(ENV('MATCH_GIT_REPO'))
git_user_email("me@xmflsct.com")
-git_private_key("./id_rsa")
-
+git_private_key("./github.key")
storage_mode("git")
-
-type("development")
-
-app_identifier(["com.xmflsct.app.tooot"])
-username(ENV['APP_STORE_EMAIL'])
diff --git a/fastlane/report.xml b/fastlane/report.xml
deleted file mode 100644
index 595519a7..00000000
--- a/fastlane/report.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/ios/.gitignore b/ios/.gitignore
new file mode 100644
index 00000000..f3d18a11
--- /dev/null
+++ b/ios/.gitignore
@@ -0,0 +1,22 @@
+/Pods/
+/build/
+
+# Xcode
+#
+build/
+*.pbxuser
+!default.pbxuser
+*.mode1v3
+!default.mode1v3
+*.mode2v3
+!default.mode2v3
+*.perspectivev3
+!default.perspectivev3
+xcuserdata
+*.xccheckout
+*.moved-aside
+DerivedData
+*.hmap
+*.ipa
+*.xcuserstate
+project.xcworkspace
\ No newline at end of file
diff --git a/ios/tooot/Supporting/Expo.plist b/ios/tooot/Supporting/Expo.plist
index b54f4423..6ceadb31 100644
--- a/ios/tooot/Supporting/Expo.plist
+++ b/ios/tooot/Supporting/Expo.plist
@@ -9,7 +9,7 @@
EXUpdatesLaunchWaitMs
0
EXUpdatesReleaseChannel
- 40-development
+ 210201-development
EXUpdatesSDKVersion
40.0.0
EXUpdatesURL
diff --git a/src/components/Parse/Emojis.tsx b/src/components/Parse/Emojis.tsx
index 92098d91..a7ecdb34 100644
--- a/src/components/Parse/Emojis.tsx
+++ b/src/components/Parse/Emojis.tsx
@@ -13,61 +13,59 @@ export interface Props {
fontBold?: boolean
}
-const ParseEmojis: React.FC = ({
- content,
- emojis,
- size = 'M',
- fontBold = false
-}) => {
- const { mode, theme } = useTheme()
- const styles = useMemo(() => {
- return StyleSheet.create({
- text: {
- color: theme.primary,
- ...StyleConstants.FontStyle[size],
- ...(fontBold && { fontWeight: StyleConstants.Font.Weight.Bold })
- },
- image: {
- width: StyleConstants.Font.Size[size],
- height: StyleConstants.Font.Size[size],
- transform: [{ translateY: size === 'L' ? -3 : -1 }]
- }
- })
- }, [mode])
+const ParseEmojis = React.memo(
+ ({ content, emojis, size = 'M', fontBold = false }: Props) => {
+ const { mode, theme } = useTheme()
+ const styles = useMemo(() => {
+ return StyleSheet.create({
+ text: {
+ color: theme.primary,
+ ...StyleConstants.FontStyle[size],
+ ...(fontBold && { fontWeight: StyleConstants.Font.Weight.Bold })
+ },
+ image: {
+ width: StyleConstants.Font.Size[size],
+ height: StyleConstants.Font.Size[size],
+ transform: [{ translateY: size === 'L' ? -3 : -1 }]
+ }
+ })
+ }, [mode])
- return (
-
- {emojis ? (
- content
- .split(regexEmoji)
- .filter(f => f)
- .map((str, i) => {
- if (str.match(regexEmoji)) {
- const emojiShortcode = str.split(regexEmoji)[1]
- const emojiIndex = emojis.findIndex(emoji => {
- return emojiShortcode === `:${emoji.shortcode}:`
- })
- return emojiIndex === -1 ? (
- {emojiShortcode}
- ) : (
-
- {/* When emoji starts a paragraph, lineHeight will break */}
- {i === 0 ? : null}
-
-
- )
- } else {
- return {str}
- }
- })
- ) : (
- {content}
- )}
-
- )
-}
+ return (
+
+ {emojis ? (
+ content
+ .split(regexEmoji)
+ .filter(f => f)
+ .map((str, i) => {
+ if (str.match(regexEmoji)) {
+ const emojiShortcode = str.split(regexEmoji)[1]
+ const emojiIndex = emojis.findIndex(emoji => {
+ return emojiShortcode === `:${emoji.shortcode}:`
+ })
+ return emojiIndex === -1 ? (
+ {emojiShortcode}
+ ) : (
+
+ {/* When emoji starts a paragraph, lineHeight will break */}
+ {i === 0 ? : null}
+
+
+ )
+ } else {
+ return {str}
+ }
+ })
+ ) : (
+ {content}
+ )}
+
+ )
+ },
+ (prev, next) => prev.content === next.content
+)
-export default React.memo(ParseEmojis, () => true)
+export default ParseEmojis
diff --git a/src/components/Parse/HTML.tsx b/src/components/Parse/HTML.tsx
index 66ed143e..25fa4c02 100644
--- a/src/components/Parse/HTML.tsx
+++ b/src/components/Parse/HTML.tsx
@@ -30,8 +30,8 @@ const renderNode = ({
theme: any
node: any
index: number
- size: 'M' | 'L'
- navigation: StackNavigationProp
+ size: 'S' | 'M' | 'L'
+ navigation: StackNavigationProp
mentions?: Mastodon.Mention[]
tags?: Mastodon.Tag[]
showFullLink: boolean
@@ -145,7 +145,7 @@ const renderNode = ({
export interface Props {
content: string
- size?: 'M' | 'L'
+ size?: 'S' | 'M' | 'L'
emojis?: Mastodon.Emoji[]
mentions?: Mastodon.Mention[]
tags?: Mastodon.Tag[]
@@ -167,7 +167,7 @@ const ParseHTML: React.FC = ({
disableDetails = false
}) => {
const navigation = useNavigation<
- StackNavigationProp
+ StackNavigationProp
>()
const route = useRoute()
const { theme } = useTheme()
diff --git a/src/components/Timelines/Timeline.tsx b/src/components/Timelines/Timeline.tsx
index de194049..a96dcad8 100644
--- a/src/components/Timelines/Timeline.tsx
+++ b/src/components/Timelines/Timeline.tsx
@@ -82,11 +82,10 @@ const Timeline: React.FC = ({
const navigation = useNavigation()
useEffect(() => {
const unsubscribe = navigation.addListener('focus', props => {
- if (props.target && props.target.includes('Screen-Notifications-Root')) {
+ if (props.target && props.target.includes('Tab-Notifications-Root')) {
if (flattenData.length) {
dispatch(
localUpdateNotification({
- unread: false,
latestTime: (flattenData[0] as Mastodon.Notification).created_at
})
)
diff --git a/src/i18n/en/screens/meSettings.ts b/src/i18n/en/screens/meSettings.ts
index 19412ec0..d0460075 100644
--- a/src/i18n/en/screens/meSettings.ts
+++ b/src/i18n/en/screens/meSettings.ts
@@ -47,6 +47,6 @@ export default {
heading: 'Help us improve',
description: 'Collecting only non-user relative usage'
},
- version: 'Version v{{version}}'
+ version: 'Version v{{version}} ({{releaseChannel}})'
}
}
diff --git a/src/i18n/zh-Hans/screens/meSettings.ts b/src/i18n/zh-Hans/screens/meSettings.ts
index 4cc479e0..be3854f5 100644
--- a/src/i18n/zh-Hans/screens/meSettings.ts
+++ b/src/i18n/zh-Hans/screens/meSettings.ts
@@ -47,6 +47,6 @@ export default {
heading: '帮助我们改进',
description: '收集不与用户相关联的使用信息'
},
- version: '版本 v{{version}}'
+ version: '版本 v{{version}} ({{releaseChannel}})'
}
}
diff --git a/src/screens/Tabs.tsx b/src/screens/Tabs.tsx
index 1a705c6a..262aa83c 100644
--- a/src/screens/Tabs.tsx
+++ b/src/screens/Tabs.tsx
@@ -90,7 +90,7 @@ const ScreenTabs: React.FC = ({ navigation }) => {
}),
[localActiveIndex, localAccount]
)
- const tabNavigatorTabBarOptions = useMemo(
+ const tabBarOptions = useMemo(
() => ({
activeTintColor: theme.primary,
inactiveTintColor:
@@ -100,7 +100,7 @@ const ScreenTabs: React.FC = ({ navigation }) => {
}),
[theme, localActiveIndex]
)
- const tabScreenLocalListeners = useCallback(
+ const localListeners = useCallback(
() => ({
tabPress: (e: any) => {
if (!(localActiveIndex !== null)) {
@@ -110,7 +110,7 @@ const ScreenTabs: React.FC = ({ navigation }) => {
}),
[localActiveIndex]
)
- const tabScreenComposeListeners = useMemo(
+ const composeListeners = useMemo(
() => ({
tabPress: (e: any) => {
e.preventDefault()
@@ -122,8 +122,8 @@ const ScreenTabs: React.FC = ({ navigation }) => {
}),
[localActiveIndex]
)
- const tabScreenComposeComponent = useCallback(() => null, [])
- const tabScreenNotificationsListeners = useCallback(
+ const composeComponent = useCallback(() => null, [])
+ const notificationsListeners = useCallback(
() => ({
tabPress: (e: any) => {
if (!(localActiveIndex !== null)) {
@@ -144,66 +144,67 @@ const ScreenTabs: React.FC = ({ navigation }) => {
}
})
const prevNotification = useSelector(getLocalNotification)
- useEffect(() => {
- if (queryNotification.data?.pages) {
- const flattenData = queryNotification.data.pages.flatMap(d => [...d])
- const latestNotificationTime = flattenData.length
- ? (flattenData[0] as Mastodon.Notification).created_at
- : undefined
+ const notificationsOptions = useMemo(() => {
+ const badge = {
+ show: {
+ tabBarBadge: '',
+ tabBarBadgeStyle: {
+ transform: [{ scale: 0.5 }],
+ backgroundColor: theme.red
+ }
+ },
+ hide: {
+ tabBarBadgeStyle: {
+ transform: [{ scale: 0.5 }],
+ backgroundColor: theme.red
+ }
+ }
+ }
+ const flattenData = queryNotification.data?.pages.flatMap(d => [...d])
+ const latestNotificationTime = flattenData?.length
+ ? (flattenData[0] as Mastodon.Notification).created_at
+ : undefined
- if (!prevNotification || !prevNotification.latestTime) {
- dispatch(localUpdateNotification({ unread: false }))
- } else if (
+ if (prevNotification?.latestTime) {
+ if (
latestNotificationTime &&
new Date(prevNotification.latestTime) < new Date(latestNotificationTime)
) {
- dispatch(
- localUpdateNotification({
- unread: true,
- latestTime: latestNotificationTime
- })
- )
+ return badge.show
+ } else {
+ return badge.hide
+ }
+ } else {
+ if (latestNotificationTime) {
+ return badge.show
+ } else {
+ return badge.hide
}
}
- }, [queryNotification.data?.pages])
+ }, [prevNotification, queryNotification.data?.pages])
return (
diff --git a/src/screens/Tabs/Me/Settings/Analytics.tsx b/src/screens/Tabs/Me/Settings/Analytics.tsx
index 310a00a7..879cee27 100644
--- a/src/screens/Tabs/Me/Settings/Analytics.tsx
+++ b/src/screens/Tabs/Me/Settings/Analytics.tsx
@@ -29,7 +29,10 @@ const SettingsAnalytics: React.FC = () => {
}
/>
- {t('content.version', { version: Constants.manifest.version })}
+ {t('content.version', {
+ version: Constants.manifest.version,
+ releaseChannel: Constants.manifest.releaseChannel || 'dev'
+ })}
)
diff --git a/src/screens/Tabs/Shared/Account/Information.tsx b/src/screens/Tabs/Shared/Account/Information.tsx
index b5e5d1b9..c946c24b 100644
--- a/src/screens/Tabs/Shared/Account/Information.tsx
+++ b/src/screens/Tabs/Shared/Account/Information.tsx
@@ -75,7 +75,7 @@ const AccountInformation: React.FC = ({ account, myInfo = false }) => {
const styles = StyleSheet.create({
base: {
- marginTop: -StyleConstants.Spacing.Global.PagePadding * 3,
+ marginTop: -StyleConstants.Avatar.L / 2,
padding: StyleConstants.Spacing.Global.PagePadding
},
avatarAndActions: {
diff --git a/src/screens/Tabs/Shared/Account/Information/Fields.tsx b/src/screens/Tabs/Shared/Account/Information/Fields.tsx
index 1888ebc5..4bd6a6e0 100644
--- a/src/screens/Tabs/Shared/Account/Information/Fields.tsx
+++ b/src/screens/Tabs/Shared/Account/Information/Fields.tsx
@@ -25,7 +25,7 @@ const AccountInformationFields = React.memo(
>
>
) => {
- state.local.instances[state.local.activeIndex!].notification = {
- ...state.local.instances[state.local.activeIndex!].notification,
- ...action.payload
- }
+ state.local.instances[state.local.activeIndex!].notification =
+ action.payload
},
remoteUpdate: (
state,