├── .watchmanconfig
├── .gitattributes
├── .babelrc
├── .eslintignore
├── app.json
├── libs
├── react-native-android-bottom-sheet
│ ├── README.md
│ ├── index.android.js
│ ├── src
│ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ └── java
│ │ │ └── com
│ │ │ └── terrysahaidak
│ │ │ └── bottomsheet
│ │ │ ├── AndroidBottomSheetPackage.java
│ │ │ └── AndroidBottomSheet.java
│ ├── package.json
│ ├── build.gradle
│ └── index.ios.js
└── react-native-gitter-faye
│ ├── index.android.js
│ ├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── com
│ │ └── terrysahaidak
│ │ └── faye
│ │ └── FayeGitterPackage.java
│ ├── package.json
│ ├── index.ios.js
│ ├── README.md
│ └── build.gradle
├── ios
├── Pods
│ ├── Headers
│ │ ├── Public
│ │ │ ├── SocketRocket
│ │ │ │ ├── SRWebSocket.h
│ │ │ │ └── SocketRocket.h
│ │ │ └── MZFayeClient
│ │ │ │ ├── MZFayeClient.h
│ │ │ │ └── MZFayeMessage.h
│ │ └── Private
│ │ │ ├── MZFayeClient
│ │ │ ├── MZFayeClient.h
│ │ │ └── MZFayeMessage.h
│ │ │ └── SocketRocket
│ │ │ ├── SRWebSocket.h
│ │ │ └── SocketRocket.h
│ ├── Target Support Files
│ │ ├── MZFayeClient
│ │ │ ├── MZFayeClient-dummy.m
│ │ │ ├── MZFayeClient-prefix.pch
│ │ │ └── MZFayeClient.xcconfig
│ │ ├── SocketRocket
│ │ │ ├── SocketRocket-dummy.m
│ │ │ ├── SocketRocket-prefix.pch
│ │ │ └── SocketRocket.xcconfig
│ │ └── Pods-GitterMobile
│ │ │ ├── Pods-GitterMobile-dummy.m
│ │ │ ├── Pods-GitterMobile.debug.xcconfig
│ │ │ ├── Pods-GitterMobile.release.xcconfig
│ │ │ └── Pods-GitterMobile-acknowledgements.markdown
│ ├── SocketRocket
│ │ ├── LICENSE
│ │ └── SocketRocket
│ │ │ └── SocketRocket.h
│ ├── Manifest.lock
│ ├── Local Podspecs
│ │ ├── MZFayeClient.podspec.json
│ │ └── RNVectorIcons.podspec.json
│ └── MZFayeClient
│ │ ├── LICENSE
│ │ └── MZFayeClient
│ │ ├── MZFayeMessage.h
│ │ └── MZFayeMessage.m
├── gittermobile
│ ├── Images.xcassets
│ │ └── AppIcon.appiconset
│ │ │ ├── Icon-App-20x20@1x.png
│ │ │ ├── Icon-App-20x20@2x.png
│ │ │ ├── Icon-App-20x20@3x.png
│ │ │ ├── Icon-App-29x29@1x.png
│ │ │ ├── Icon-App-29x29@2x.png
│ │ │ ├── Icon-App-29x29@3x.png
│ │ │ ├── Icon-App-40x40@1x.png
│ │ │ ├── Icon-App-40x40@2x.png
│ │ │ ├── Icon-App-40x40@3x.png
│ │ │ ├── Icon-App-57x57@1x.png
│ │ │ ├── Icon-App-60x60@1x.png
│ │ │ ├── Icon-App-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.png
│ │ │ ├── Icon-App-76x76@1x.png
│ │ │ ├── Icon-App-76x76@2x.png
│ │ │ ├── Icon-App-76x76@3x.png
│ │ │ └── Icon-App-83.5x83.5@2x.png
│ ├── AppDelegate.h
│ ├── main.m
│ ├── AppDelegate.m
│ └── Info.plist
├── Podfile
├── gittermobile.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── gittermobile.xcscmblueprint
├── GitterMobile
│ └── FayeManager.h
├── Podfile.lock
├── gittermobileTests
│ ├── Info.plist
│ └── gittermobileTests.m
├── gittermobile-tvOSTests
│ └── Info.plist
└── gittermobile-tvOS
│ └── Info.plist
├── screenshots
├── home.png
├── room.png
├── drawer.png
├── message.png
├── user_screen.png
├── search_rooms.png
└── room_info_screen.png
├── index.ios.js
├── index.android.js
├── app
├── images
│ └── gitter-background.jpg
├── components
│ ├── Link
│ │ ├── styles.js
│ │ └── index.js
│ ├── ScrollToTop
│ │ ├── styles.js
│ │ └── index.js
│ ├── Button
│ │ ├── styles.js
│ │ ├── index.ios.js
│ │ └── index.android.js
│ ├── LoadingOverlay
│ │ ├── styles.js
│ │ └── index.js
│ ├── FailedToLoad
│ │ ├── styles.js
│ │ └── index.js
│ ├── Heading
│ │ └── index.js
│ ├── Divider
│ │ └── index.js
│ ├── Avatar
│ │ └── index.js
│ ├── ParsedText
│ │ ├── styles.js
│ │ └── index.js
│ ├── CustomSearch
│ │ ├── styles.js
│ │ └── index.js
│ ├── LoadingMoreSnack
│ │ ├── styles.js
│ │ └── index.js
│ ├── UnreadBadge
│ │ ├── styles.js
│ │ └── index.js
│ ├── Loading
│ │ └── index.js
│ ├── Emoji
│ │ └── index.js
│ └── Toolbar
│ │ └── styles.js
├── utils
│ ├── channelNameAndOwner.js
│ ├── links.js
│ ├── storage.js
│ ├── normalize.js
│ ├── hexToRgb.js
│ ├── iconsMap.js
│ └── createMessage.js
├── screens
│ ├── RoomUsers
│ │ ├── RoomUsersList
│ │ │ ├── styles.js
│ │ │ └── index.js
│ │ ├── RoomUsersSearchResult
│ │ │ ├── styles.js
│ │ │ └── index.js
│ │ ├── styles.js
│ │ └── RoomUserItem
│ │ │ ├── styles.js
│ │ │ └── index.js
│ ├── RoomSettings
│ │ ├── Section
│ │ │ ├── styles.js
│ │ │ └── index.js
│ │ └── styles.js
│ ├── Drawer
│ │ ├── styles.js
│ │ ├── SearchField
│ │ │ ├── styles.js
│ │ │ └── index.js
│ │ ├── ChannelListSection
│ │ │ ├── styles.js
│ │ │ └── index.js
│ │ ├── ChannelListItem
│ │ │ ├── styles.js
│ │ │ └── index.js
│ │ └── DrawerUserInfo
│ │ │ ├── styles.js
│ │ │ └── index.js
│ ├── ImageLightbox
│ │ ├── styles.js
│ │ └── index.js
│ ├── RoomInfo
│ │ ├── styles.js
│ │ ├── RoomInfo
│ │ │ ├── styles.js
│ │ │ └── index.js
│ │ ├── Activity
│ │ │ ├── styles.js
│ │ │ └── index.js
│ │ ├── RepoInfo
│ │ │ └── styles.js
│ │ ├── RoomUsers
│ │ │ ├── styles.js
│ │ │ └── index.js
│ │ └── UserInfo
│ │ │ └── index.js
│ ├── Search
│ │ ├── SearchRoomsTab
│ │ │ ├── styles.js
│ │ │ └── index.js
│ │ ├── styles.js
│ │ ├── SearchUserItem
│ │ │ └── index.js
│ │ ├── SearchUsersTab
│ │ │ └── index.js
│ │ └── SearchRoomItem
│ │ │ └── index.js
│ ├── Room
│ │ ├── MessagesList
│ │ │ └── styles.js
│ │ ├── StatusMessage
│ │ │ ├── renderEmoji.js
│ │ │ ├── styles.js
│ │ │ └── index.js
│ │ ├── styles.js
│ │ ├── HistoryBegin
│ │ │ ├── index.js
│ │ │ └── styles.js
│ │ ├── JoinRoomField
│ │ │ ├── index.js
│ │ │ └── styles.js
│ │ ├── Message
│ │ │ └── styles.js
│ │ └── SendMessageField
│ │ │ └── styles.js
│ ├── Settings
│ │ ├── Group
│ │ │ ├── styles.js
│ │ │ └── index.js
│ │ ├── TextItem
│ │ │ ├── styles.js
│ │ │ └── index.js
│ │ └── styles.js
│ ├── RoomUserAdd
│ │ ├── SearchResult
│ │ │ ├── styles.js
│ │ │ └── index.js
│ │ ├── styles.js
│ │ └── RoomUserItem
│ │ │ ├── styles.js
│ │ │ └── index.js
│ ├── Message
│ │ ├── styles.js
│ │ ├── ReadBy
│ │ │ ├── styles.js
│ │ │ └── index.js
│ │ └── Message
│ │ │ ├── styles.js
│ │ │ └── index.js
│ ├── Launch
│ │ ├── styles.js
│ │ └── index.js
│ ├── Home
│ │ ├── HomeRoomItem
│ │ │ ├── styles.js
│ │ │ └── index.js
│ │ ├── styles.js
│ │ └── HomeRoomItemMy
│ │ │ ├── styles.js
│ │ │ └── index.js
│ ├── LoginByWebView
│ │ ├── styles.js
│ │ └── index.js
│ ├── SearchMessages
│ │ ├── styles.js
│ │ └── MessagesList
│ │ │ └── index.js
│ ├── User
│ │ ├── styles.js
│ │ ├── UserInfo
│ │ │ └── styles.js
│ │ └── UserTop
│ │ │ ├── styles.js
│ │ │ └── index.js
│ ├── NoInternet
│ │ ├── styles.js
│ │ └── index.js
│ ├── Login
│ │ ├── styles.js
│ │ └── index.js
│ ├── LoginByToken
│ │ └── styles.js
│ └── index.js
├── styles
│ └── common
│ │ ├── BackgroundImage.js
│ │ └── navigationStyles.js
├── index.js
├── api
│ └── github.js
├── modules
│ ├── readBy.js
│ ├── activity.js
│ ├── settings.js
│ ├── index.js
│ ├── viewer.js
│ ├── ui.js
│ ├── roomInfo.js
│ └── navigation.js
├── configureStore.js
└── constants.js
├── android
├── app
│ ├── src
│ │ └── main
│ │ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── strings.xml
│ │ │ │ └── styles.xml
│ │ │ ├── mipmap-hdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ └── mipmap-xxxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── assets
│ │ │ └── fonts
│ │ │ │ ├── Entypo.ttf
│ │ │ │ ├── Zocial.ttf
│ │ │ │ ├── EvilIcons.ttf
│ │ │ │ ├── Ionicons.ttf
│ │ │ │ ├── Octicons.ttf
│ │ │ │ ├── FontAwesome.ttf
│ │ │ │ ├── Foundation.ttf
│ │ │ │ ├── MaterialIcons.ttf
│ │ │ │ ├── SimpleLineIcons.ttf
│ │ │ │ └── MaterialCommunityIcons.ttf
│ │ │ ├── java
│ │ │ └── com
│ │ │ │ └── gittermobile
│ │ │ │ ├── MainActivity.java
│ │ │ │ └── MainApplication.java
│ │ │ └── AndroidManifest.xml
│ └── BUCK
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── keystores
│ ├── debug.keystore.properties
│ └── BUCK
├── build.gradle
├── gradle.properties
└── settings.gradle
├── .buckconfig
├── .editorconfig
├── __tests__
├── index.ios.js
└── index.android.js
├── .eslintrc
├── .gitignore
├── .flowconfig
├── LICENSE
└── package.json
/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.pbxproj -text
2 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["react-native"]
3 | }
4 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | bundle/
3 | bundle.js
4 | vendor.js
5 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "GitterMobile",
3 | "displayName": "GitterMobile"
4 | }
--------------------------------------------------------------------------------
/libs/react-native-android-bottom-sheet/README.md:
--------------------------------------------------------------------------------
1 | ## react-native-android-bottom-sheet
2 |
--------------------------------------------------------------------------------
/ios/Pods/Headers/Public/SocketRocket/SRWebSocket.h:
--------------------------------------------------------------------------------
1 | ../../../SocketRocket/SocketRocket/SRWebSocket.h
--------------------------------------------------------------------------------
/screenshots/home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/screenshots/home.png
--------------------------------------------------------------------------------
/screenshots/room.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/screenshots/room.png
--------------------------------------------------------------------------------
/index.ios.js:
--------------------------------------------------------------------------------
1 | import GitterMobile from './app/index.js'
2 | global.CURRENT_VERSION = 'v0.6.0-beta-2'
3 |
--------------------------------------------------------------------------------
/ios/Pods/Headers/Private/MZFayeClient/MZFayeClient.h:
--------------------------------------------------------------------------------
1 | ../../../MZFayeClient/MZFayeClient/MZFayeClient.h
--------------------------------------------------------------------------------
/ios/Pods/Headers/Private/MZFayeClient/MZFayeMessage.h:
--------------------------------------------------------------------------------
1 | ../../../MZFayeClient/MZFayeClient/MZFayeMessage.h
--------------------------------------------------------------------------------
/ios/Pods/Headers/Private/SocketRocket/SRWebSocket.h:
--------------------------------------------------------------------------------
1 | ../../../SocketRocket/SocketRocket/SRWebSocket.h
--------------------------------------------------------------------------------
/ios/Pods/Headers/Private/SocketRocket/SocketRocket.h:
--------------------------------------------------------------------------------
1 | ../../../SocketRocket/SocketRocket/SocketRocket.h
--------------------------------------------------------------------------------
/ios/Pods/Headers/Public/MZFayeClient/MZFayeClient.h:
--------------------------------------------------------------------------------
1 | ../../../MZFayeClient/MZFayeClient/MZFayeClient.h
--------------------------------------------------------------------------------
/ios/Pods/Headers/Public/MZFayeClient/MZFayeMessage.h:
--------------------------------------------------------------------------------
1 | ../../../MZFayeClient/MZFayeClient/MZFayeMessage.h
--------------------------------------------------------------------------------
/ios/Pods/Headers/Public/SocketRocket/SocketRocket.h:
--------------------------------------------------------------------------------
1 | ../../../SocketRocket/SocketRocket/SocketRocket.h
--------------------------------------------------------------------------------
/screenshots/drawer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/screenshots/drawer.png
--------------------------------------------------------------------------------
/index.android.js:
--------------------------------------------------------------------------------
1 | import GitterMobile from './app/index.js'
2 | global.CURRENT_VERSION = 'v0.6.0-beta-2'
3 |
--------------------------------------------------------------------------------
/screenshots/message.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/screenshots/message.png
--------------------------------------------------------------------------------
/screenshots/user_screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/screenshots/user_screen.png
--------------------------------------------------------------------------------
/screenshots/search_rooms.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/screenshots/search_rooms.png
--------------------------------------------------------------------------------
/app/images/gitter-background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/app/images/gitter-background.jpg
--------------------------------------------------------------------------------
/screenshots/room_info_screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/screenshots/room_info_screen.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | GitterMobile
3 |
4 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/libs/react-native-gitter-faye/index.android.js:
--------------------------------------------------------------------------------
1 | import { NativeModules } from 'react-native'
2 | module.exports = NativeModules.FayeGitter;
3 |
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Entypo.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/android/app/src/main/assets/fonts/Entypo.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Zocial.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/android/app/src/main/assets/fonts/Zocial.ttf
--------------------------------------------------------------------------------
/.buckconfig:
--------------------------------------------------------------------------------
1 |
2 | [android]
3 | target = Google Inc.:Google APIs:23
4 |
5 | [maven_repositories]
6 | central = https://repo1.maven.org/maven2
7 |
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/EvilIcons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/android/app/src/main/assets/fonts/EvilIcons.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Ionicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/android/app/src/main/assets/fonts/Ionicons.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Octicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/android/app/src/main/assets/fonts/Octicons.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/FontAwesome.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/android/app/src/main/assets/fonts/FontAwesome.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Foundation.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/android/app/src/main/assets/fonts/Foundation.ttf
--------------------------------------------------------------------------------
/libs/react-native-android-bottom-sheet/index.android.js:
--------------------------------------------------------------------------------
1 | import { NativeModules } from 'react-native'
2 | export default NativeModules.AndroidBottomSheet
3 |
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/MaterialIcons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/android/app/src/main/assets/fonts/MaterialIcons.ttf
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/components/Link/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 |
5 | })
6 |
7 | export default styles
8 |
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/SimpleLineIcons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/android/app/src/main/assets/fonts/SimpleLineIcons.ttf
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/keystores/debug.keystore.properties:
--------------------------------------------------------------------------------
1 | key.store=debug.keystore
2 | key.alias=androiddebugkey
3 | key.store.password=android
4 | key.alias.password=android
5 |
--------------------------------------------------------------------------------
/app/utils/channelNameAndOwner.js:
--------------------------------------------------------------------------------
1 | export default function channelNameAndOwner(str) {
2 | const [owner, name] = str.split(/\/(.*)/)
3 | return {owner, name}
4 | }
5 |
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/MaterialCommunityIcons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/android/app/src/main/assets/fonts/MaterialCommunityIcons.ttf
--------------------------------------------------------------------------------
/android/keystores/BUCK:
--------------------------------------------------------------------------------
1 | keystore(
2 | name = "debug",
3 | properties = "debug.keystore.properties",
4 | store = "debug.keystore",
5 | visibility = [
6 | "PUBLIC",
7 | ],
8 | )
9 |
--------------------------------------------------------------------------------
/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png
--------------------------------------------------------------------------------
/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@1x.png
--------------------------------------------------------------------------------
/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@3x.png
--------------------------------------------------------------------------------
/ios/Pods/Target Support Files/MZFayeClient/MZFayeClient-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_MZFayeClient : NSObject
3 | @end
4 | @implementation PodsDummy_MZFayeClient
5 | @end
6 |
--------------------------------------------------------------------------------
/ios/Pods/Target Support Files/SocketRocket/SocketRocket-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_SocketRocket : NSObject
3 | @end
4 | @implementation PodsDummy_SocketRocket
5 | @end
6 |
--------------------------------------------------------------------------------
/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apiko-dev/GitterMobile/HEAD/ios/gittermobile/Images.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/app/screens/RoomUsers/RoomUsersList/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 | container: {
5 | flex: 1
6 | }
7 | })
8 |
9 | export default styles
10 |
--------------------------------------------------------------------------------
/app/screens/RoomSettings/Section/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 | container: {
5 | // padding: 16
6 | },
7 | })
8 |
9 | export default styles
10 |
--------------------------------------------------------------------------------
/ios/Pods/Target Support Files/Pods-GitterMobile/Pods-GitterMobile-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Pods_GitterMobile : NSObject
3 | @end
4 | @implementation PodsDummy_Pods_GitterMobile
5 | @end
6 |
--------------------------------------------------------------------------------
/libs/react-native-gitter-faye/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/app/screens/Drawer/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 | container: {
5 | flex: 1,
6 | backgroundColor: 'white'
7 | }
8 | })
9 |
10 | export default styles
11 |
--------------------------------------------------------------------------------
/app/screens/ImageLightbox/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 | container: {
5 | flex: 1,
6 | backgroundColor: '#000'
7 | }
8 | })
9 |
10 | export default styles
11 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | insert_final_newline = true
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | trim_trailing_whitespace = true
9 |
10 | [*.md]
11 | trim_trailing_whitespace = false
12 |
--------------------------------------------------------------------------------
/libs/react-native-android-bottom-sheet/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/app/styles/common/BackgroundImage.js:
--------------------------------------------------------------------------------
1 | import {Dimensions} from 'react-native'
2 |
3 | const {width, height} = Dimensions.get('window')
4 |
5 | const styles = {
6 | flex: 1,
7 | width,
8 | height
9 | }
10 |
11 | export default styles
12 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
6 |
--------------------------------------------------------------------------------
/app/index.js:
--------------------------------------------------------------------------------
1 | import {Provider} from 'react-redux'
2 | import configureStore from './configureStore'
3 |
4 | import Application from './screens'
5 |
6 | const store = configureStore()
7 | export const rootNavigator = new Application(store, Provider)
8 |
9 | rootNavigator.run()
10 |
--------------------------------------------------------------------------------
/app/utils/links.js:
--------------------------------------------------------------------------------
1 | export const createGhAvatarLink = (name, size = 40) => {
2 | return `https://avatars.githubusercontent.com/${name}?v=3&size=${size}`
3 | }
4 |
5 | export function quoteLink(time, url, id) {
6 | return `:point_up: [${time}](https://gitter.im${url}?at=${id})`
7 | }
8 |
--------------------------------------------------------------------------------
/app/api/github.js:
--------------------------------------------------------------------------------
1 | const BASE_API_URL = 'https://api.github.com'
2 |
3 | export function checkNewReleases() {
4 | return request('repos/terrysahaidak/GitterMobile/releases')
5 | }
6 |
7 | function request(endpoint) {
8 | return fetch(`${BASE_API_URL}/${endpoint}`).then(raw => raw.json())
9 | }
10 |
--------------------------------------------------------------------------------
/app/screens/Drawer/SearchField/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 | container: {
5 | marginVertical: 12,
6 | marginHorizontal: 16
7 | },
8 | text: {
9 | color: '#E0E0E0'
10 | }
11 | })
12 |
13 | export default styles
14 |
--------------------------------------------------------------------------------
/app/components/ScrollToTop/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 | container: {
5 | // flex: 1,
6 | position: 'absolute',
7 | alignItems: 'center',
8 | justifyContent: 'center'
9 | }
10 | })
11 |
12 | export default styles
13 |
--------------------------------------------------------------------------------
/ios/Pods/Target Support Files/MZFayeClient/MZFayeClient-prefix.pch:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
--------------------------------------------------------------------------------
/ios/Pods/Target Support Files/SocketRocket/SocketRocket-prefix.pch:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
--------------------------------------------------------------------------------
/libs/react-native-gitter-faye/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-faye",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.android.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC"
11 | }
12 |
--------------------------------------------------------------------------------
/app/screens/RoomInfo/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 | container: {
5 | flex: 1,
6 | backgroundColor: 'white'
7 | },
8 | tabs: {
9 |
10 | },
11 | tabsContainer: {
12 | flex: 1
13 | }
14 | })
15 |
16 | export default styles
17 |
--------------------------------------------------------------------------------
/app/screens/Search/SearchRoomsTab/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 | container: {
5 | flex: 1
6 | },
7 | tabText: {
8 | textAlign: 'center',
9 | fontSize: 24,
10 | marginTop: 50
11 | }
12 | })
13 |
14 | export default styles
15 |
--------------------------------------------------------------------------------
/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | # platform :ios, '8.0'
3 | # Uncomment this line if you're using Swift
4 | # use_frameworks!
5 |
6 | target 'GitterMobile' do
7 | pod 'MZFayeClient', :git => 'https://github.com/m1entus/MZFayeClient.git', :commit => '6a88a1'
8 | end
9 |
--------------------------------------------------------------------------------
/app/screens/Room/MessagesList/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 | rootStyle: {
5 | flex: 1
6 | },
7 | verticallyInverted: {
8 | flex: 1,
9 | transform: [
10 | { scaleY: -1 }
11 | ]
12 | }
13 | })
14 |
15 | export default styles
16 |
--------------------------------------------------------------------------------
/ios/gittermobile.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/screens/Room/StatusMessage/renderEmoji.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Emoji from '../../../components/Emoji'
3 |
4 | const renderEmoji = (matchingString, matches) => {
5 | const name = matches[0].replace(/:/, '')
6 | return (
7 |
8 | )
9 | }
10 |
11 | export default renderEmoji
12 |
--------------------------------------------------------------------------------
/libs/react-native-android-bottom-sheet/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-android-bottom-sheet",
3 | "version": "0.0.1",
4 | "description": "",
5 | "main": "index.android.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC"
11 | }
12 |
--------------------------------------------------------------------------------
/app/components/Button/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 | button: {
5 | height: 35,
6 | borderRadius: 2,
7 | flexDirection: 'row',
8 | justifyContent: 'center',
9 | alignItems: 'center',
10 | elevation: 4
11 | }
12 | })
13 |
14 | export default styles
15 |
--------------------------------------------------------------------------------
/app/utils/storage.js:
--------------------------------------------------------------------------------
1 | import {AsyncStorage} from 'react-native'
2 |
3 | export function getItem(key) {
4 | return AsyncStorage.getItem(key)
5 | }
6 |
7 | export function setItem(key, value) {
8 | return AsyncStorage.setItem(key, value)
9 | }
10 |
11 | export function removeItem(key) {
12 | return AsyncStorage.removeItem(key)
13 | }
14 |
--------------------------------------------------------------------------------
/__tests__/index.ios.js:
--------------------------------------------------------------------------------
1 | import 'react-native';
2 | import React from 'react'
3 | import Index from '../index.ios.js';
4 |
5 | // Note: test renderer must be required after react-native.
6 | import renderer from 'react-test-renderer';
7 |
8 | it('renders correctly', () => {
9 | const tree = renderer.create(
10 |
11 | );
12 | });
13 |
--------------------------------------------------------------------------------
/__tests__/index.android.js:
--------------------------------------------------------------------------------
1 | import 'react-native';
2 | import React from 'react'
3 | import Index from '../index.android.js';
4 |
5 | // Note: test renderer must be required after react-native.
6 | import renderer from 'react-test-renderer';
7 |
8 | it('renders correctly', () => {
9 | const tree = renderer.create(
10 |
11 | );
12 | });
13 |
--------------------------------------------------------------------------------
/app/screens/Settings/Group/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 | container: {
5 | // flex: 1,
6 | backgroundColor: 'white',
7 | elevation: 4,
8 | marginBottom: 4
9 | },
10 | headingContainer: {
11 | paddingVertical: 8
12 | },
13 | items: {
14 |
15 | }
16 | })
17 |
18 | export default styles
19 |
--------------------------------------------------------------------------------
/app/utils/normalize.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Returns normalized data - ids and entities
3 | * @param response - json response
4 | */
5 | export default function normalize(response) {
6 | const result = {
7 | ids: [],
8 | entities: {}
9 | }
10 |
11 | response.map(item => {
12 | result.ids.push(item.id)
13 | result.entities[[item.id]] = item
14 | })
15 |
16 | return result
17 | }
18 |
--------------------------------------------------------------------------------
/ios/GitterMobile/FayeManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // FayeManager.h
3 | // gittermobile
4 | //
5 | // Created by Roman Temchenko on 5/4/16.
6 | // Copyright © 2016 Facebook. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import
12 |
13 | @interface FayeManager : RCTEventEmitter
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/app/screens/RoomUserAdd/SearchResult/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 | container: {
5 | flex: 1
6 | },
7 | loading: {
8 | height: 150
9 | },
10 | noResultContainer: {
11 | paddingTop: 50
12 | },
13 | noResult: {
14 | textAlign: 'center',
15 | fontSize: 24
16 | }
17 | })
18 |
19 | export default styles
20 |
--------------------------------------------------------------------------------
/app/screens/RoomUsers/RoomUsersSearchResult/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 | container: {
5 | flex: 1
6 | },
7 | loading: {
8 | height: 150
9 | },
10 | noResultContainer: {
11 | paddingTop: 50
12 | },
13 | noResult: {
14 | textAlign: 'center',
15 | fontSize: 24
16 | }
17 | })
18 |
19 | export default styles
20 |
--------------------------------------------------------------------------------
/app/components/LoadingOverlay/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 | loadingContainer: {
5 | flex: 1,
6 | position: 'absolute',
7 | bottom: 0,
8 | top: 0,
9 | left: 0,
10 | right: 0,
11 | backgroundColor: 'rgba(0,0,0,0.7)',
12 | justifyContent: 'center',
13 | alignItems: 'center'
14 | }
15 | })
16 |
17 | export default styles
18 |
--------------------------------------------------------------------------------
/app/screens/Room/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 | import {THEMES} from '../../constants'
3 | const {colors} = THEMES.gitterDefault
4 |
5 | const styles = StyleSheet.create({
6 | container: {
7 | flex: 1,
8 | backgroundColor: 'white'
9 | },
10 | toolbar: {
11 | backgroundColor: colors.raspberry,
12 | height: 56,
13 | elevation: 4
14 | }
15 | })
16 |
17 | export default styles
18 |
--------------------------------------------------------------------------------
/libs/react-native-gitter-faye/index.ios.js:
--------------------------------------------------------------------------------
1 | import { NativeModules } from 'react-native'
2 |
3 | const noop = () => {}
4 | const trueNoop = Promise.resolve(true)
5 |
6 | const FayeGitter = {
7 | setAccessToken: noop,
8 | create: noop,
9 | logger: noop,
10 | connect: trueNoop,
11 | checkConnectionStatus: trueNoop,
12 | subscribe: noop,
13 | unsubscribe: noop
14 | }
15 |
16 | export default NativeModules.FayeManager
17 |
--------------------------------------------------------------------------------
/app/screens/Settings/TextItem/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 | container: {
5 | flex: 1,
6 | padding: 16,
7 | justifyContent: 'center'
8 | },
9 | text: {
10 | fontSize: 18,
11 | fontWeight: 'bold',
12 | // color: 'black'
13 | },
14 | button: {
15 | elevation: 0,
16 | height: 56
17 | }
18 | })
19 |
20 | export default styles
21 |
--------------------------------------------------------------------------------
/app/styles/common/navigationStyles.js:
--------------------------------------------------------------------------------
1 | import {THEMES} from '../../constants'
2 | const {colors} = THEMES.gitterDefault
3 |
4 | const navigationStyles = {
5 | navBarBackgroundColor: colors.raspberry,
6 | navBarButtonColor: 'white',
7 | navBarTextColor: 'white',
8 | topBarElevationShadowEnabled: true,
9 | statusBarColor: colors.darkRed,
10 | statusBarTextColorScheme: 'dark'
11 | }
12 |
13 | export default navigationStyles
14 |
--------------------------------------------------------------------------------
/app/screens/RoomInfo/RoomInfo/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 | container: {
5 | flex: 1
6 | },
7 | header: {
8 | flexDirection: 'row',
9 | paddingHorizontal: 16,
10 | paddingVertical: 24
11 | },
12 | headerTextContainer: {
13 | marginLeft: 16,
14 | flexDirection: 'column'
15 | },
16 | name: {
17 | }
18 | })
19 |
20 | export default styles
21 |
--------------------------------------------------------------------------------
/app/screens/Message/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 | import {THEMES} from '../../constants'
3 | const {colors} = THEMES.gitterDefault
4 |
5 | const styles = StyleSheet.create({
6 | container: {
7 | flex: 1,
8 | backgroundColor: 'white'
9 | },
10 | toolbar: {
11 | height: 56,
12 | backgroundColor: colors.raspberry,
13 | elevation: 4,
14 | marginBottom: 8
15 | },
16 | })
17 |
18 | export default styles
19 |
--------------------------------------------------------------------------------
/app/screens/RoomUserAdd/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet, Platform} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 | container: {
5 | flex: 1,
6 | backgroundColor: 'rgba(0,0,0,0.2)',
7 | paddingTop: Platform.OS === 'ios' ? 24 : 0,
8 | },
9 | bottomContainer: {
10 | flex: 1,
11 | margin: 8,
12 | borderRadius: 2,
13 | backgroundColor: 'white',
14 | elevation: 2
15 | }
16 | })
17 |
18 | export default styles
19 |
--------------------------------------------------------------------------------
/app/screens/Launch/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 | import backgroundImage from '../../styles/common/BackgroundImage'
3 |
4 | const styles = StyleSheet.create({
5 | container: {
6 | ...backgroundImage,
7 | justifyContent: 'space-around',
8 | alignItems: 'center'
9 | },
10 | logo: {
11 | fontSize: 40,
12 | color: 'white',
13 | backgroundColor: 'transparent'
14 | }
15 | })
16 |
17 |
18 | export default styles
19 |
--------------------------------------------------------------------------------
/app/screens/RoomUsers/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet, Platform} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 | container: {
5 | flex: 1,
6 | backgroundColor: 'rgba(0,0,0,0.2)',
7 | paddingTop: Platform.OS === 'ios' ? 24 : 0,
8 |
9 | },
10 | bottomContainer: {
11 | flex: 1,
12 | borderRadius: 2,
13 | elevation: 2,
14 | backgroundColor: 'white',
15 | margin: 4
16 | }
17 | })
18 |
19 | export default styles
20 |
--------------------------------------------------------------------------------
/app/screens/Message/ReadBy/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 | container: {
5 | // flex: 1
6 | },
7 | usersContainer: {
8 | paddingHorizontal: 16,
9 | paddingVertical: 4,
10 | alignItems: 'center',
11 | flexWrap: 'wrap',
12 | flexDirection: 'row'
13 | },
14 | itemContainer: {
15 | marginRight: 6,
16 | marginBottom: 4
17 | }
18 | })
19 |
20 | export default styles
21 |
--------------------------------------------------------------------------------
/app/screens/RoomInfo/Activity/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 | container: {
5 | // flex: 1
6 | },
7 | header: {
8 | paddingHorizontal: 16,
9 | paddingVertical: 24
10 | },
11 | listContainer: {
12 | paddingHorizontal: 16
13 | },
14 | itemContainer: {
15 | paddingVertical: 4
16 | },
17 | nothing: {
18 | margin: 16
19 | }
20 | })
21 |
22 | export default styles
23 |
--------------------------------------------------------------------------------
/app/components/FailedToLoad/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 | container: {
5 | flex: 1,
6 | justifyContent: 'center',
7 | alignItems: 'center'
8 | },
9 | heading: {
10 | fontSize: 18,
11 | marginBottom: 10
12 | },
13 | button: {
14 | width: 100,
15 | height: 30,
16 | alignItems: 'center',
17 | justifyContent: 'center'
18 | }
19 | })
20 |
21 | export default styles
22 |
--------------------------------------------------------------------------------
/app/screens/RoomSettings/Section/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {View} from 'react-native'
4 | import Heading from '../../../components/Heading'
5 |
6 | import s from './styles'
7 |
8 | const Section = ({title, children}) => (
9 |
10 |
11 |
12 | {children}
13 |
14 | )
15 |
16 | Section.propTypes = {
17 |
18 | }
19 |
20 | export default Section
21 |
--------------------------------------------------------------------------------
/app/components/LoadingOverlay/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {View, Text} from 'react-native'
3 | import Loading from '../Loading'
4 | import s from './styles'
5 |
6 | const LoadingOverlay = ({text}) => (
7 |
8 |
9 |
10 |
11 |
12 | )
13 |
14 | LoadingOverlay.propTypes = {
15 |
16 | }
17 |
18 | export default LoadingOverlay
19 |
--------------------------------------------------------------------------------
/app/screens/Settings/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 | import {THEMES} from '../../constants'
3 | const {colors} = THEMES.gitterDefault
4 |
5 | const styles = StyleSheet.create({
6 | container: {
7 | flex: 1,
8 | backgroundColor: '#f0eef0'
9 | },
10 | scrollContainer: {
11 | flex: 1
12 | },
13 | toolbar: {
14 | height: 56,
15 | backgroundColor: colors.raspberry,
16 | elevation: 4
17 | }
18 | })
19 |
20 | export default styles
21 |
--------------------------------------------------------------------------------
/app/screens/RoomUsers/RoomUserItem/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 | button: {
5 | elevation: 0,
6 | flexDirection: 'row',
7 | height: 70,
8 | justifyContent: 'flex-start',
9 | paddingLeft: 18,
10 | paddingVertical: 16
11 | },
12 | userInfo: {
13 | paddingLeft: 18
14 | },
15 | displayName: {
16 | fontSize: 18,
17 | color: 'black'
18 | }
19 | })
20 |
21 | export default styles
22 |
--------------------------------------------------------------------------------
/libs/react-native-gitter-faye/README.md:
--------------------------------------------------------------------------------
1 | ## react-native-gitter-faye
2 |
3 | #### example
4 | ```
5 | FayeGitter.setAccessToken('token')
6 | FayeGitter.create()
7 |
8 | FayeGitter.connect().then(() => {
9 | FayeGitter.subscribe('/api/v1/user/555e610f15522ed4b3e0c169/rooms')
10 | FayeGitter.logger()
11 | })
12 |
13 | // events
14 | FayeGitter:onDisconnected
15 | FayeGitter:onFailedToCreate
16 | FayeGitter:Message
17 | FayeGitter:SubscribtionFailed
18 | FayeGitter:Subscribed
19 | FayeGitter:Unsubscribed
20 | FayeGitter:log
21 | ```
22 |
--------------------------------------------------------------------------------
/ios/gittermobile/AppDelegate.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
3 | * All rights reserved.
4 | *
5 | * This source code is licensed under the BSD-style license found in the
6 | * LICENSE file in the root directory of this source tree. An additional grant
7 | * of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | @interface AppDelegate : UIResponder
13 |
14 | @property (nonatomic, strong) UIWindow *window;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/app/utils/hexToRgb.js:
--------------------------------------------------------------------------------
1 | export default function hexToRgb(hex) {
2 | // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
3 | const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i
4 | const newHex = hex.replace(shorthandRegex, (m, r, g, b) => {
5 | return r + r + g + g + b + b
6 | })
7 |
8 | const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(newHex)
9 | return result ? [
10 | parseInt(result[1], 16),
11 | parseInt(result[2], 16),
12 | parseInt(result[3], 16)
13 | ].join() : null
14 | }
15 |
--------------------------------------------------------------------------------
/app/screens/Drawer/ChannelListSection/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 | container: {
5 | },
6 | heading: {
7 | marginBottom: 16
8 | },
9 | sectionHeader: {
10 | flexDirection: 'row',
11 | alignItems: 'center',
12 | justifyContent: 'space-between',
13 | paddingRight: 16
14 | },
15 | icon: {
16 | width: 16,
17 | height: 16,
18 | opacity: 0.6
19 | },
20 | collapsButton: {
21 | width: 16,
22 | height: 16
23 | }
24 | })
25 |
26 | export default styles
27 |
--------------------------------------------------------------------------------
/app/screens/Room/HistoryBegin/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {View, Text} from 'react-native';
4 | import s from './styles'
5 |
6 | const HistoryBegin = () => {
7 | return (
8 |
9 |
10 | Welcome!
11 |
12 |
13 | This is the very beginning of this channel history.
14 |
15 |
16 | )
17 | }
18 |
19 | HistoryBegin.propTypes = {
20 |
21 | }
22 |
23 | export default HistoryBegin
24 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "babel-eslint",
3 | "extends": "airbnb",
4 | "env": {
5 | "browser": true,
6 | "node": true,
7 | "jasmine": true
8 | },
9 | "rules": {
10 | "no-use-before-define": [2, "nofunc"],
11 | "object-curly-spacing": 0,
12 | "react/jsx-indent-props": 0,
13 | "react/jsx-closing-bracket-location": [2, "after-props"],
14 | "react/wrap-multilines": 0,
15 | "new-cap": 0,
16 | "indent": [2, 2],
17 | "semi": 0,
18 | "comma-dangle": [1, "never"],
19 | "no-else-return": 0,
20 | "no-unused-vars": 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/libs/react-native-android-bottom-sheet/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.3"
6 |
7 | defaultConfig {
8 | minSdkVersion 16
9 | targetSdkVersion 23
10 | versionCode 1
11 | versionName "1.0"
12 | }
13 | }
14 |
15 | repositories {
16 | mavenCentral()
17 | }
18 |
19 | dependencies {
20 | compile 'com.android.support:appcompat-v7:23.2.1'
21 | compile 'com.facebook.react:react-native:0.17.0'
22 | compile 'com.cocosw:bottomsheet:1.+@aar'
23 | }
24 |
--------------------------------------------------------------------------------
/app/screens/Room/JoinRoomField/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {Text} from 'react-native';
4 | import Button from '../../../components/Button'
5 | import s from './styles'
6 |
7 | const JoinRoomField = ({onPress}) => {
8 | return (
9 |
16 | )
17 | }
18 |
19 | JoinRoomField.propTypes = {
20 | onPress: PropTypes.func
21 | }
22 |
23 | export default JoinRoomField
24 |
--------------------------------------------------------------------------------
/libs/react-native-android-bottom-sheet/index.ios.js:
--------------------------------------------------------------------------------
1 | import {ActionSheetIOS} from 'react-native'
2 |
3 | const BottomSheet = {
4 | showBotttomSheetWithOptions({title, items}, callback) {
5 | const options = {
6 | title: title || '',
7 | options: items.concat('Close'),
8 | cancelButtonIndex: items.length
9 | }
10 |
11 | ActionSheetIOS.showActionSheetWithOptions(
12 | options,
13 | index => index === items.length // Close
14 | ? () => {}
15 | : callback(index, items[index])
16 | )
17 | }
18 | }
19 |
20 | export default BottomSheet
21 |
--------------------------------------------------------------------------------
/app/screens/Room/JoinRoomField/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 | import {THEMES} from '../../../constants'
3 | const {colors} = THEMES.gitterDefault
4 |
5 |
6 | const styles = StyleSheet.create({
7 | container: {
8 | height: 52,
9 | alignSelf: 'stretch',
10 | alignItems: 'center',
11 | justifyContent: 'center',
12 | elevation: 8,
13 | backgroundColor: 'white',
14 | borderTopWidth: 1,
15 | borderTopColor: '#f0eef0'
16 | },
17 | text: {
18 | color: colors.raspberry,
19 | fontSize: 18
20 | }
21 |
22 | })
23 |
24 | export default styles
25 |
--------------------------------------------------------------------------------
/ios/gittermobile/main.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
3 | * All rights reserved.
4 | *
5 | * This source code is licensed under the BSD-style license found in the
6 | * LICENSE file in the root directory of this source tree. An additional grant
7 | * of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | #import "AppDelegate.h"
13 |
14 | int main(int argc, char * argv[]) {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/app/screens/Room/HistoryBegin/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet, Dimensions} from 'react-native'
2 | const {height} = Dimensions.get('window')
3 | const TOOLBAR_HEIGHT = 56 + 24
4 | const BOTTOM_BAR_HEIGHT = 56
5 |
6 | const styles = StyleSheet.create({
7 | container: {
8 | flex: 1,
9 | height: height - TOOLBAR_HEIGHT - BOTTOM_BAR_HEIGHT,
10 | alignSelf: 'stretch',
11 | justifyContent: 'flex-end',
12 | paddingBottom: 10,
13 | paddingHorizontal: 15
14 | },
15 | heading: {
16 | fontSize: 24
17 | },
18 | text: {
19 | fontSize: 14
20 | }
21 | })
22 |
23 | export default styles
24 |
--------------------------------------------------------------------------------
/app/components/Heading/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {View, Text} from 'react-native';
4 |
5 | const Heading = ({text, color, styles}) => (
6 |
9 |
13 | {text}
14 |
15 |
16 | )
17 |
18 | Heading.defaultProps = {
19 | color: '#E20354'
20 | }
21 |
22 | Heading.propTypes = {
23 | text: PropTypes.string.isRequired,
24 | color: PropTypes.string,
25 | styles: PropTypes.any
26 | }
27 |
28 | export default Heading
29 |
--------------------------------------------------------------------------------
/app/modules/readBy.js:
--------------------------------------------------------------------------------
1 | export const READ_BY_SNAPSHOT = 'readBy/READ_BY_SNAPSHOT'
2 |
3 | export function receiveReadBySnapshot(messageId, snapshot) {
4 | return {
5 | type: READ_BY_SNAPSHOT,
6 | payload: snapshot,
7 | messageId
8 | }
9 | }
10 |
11 | const initialState = {
12 | byMessage: {}
13 | }
14 |
15 | export default function readBy(state = initialState, action) {
16 | switch (action.type) {
17 | case READ_BY_SNAPSHOT:
18 | return {...state,
19 | byMessage: {...state.byMessage,
20 | [action.messageId]: action.payload
21 | }
22 | }
23 |
24 | default:
25 | return state
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/screens/Drawer/ChannelListItem/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 | container: {
5 | flex: 1,
6 | flexDirection: 'row',
7 | alignItems: 'center',
8 | justifyContent: 'space-between',
9 | paddingHorizontal: 16,
10 | height: 50,
11 | backgroundColor: 'white'
12 | },
13 | headingContainer: {
14 | marginLeft: 10,
15 | flex: 1
16 | },
17 | heading: {
18 | fontSize: 12,
19 | color: 'black'
20 | },
21 | leftContainer: {
22 | flexDirection: 'row',
23 | alignItems: 'center'
24 | }
25 | })
26 |
27 | export default styles
28 |
--------------------------------------------------------------------------------
/app/screens/Home/HomeRoomItem/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 | container: {
5 | flex: 1,
6 | height: 80,
7 | padding: 20,
8 | paddingLeft: 20,
9 | alignSelf: 'stretch',
10 | flexDirection: 'row',
11 | justifyContent: 'flex-start',
12 | alignItems: 'center'
13 | },
14 | infoContainer: {
15 | flex: 1,
16 | flexDirection: 'column',
17 | marginLeft: 16
18 | },
19 | name: {
20 | fontSize: 16,
21 | color: 'black'
22 | },
23 | userCount: {
24 | fontSize: 14,
25 | color: 'gray'
26 | }
27 | })
28 |
29 | export default styles
30 |
--------------------------------------------------------------------------------
/app/screens/Settings/TextItem/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {View, Text} from 'react-native';
4 | import s from './styles'
5 |
6 | import Button from '../../../components/Button'
7 |
8 | const TextITem = ({
9 | onPress,
10 | text
11 | }) => (
12 |
19 | )
20 |
21 | TextITem.propTypes = {
22 | onPress: PropTypes.func,
23 | text: PropTypes.string,
24 | icon: PropTypes.string
25 | }
26 |
27 | export default TextITem
28 |
--------------------------------------------------------------------------------
/app/components/Divider/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {View} from 'react-native';
4 |
5 | const Divider = ({inset, style, light}) => {
6 | return (
7 |
14 | )
15 | }
16 |
17 | Divider.defaultProps = {
18 | light: true
19 | }
20 |
21 | Divider.propTypes = {
22 | inset: PropTypes.bool,
23 | style: PropTypes.object,
24 | light: PropTypes.bool
25 | }
26 |
27 | export default Divider
28 |
--------------------------------------------------------------------------------
/app/screens/LoginByWebView/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 | import backgroundImage from '../../styles/common/BackgroundImage'
3 | import {THEMES} from '../../constants'
4 | const {colors} = THEMES.gitterDefault
5 |
6 | const styles = StyleSheet.create({
7 | container: {
8 | ...backgroundImage,
9 | flex: 1,
10 | justifyContent: 'center'
11 | },
12 | logo: {
13 | fontSize: 40,
14 | color: 'white',
15 | backgroundColor: 'transparent',
16 | marginTop: 20
17 | },
18 | loadingContainer: {
19 | justifyContent: 'center',
20 | alignItems: 'center'
21 | }
22 | })
23 |
24 |
25 | export default styles
26 |
--------------------------------------------------------------------------------
/app/screens/SearchMessages/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 | import {THEMES} from '../../constants'
3 | const {colors} = THEMES.gitterDefault
4 |
5 | const styles = StyleSheet.create({
6 | container: {
7 | flex: 1,
8 | backgroundColor: 'white'
9 | },
10 | toolbar: {
11 | backgroundColor: colors.raspberry,
12 | height: 56,
13 | elevation: 4
14 | },
15 | text: {
16 | textAlign: 'center',
17 | fontSize: 14,
18 | paddingTop: 16
19 | },
20 | textInput: {
21 | color: 'white',
22 | height: 24,
23 | fontSize: 18,
24 | alignSelf: 'stretch'
25 | }
26 | })
27 |
28 | export default styles
29 |
--------------------------------------------------------------------------------
/ios/Pods/SocketRocket/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Copyright 2012 Square Inc.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 |
16 |
--------------------------------------------------------------------------------
/libs/react-native-gitter-faye/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.1"
6 |
7 | defaultConfig {
8 | minSdkVersion 16
9 | targetSdkVersion 22
10 | versionCode 1
11 | versionName "1.0"
12 | }
13 | lintOptions {
14 | abortOnError false
15 | }
16 | }
17 |
18 | repositories {
19 | mavenCentral()
20 | }
21 |
22 | dependencies {
23 | compile 'com.facebook.react:react-native:0.20.0'
24 | }
25 |
26 | repositories {
27 | jcenter()
28 | }
29 |
30 | dependencies {
31 | compile 'com.github.amatkivskiy:gitter.sdk.async:1.5'
32 | }
33 |
--------------------------------------------------------------------------------
/app/modules/activity.js:
--------------------------------------------------------------------------------
1 | export const RECEIVE_ROOM_EVENTS_SNAPSHOT = 'activity/RECEIVE_ROOM_EVENTS_SNAPSHOT'
2 |
3 | export function receiveRoomEventsSnapshot(roomId, snapshot) {
4 | return {
5 | type: RECEIVE_ROOM_EVENTS_SNAPSHOT,
6 | snapshot,
7 | roomId
8 | }
9 | }
10 |
11 | const initialState = {
12 | byRoom: {
13 | // [id]: []
14 | }
15 | }
16 |
17 | export default function activity(state = initialState, action) {
18 | switch (action.type) {
19 | case RECEIVE_ROOM_EVENTS_SNAPSHOT:
20 | return {
21 | byRoom: {...state.byRoom,
22 | [action.roomId]: action.snapshot
23 | }
24 | }
25 | default:
26 | return state
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/app/screens/Drawer/SearchField/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {View, Text} from 'react-native';
4 | import s from './styles'
5 |
6 | import {THEMES} from '../../../constants'
7 | const {colors} = THEMES.gitterDefault
8 |
9 | import Icon from 'react-native-vector-icons/MaterialIcons'
10 |
11 | const SearchField = ({onPress}) => (
12 |
13 | onPress()}>
19 | Search
20 |
21 |
22 | )
23 |
24 | export default SearchField
25 |
--------------------------------------------------------------------------------
/app/components/FailedToLoad/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {View, Text} from 'react-native';
4 | import Button from '../Button'
5 | import s from './styles'
6 |
7 | const FailedToLoad = ({onRetry, message}) => {
8 | return (
9 |
10 |
11 | {message}
12 |
13 |
18 |
19 | )
20 | }
21 |
22 | FailedToLoad.propTypes = {
23 | onRetry: PropTypes.func,
24 | message: PropTypes.string
25 | }
26 |
27 | export default FailedToLoad
28 |
--------------------------------------------------------------------------------
/app/components/Avatar/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {Image} from 'react-native';
4 |
5 |
6 | const Avatar = ({src, size}) => {
7 | return (
8 |
17 | )
18 | }
19 |
20 | Avatar.defaultProps = {
21 | src: 'https://avatars.githubusercontent.com/ammorium?v=3&s=100',
22 | size: 40
23 | }
24 |
25 | Avatar.propTypes = {
26 | src: PropTypes.string,
27 | size: PropTypes.number
28 | }
29 |
30 | export default Avatar
31 |
--------------------------------------------------------------------------------
/app/components/ParsedText/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet, Platform} from 'react-native'
2 | import {THEMES} from '../../constants'
3 | const {colors} = THEMES.gitterDefault
4 |
5 | const iOS = Platform.OS === 'ios'
6 |
7 | const styles = StyleSheet.create({
8 | mention: {
9 | fontWeight: 'bold'
10 | },
11 | groupMention: {
12 | color: '#e67e22'
13 | },
14 | selfMention: {
15 | color: '#e67e22'
16 | },
17 | url: {
18 | color: colors.link
19 | },
20 | emoji: {
21 | fontSize: 14
22 | },
23 | text: {
24 | fontSize: 14
25 | },
26 | codespan: {
27 | fontFamily: iOS ? 'Courier New' : 'monospace',
28 | color: 'green'
29 | }
30 | })
31 |
32 | export default styles
33 |
--------------------------------------------------------------------------------
/app/screens/User/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 | import {THEMES} from '../../constants'
3 | const {colors} = THEMES.gitterDefault
4 |
5 | const styles = StyleSheet.create({
6 | container: {
7 | flex: 1,
8 | backgroundColor: 'white',
9 | height: '100%'
10 | },
11 | loadingContainer: {
12 | height: '100%',
13 | flex: 1,
14 | justifyContent: 'center',
15 | alignItems: 'center',
16 | backgroundColor: 'white'
17 | },
18 | toolbar: {
19 | height: 56,
20 | backgroundColor: colors.raspberry,
21 | elevation: 4
22 | },
23 | tabsContainer: {
24 | // flex: 1
25 | },
26 | tabs: {
27 | elevation: 4
28 | }
29 | })
30 |
31 | export default styles
32 |
--------------------------------------------------------------------------------
/ios/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - MZFayeClient (1.0.3):
3 | - SocketRocket
4 | - SocketRocket (0.5.1)
5 |
6 | DEPENDENCIES:
7 | - MZFayeClient (from `https://github.com/m1entus/MZFayeClient.git`, commit `6a88a1`)
8 |
9 | EXTERNAL SOURCES:
10 | MZFayeClient:
11 | :commit: 6a88a1
12 | :git: https://github.com/m1entus/MZFayeClient.git
13 |
14 | CHECKOUT OPTIONS:
15 | MZFayeClient:
16 | :commit: 6a88a1
17 | :git: https://github.com/m1entus/MZFayeClient.git
18 |
19 | SPEC CHECKSUMS:
20 | MZFayeClient: ac3defb0026d26f025444eeb021117be9cab4642
21 | SocketRocket: d57c7159b83c3c6655745cd15302aa24b6bae531
22 |
23 | PODFILE CHECKSUM: 943ae513e18e7ab74182d57137d9874ad2a96422
24 |
25 | COCOAPODS: 1.2.0
26 |
--------------------------------------------------------------------------------
/ios/Pods/Manifest.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - MZFayeClient (1.0.3):
3 | - SocketRocket
4 | - SocketRocket (0.5.1)
5 |
6 | DEPENDENCIES:
7 | - MZFayeClient (from `https://github.com/m1entus/MZFayeClient.git`, commit `6a88a1`)
8 |
9 | EXTERNAL SOURCES:
10 | MZFayeClient:
11 | :commit: 6a88a1
12 | :git: https://github.com/m1entus/MZFayeClient.git
13 |
14 | CHECKOUT OPTIONS:
15 | MZFayeClient:
16 | :commit: 6a88a1
17 | :git: https://github.com/m1entus/MZFayeClient.git
18 |
19 | SPEC CHECKSUMS:
20 | MZFayeClient: ac3defb0026d26f025444eeb021117be9cab4642
21 | SocketRocket: d57c7159b83c3c6655745cd15302aa24b6bae531
22 |
23 | PODFILE CHECKSUM: 943ae513e18e7ab74182d57137d9874ad2a96422
24 |
25 | COCOAPODS: 1.2.0
26 |
--------------------------------------------------------------------------------
/app/modules/settings.js:
--------------------------------------------------------------------------------
1 | export const READ_ALL_MESSAGES = 'settings/READ_ALL_MESSAGES'
2 |
3 | export function readAll(enabled, limit = 2) {
4 | return {
5 | type: READ_ALL_MESSAGES,
6 | enabled,
7 | limit
8 | }
9 | }
10 |
11 | const initialState = {
12 | limit: 30,
13 | usersLimit: 30,
14 | readAllMessages: {
15 | enabled: false,
16 | limit: 2
17 | }
18 | }
19 |
20 | export default function settings(state = initialState, action) {
21 | switch (action.type) {
22 | case READ_ALL_MESSAGES:
23 | return {...state,
24 | readAllMessages: {
25 | enabled: action.enabled,
26 | limit: action.limit
27 | }
28 | }
29 |
30 | default:
31 | return state
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/screens/Search/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 | import {THEMES} from '../../constants'
3 |
4 | const {colors} = THEMES.gitterDefault
5 |
6 | const styles = StyleSheet.create({
7 | container: {
8 | flex: 1,
9 | backgroundColor: 'white'
10 | },
11 | tabsContainer: {
12 | flex: 1
13 | },
14 | toolbar: {
15 | height: 56,
16 | backgroundColor: colors.raspberry
17 | },
18 | toolbarContainer: {
19 | justifyContent: 'center',
20 | alignSelf: 'stretch'
21 | },
22 | tabs: {
23 | elevation: 4
24 | },
25 | textInput: {
26 | color: 'white',
27 | height: 24,
28 | fontSize: 18,
29 | alignSelf: 'stretch'
30 | }
31 | })
32 |
33 | export default styles
34 |
--------------------------------------------------------------------------------
/app/screens/NoInternet/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 | import backgroundImage from '../../styles/common/BackgroundImage'
3 |
4 | const styles = StyleSheet.create({
5 | container: {
6 | ...backgroundImage,
7 | justifyContent: 'space-around',
8 | alignItems: 'center'
9 | },
10 | logo: {
11 | fontSize: 40,
12 | textAlign: 'center',
13 | color: 'white'
14 | },
15 | buttonStyle: {
16 | margin: 10,
17 | width: 150,
18 | height: 40,
19 | borderRadius: 2,
20 | justifyContent: 'center',
21 | alignItems: 'center',
22 | elevation: 2
23 | },
24 | buttonText: {
25 | color: 'white',
26 | fontWeight: 'bold'
27 | }
28 | })
29 |
30 | export default styles
31 |
--------------------------------------------------------------------------------
/ios/Pods/Local Podspecs/MZFayeClient.podspec.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "MZFayeClient",
3 | "version": "1.0.3",
4 | "summary": "Faye Client for iOS. Supports subscription blocks.",
5 | "homepage": "https://github.com/m1entus/MZFayeClient",
6 | "license": {
7 | "type": "MIT",
8 | "file": "LICENSE"
9 | },
10 | "authors": {
11 | "Michał Zaborowski": "m1entus@gmail.com"
12 | },
13 | "source": {
14 | "git": "https://github.com/m1entus/MZFayeClient.git",
15 | "tag": "1.0.3"
16 | },
17 | "source_files": "MZFayeClient/*.{h,m}",
18 | "dependencies": {
19 | "SocketRocket": [
20 |
21 | ]
22 | },
23 | "platforms": {
24 | "ios": "7.0"
25 | },
26 | "frameworks": "QuartzCore",
27 | "requires_arc": true
28 | }
29 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.2.3'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | mavenLocal()
18 | jcenter()
19 | maven {
20 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
21 | url "$rootDir/../node_modules/react-native/android"
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/components/Link/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React, { Component } from 'react'
3 | import {Text, Linking} from 'react-native';
4 | import s from './styles'
5 | import {THEMES} from '../../constants'
6 | const {colors} = THEMES.gitterDefault
7 |
8 |
9 | export default class Link extends Component {
10 | render() {
11 | const {children, to, fontSize} = this.props
12 | return (
13 | Linking.openURL(to)}>
16 | {children}
17 |
18 | )
19 | }
20 | }
21 |
22 | Link.propTypes = {
23 | children: PropTypes.string.isRequired,
24 | to: PropTypes.string.isRequired,
25 | fontSize: PropTypes.number
26 | }
27 |
--------------------------------------------------------------------------------
/app/utils/iconsMap.js:
--------------------------------------------------------------------------------
1 | import MaterialIcons from 'react-native-vector-icons/MaterialIcons'
2 | import {icons} from '../constants'
3 |
4 | export const iconsMap = {};
5 | export const iconsLoaded = new Promise((resolve, reject) => {
6 | new Promise.all(
7 | Object.keys(icons).map(iconName => {
8 | const icon = icons[iconName]
9 | const Provider = MaterialIcons
10 | return Provider.getImageSource(
11 | icon.icon,
12 | icon.size,
13 | icon.color
14 | )
15 | })
16 | ).then(sources => {
17 | Object.keys(icons)
18 | .forEach((iconName, idx) => iconsMap[iconName] = sources[idx])
19 |
20 | // Call resolve (and we are done)
21 | resolve(true);
22 | })
23 | })
24 |
25 | export default iconsMap
26 |
--------------------------------------------------------------------------------
/ios/Pods/SocketRocket/SocketRocket/SocketRocket.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2012 Square Inc.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | #import
18 |
--------------------------------------------------------------------------------
/ios/Pods/Local Podspecs/RNVectorIcons.podspec.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "RNVectorIcons",
3 | "version": "2.1.0",
4 | "summary": "Customizable Icons for React Native with support for NavBar/TabBar, image source and full styling.",
5 | "homepage": "https://github.com/oblador/react-native-vector-icons",
6 | "license": "MIT",
7 | "authors": {
8 | "Joel Arvidsson": "joel@oblador.se"
9 | },
10 | "platforms": {
11 | "ios": "7.0"
12 | },
13 | "source": {
14 | "git": "https://github.com/oblador/react-native-vector-icons.git",
15 | "tag": "v2.1.0"
16 | },
17 | "source_files": "RNVectorIconsManager/**/*.{h,m}",
18 | "resources": "Fonts/*.ttf",
19 | "preserve_paths": "**/*.js",
20 | "dependencies": {
21 | "React": [
22 |
23 | ]
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/components/CustomSearch/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 | const height = 48
3 |
4 | const styles = StyleSheet.create({
5 | container: {
6 | borderRadius: 2,
7 | height,
8 | flexDirection: 'row',
9 | alignItems: 'center',
10 | // justifyContent: 'center',
11 | margin: 4,
12 | backgroundColor: 'white',
13 | elevation: 2
14 | },
15 | button: {
16 | elevation: 0,
17 | width: 56,
18 | height,
19 | justifyContent: 'center',
20 | alignItems: 'center'
21 | },
22 | buttonIcon: {
23 | width: 25,
24 | height: 25,
25 | opacity: 0.6
26 | },
27 | textInput: {
28 | flex: 1,
29 | height,
30 | backgroundColor: 'white',
31 | fontSize: 18
32 | }
33 | })
34 |
35 | export default styles
36 |
--------------------------------------------------------------------------------
/ios/Pods/Target Support Files/SocketRocket/SocketRocket.xcconfig:
--------------------------------------------------------------------------------
1 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/SocketRocket
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/SocketRocket" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/MZFayeClient" "${PODS_ROOT}/Headers/Public/SocketRocket"
4 | OTHER_LDFLAGS = -l"icucore" -framework "CFNetwork" -framework "Security"
5 | PODS_BUILD_DIR = $BUILD_DIR
6 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
7 | PODS_ROOT = ${SRCROOT}
8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/SocketRocket
9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
10 | SKIP_INSTALL = YES
11 |
--------------------------------------------------------------------------------
/app/screens/Launch/index.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react'
2 | import {Text, Image, StatusBar} from 'react-native';
3 | import s from './styles'
4 | import {THEMES} from '../../constants'
5 | const {colors} = THEMES.gitterDefault
6 |
7 |
8 | export default class LaunchScreen extends Component {
9 | render() {
10 | return (
11 |
13 |
16 |
17 | Loading...
18 |
19 |
20 | )
21 | }
22 | }
23 |
24 | LaunchScreen.navigatorStyle = {
25 | navBarHidden: true,
26 | statusBarBlur: true,
27 | statusBarColor: colors.darkRed
28 | }
29 |
--------------------------------------------------------------------------------
/app/components/LoadingMoreSnack/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet, Dimensions} from 'react-native'
2 | import {THEMES} from '../../constants'
3 |
4 | const {colors} = THEMES.gitterDefault
5 | const {width} = Dimensions.get('window')
6 |
7 |
8 | const style = StyleSheet.create({
9 | container: {
10 | flex: 1,
11 | alignItems: 'center',
12 | justifyContent: 'center',
13 | position: 'absolute',
14 | top: 56,
15 | right: 0,
16 | height: 25,
17 | width,
18 | elevation: 4
19 | },
20 | text: {
21 | textAlign: 'center'
22 | },
23 | info: {
24 | backgroundColor: colors.androidGray
25 | },
26 | progressBar: {
27 | position: 'absolute',
28 | top: -6,
29 | right: 0,
30 | left: 0,
31 | elevation: 4
32 | }
33 | })
34 |
35 | export default style
36 |
--------------------------------------------------------------------------------
/app/components/LoadingMoreSnack/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {ProgressBarAndroid, View, Text} from 'react-native';
4 | import s from './styles'
5 | import {THEMES} from '../../constants'
6 | const {colors} = THEMES.gitterDefault
7 |
8 | const LoadingMoreSnack = ({loading}) => {
9 | if (loading) {
10 | return (
11 |
12 |
15 |
16 | )
17 | }
18 |
19 | return (
20 |
21 | Loading...
22 |
23 | )
24 | }
25 |
26 | LoadingMoreSnack.propTypes = {
27 | loading: PropTypes.bool
28 | }
29 |
30 | export default LoadingMoreSnack
31 |
--------------------------------------------------------------------------------
/app/screens/RoomInfo/RepoInfo/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 | container: {
5 | // flex: 1
6 | },
7 | header: {
8 | flexDirection: 'row',
9 | paddingHorizontal: 16,
10 | paddingVertical: 24
11 | },
12 | headerTextContainer: {
13 | marginLeft: 16,
14 | flexDirection: 'column'
15 | },
16 | name: {
17 | },
18 | itemContainer: {
19 | paddingHorizontal: 16,
20 | paddingVertical: 8
21 | },
22 | description: {
23 |
24 | },
25 | statContainer: {
26 | flexDirection: 'row',
27 | justifyContent: 'space-around'
28 | },
29 | statItemContainer: {
30 | alignItems: 'center',
31 | width: 75
32 | },
33 | button: {
34 | height: 48,
35 | elevation: 0
36 | }
37 | })
38 |
39 | export default styles
40 |
--------------------------------------------------------------------------------
/ios/Pods/Target Support Files/MZFayeClient/MZFayeClient.xcconfig:
--------------------------------------------------------------------------------
1 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/MZFayeClient
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/MZFayeClient" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/MZFayeClient" "${PODS_ROOT}/Headers/Public/SocketRocket"
4 | LIBRARY_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/SocketRocket"
5 | OTHER_LDFLAGS = -framework "QuartzCore"
6 | PODS_BUILD_DIR = $BUILD_DIR
7 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
8 | PODS_ROOT = ${SRCROOT}
9 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/MZFayeClient
10 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
11 | SKIP_INSTALL = YES
12 |
--------------------------------------------------------------------------------
/app/modules/index.js:
--------------------------------------------------------------------------------
1 | import {combineReducers} from 'redux'
2 |
3 | import ui from './ui'
4 | import app from './app'
5 | import auth from './auth'
6 | import rooms from './rooms'
7 | import users from './users'
8 | import readBy from './readBy'
9 | import viewer from './viewer'
10 | import search from './search'
11 | import roomInfo from './roomInfo'
12 | import messages from './messages'
13 | import settings from './settings'
14 | import realtime from './realtime'
15 | import activity from './activity'
16 | import navigation from './navigation'
17 |
18 | const rootReducer = combineReducers({
19 | ui,
20 | app,
21 | auth,
22 | rooms,
23 | users,
24 | readBy,
25 | viewer,
26 | search,
27 | roomInfo,
28 | messages,
29 | settings,
30 | realtime,
31 | activity,
32 | navigation
33 | })
34 |
35 | export default rootReducer
36 |
--------------------------------------------------------------------------------
/app/screens/Room/StatusMessage/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 | import {THEMES} from '../../../constants'
3 | const {colors} = THEMES.gitterDefault
4 |
5 | const style = StyleSheet.create({
6 | container: {
7 | flex: 1,
8 | flexDirection: 'row',
9 | flexWrap: 'wrap',
10 | paddingLeft: 15,
11 | paddingRight: 15,
12 | paddingTop: 5,
13 | paddingBottom: 5
14 | },
15 | content: {
16 | flex: 1,
17 | flexDirection: 'column',
18 | flexWrap: 'wrap',
19 | marginLeft: 15
20 | },
21 | text: {
22 | fontSize: 14,
23 | color: 'purple'
24 | },
25 | url: {
26 | color: colors.link
27 | },
28 | readStatus: {
29 | width: 15,
30 | marginTop: 3
31 | },
32 | readStatusIcon: {
33 | width: 15,
34 | height: 15
35 | }
36 | })
37 |
38 | export default style
39 |
--------------------------------------------------------------------------------
/app/components/UnreadBadge/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 | import {THEMES} from '../../constants'
3 | const {colors} = THEMES.gitterDefault
4 |
5 | const styles = StyleSheet.create({
6 | container: {
7 | width: 20,
8 | height: 20,
9 | borderRadius: 20,
10 | borderColor: 'rgba(0,0,0,0.1)',
11 | borderWidth: 0,
12 | alignItems: 'center',
13 | justifyContent: 'center'
14 | },
15 | mention: {
16 | backgroundColor: colors.mention
17 | },
18 | unread: {
19 | backgroundColor: colors.green
20 | },
21 | text: {
22 | color: colors.white,
23 | fontSize: 10
24 | },
25 | lurk: {
26 | width: 8,
27 | height: 8,
28 | borderRadius: 8,
29 | borderColor: colors.green,
30 | borderWidth: 1,
31 | backgroundColor: 'transparent'
32 | }
33 | })
34 |
35 | export default styles
36 |
--------------------------------------------------------------------------------
/app/screens/Settings/Group/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React, { Children } from 'react'
3 | import {View} from 'react-native';
4 | import s from './styles'
5 |
6 | import Heading from '../../../components/Heading'
7 | import Divider from '../../../components/Divider'
8 |
9 | const Group = ({
10 | heading,
11 | children
12 | }) => (
13 |
14 |
15 |
16 |
17 |
18 |
19 | {Children.map(children, Item => (
20 |
21 | {Item}
22 |
23 |
24 | ))}
25 |
26 |
27 | )
28 |
29 | Group.propTypes = {
30 | heading: PropTypes.string,
31 | children: PropTypes.array
32 | }
33 |
34 | export default Group
35 |
--------------------------------------------------------------------------------
/ios/Pods/Target Support Files/Pods-GitterMobile/Pods-GitterMobile.debug.xcconfig:
--------------------------------------------------------------------------------
1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/MZFayeClient" "${PODS_ROOT}/Headers/Public/SocketRocket"
3 | LIBRARY_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/MZFayeClient" "$PODS_CONFIGURATION_BUILD_DIR/SocketRocket"
4 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/MZFayeClient" -isystem "${PODS_ROOT}/Headers/Public/SocketRocket"
5 | OTHER_LDFLAGS = $(inherited) -ObjC -l"MZFayeClient" -l"SocketRocket" -l"icucore" -framework "CFNetwork" -framework "QuartzCore" -framework "Security"
6 | PODS_BUILD_DIR = $BUILD_DIR
7 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
8 | PODS_ROOT = ${SRCROOT}/Pods
9 |
--------------------------------------------------------------------------------
/app/screens/SearchMessages/MessagesList/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {ScrollView} from 'react-native'
4 | import Message from '../../Room/Message'
5 |
6 | const MessagesList = ({
7 | items,
8 | onLongPress,
9 | onPress,
10 | onUserAvatarPress
11 | }) => (
12 |
14 | {items.map(item =>
15 | {}}
21 | key={item.id} />
22 | )}
23 |
24 | )
25 |
26 | MessagesList.propTypes = {
27 | items: PropTypes.array,
28 | onPress: PropTypes.func,
29 | onLongPress: PropTypes.func,
30 | onUserAvatarPress: PropTypes.func
31 | }
32 |
33 | export default MessagesList
34 |
--------------------------------------------------------------------------------
/ios/Pods/Target Support Files/Pods-GitterMobile/Pods-GitterMobile.release.xcconfig:
--------------------------------------------------------------------------------
1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/MZFayeClient" "${PODS_ROOT}/Headers/Public/SocketRocket"
3 | LIBRARY_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/MZFayeClient" "$PODS_CONFIGURATION_BUILD_DIR/SocketRocket"
4 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/MZFayeClient" -isystem "${PODS_ROOT}/Headers/Public/SocketRocket"
5 | OTHER_LDFLAGS = $(inherited) -ObjC -l"MZFayeClient" -l"SocketRocket" -l"icucore" -framework "CFNetwork" -framework "QuartzCore" -framework "Security"
6 | PODS_BUILD_DIR = $BUILD_DIR
7 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
8 | PODS_ROOT = ${SRCROOT}/Pods
9 |
--------------------------------------------------------------------------------
/ios/gittermobileTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/ios/gittermobile-tvOSTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/screens/Drawer/DrawerUserInfo/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet, StatusBar, Platform} from 'react-native'
2 | const STATUS_BAR_HEIGHT = StatusBar.currentHeight
3 |
4 | const styles = StyleSheet.create({
5 | container: {
6 | elevation: 4
7 | },
8 | topContainer: {
9 | paddingLeft: 16,
10 | paddingRight: 8,
11 | paddingTop: Platform.OS === 'ios' ? 24 + 8 : 8,
12 | alignSelf: 'stretch',
13 | flexDirection: 'row',
14 | justifyContent: 'center',
15 | alignItems: 'center'
16 | },
17 | info: {
18 | flex: 1,
19 | flexDirection: 'column',
20 | marginLeft: 16
21 | },
22 | displayName: {
23 | fontSize: 16
24 | },
25 | buttonStyle: {
26 | width: 35,
27 | height: 35,
28 | justifyContent: 'center',
29 | alignItems: 'center'
30 | },
31 | icon: {
32 | width: 20,
33 | height: 20
34 | }
35 | })
36 |
37 | export default styles
38 |
--------------------------------------------------------------------------------
/app/components/UnreadBadge/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {View, Text} from 'react-native';
4 | import s from './styles'
5 |
6 | const UnreadBadge = ({mentions, unreadItems, lurk}) => {
7 | if (!!mentions) {
8 | return (
9 |
10 | @
11 |
12 | )
13 | } else if (lurk) {
14 | return (
15 |
16 |
17 |
18 | )
19 | } else {
20 | return (
21 |
22 | {unreadItems}
23 |
24 | )
25 | }
26 | }
27 |
28 | UnreadBadge.propTypes = {
29 | mentions: PropTypes.number,
30 | unreadItems: PropTypes.number,
31 | lurk: PropTypes.bool
32 | }
33 |
34 | export default UnreadBadge
35 |
--------------------------------------------------------------------------------
/app/screens/RoomUserAdd/RoomUserItem/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 | button: {
5 | flex: 1,
6 | elevation: 0,
7 | flexDirection: 'row',
8 | height: 70,
9 | flexWrap: 'wrap',
10 | paddingHorizontal: 18,
11 | paddingVertical: 16
12 | },
13 | container: {
14 | flex: 1,
15 | alignItems: 'center',
16 | flexDirection: 'row',
17 | height: 70,
18 | flexWrap: 'wrap'
19 | },
20 | userInfo: {
21 | flex: 1,
22 | paddingLeft: 18,
23 | flexDirection: 'column'
24 | },
25 | displayName: {
26 | fontSize: 18,
27 | color: 'black'
28 | },
29 | icon: {
30 | width: 30,
31 | height: 30,
32 | opacity: 0.6
33 | },
34 | addIcon: {
35 | width: 40,
36 | height: 40,
37 | justifyContent: 'center',
38 | alignItems: 'center',
39 | elevation: 0
40 | }
41 | })
42 |
43 | export default styles
44 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 | android.useDeprecatedNdk=true
21 |
--------------------------------------------------------------------------------
/app/screens/RoomInfo/RoomUsers/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 | import {THEMES} from '../../../constants'
3 | const {colors} = THEMES.gitterDefault
4 |
5 | const styles = StyleSheet.create({
6 | container: {
7 | // flex: 1
8 | },
9 | usersContainer: {
10 | // flex: 1,
11 | padding: 16,
12 | alignItems: 'center',
13 | flexWrap: 'wrap',
14 | flexDirection: 'row'
15 | },
16 | itemContainer: {
17 | margin: 2
18 | },
19 | buttonsGroup: {
20 | // flex: 1,
21 | flexDirection: 'row',
22 | justifyContent: 'space-between',
23 | marginLeft: 16,
24 | marginRight: 16,
25 | marginBottom: 16
26 | },
27 | button: {
28 | width: 128,
29 | height: 32,
30 | elevation: 2,
31 | justifyContent: 'center',
32 | alignItems: 'center',
33 | backgroundColor: colors.blue
34 | },
35 | primaryButton: {
36 | backgroundColor: colors.primaryButton
37 | }
38 | })
39 |
40 | export default styles
41 |
--------------------------------------------------------------------------------
/app/screens/User/UserInfo/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 | import {THEMES} from '../../../constants'
3 | const {colors} = THEMES.gitterDefault
4 |
5 | const styles = StyleSheet.create({
6 | container: {
7 | flex: 1,
8 | backgroundColor: 'white',
9 | paddingBottom: 16
10 | },
11 | item: {
12 | paddingHorizontal: 20,
13 | paddingVertical: 8,
14 | flexDirection: 'row'
15 | },
16 | icon: {
17 | marginRight: 8
18 | },
19 | button: {
20 | marginHorizontal: 20,
21 | marginVertical: 10,
22 | backgroundColor: colors.secondaryButton,
23 | elevation: 2,
24 | height: 35,
25 | borderRadius: 2,
26 | flexDirection: 'row',
27 | justifyContent: 'center',
28 | alignItems: 'center'
29 | },
30 | chatPrivately: {
31 | backgroundColor: colors.primaryButton
32 | },
33 | textWrapper: {
34 | // flex: 1
35 | },
36 | text: {
37 | fontSize: 18
38 | }
39 | })
40 |
41 | export default styles
42 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 | project.xcworkspace
24 |
25 | # Android/IntelliJ
26 | #
27 | build/
28 | .idea
29 | .gradle
30 | local.properties
31 | *.iml
32 |
33 | # node.js
34 | #
35 | node_modules/
36 | npm-debug.log
37 | yarn-error.log
38 |
39 | # BUCK
40 | buck-out/
41 | \.buckd/
42 | *.keystore
43 |
44 | # fastlane
45 | #
46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
47 | # screenshots whenever they are needed.
48 | # For more information about the recommended setup visit:
49 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
50 |
51 | fastlane/report.xml
52 | fastlane/Preview.html
53 | fastlane/screenshots
54 |
55 | app/local.js
56 |
--------------------------------------------------------------------------------
/app/screens/RoomSettings/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet, Platform} from 'react-native'
2 | import {THEMES} from '../../constants'
3 | const {colors} = THEMES.gitterDefault
4 | const iOS = Platform.OS === 'ios'
5 |
6 | const styles = StyleSheet.create({
7 | container: {
8 | flex: 1,
9 | backgroundColor: 'white'
10 | },
11 | toolbar: {
12 | backgroundColor: colors.raspberry,
13 | height: 56,
14 | elevation: 4
15 | },
16 | itemStyle: {
17 | fontSize: 12
18 | },
19 | picker: {
20 | height: iOS ? 110 : 50,
21 | overflow: 'hidden',
22 | justifyContent: 'space-around',
23 | marginHorizontal: 8
24 | },
25 | buttonStyle: {
26 | margin: 10,
27 | backgroundColor: colors.primaryButton,
28 | width: 150,
29 | height: 40,
30 | borderRadius: 2,
31 | alignSelf: 'center',
32 | justifyContent: 'center',
33 | alignItems: 'center',
34 | elevation: 2
35 | },
36 | buttonText: {
37 | color: 'white',
38 | fontWeight: 'bold'
39 | }
40 | })
41 |
42 | export default styles
43 |
--------------------------------------------------------------------------------
/app/components/Loading/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {ActivityIndicator, View, Text} from 'react-native';
4 | import {THEMES} from '../../constants'
5 | const {colors} = THEMES.gitterDefault
6 |
7 | const Loading = ({size, height, color, text}) => (
8 |
14 |
18 | {text && (
19 |
25 | {text}
26 |
27 | )}
28 |
29 | )
30 |
31 | Loading.propTypes = {
32 | size: PropTypes.string,
33 | height: PropTypes.number,
34 | color: PropTypes.string
35 | }
36 |
37 | Loading.defaultProps = {
38 | size: 'large'
39 | }
40 |
41 | export default Loading
42 |
--------------------------------------------------------------------------------
/app/screens/Message/Message/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const style = StyleSheet.create({
4 | container: {
5 | flex: 1,
6 | flexDirection: 'row',
7 | flexWrap: 'wrap',
8 | paddingLeft: 15,
9 | paddingRight: 15,
10 | paddingTop: 16,
11 | paddingBottom: 4
12 | },
13 | content: {
14 | flex: 1,
15 | flexDirection: 'column',
16 | flexWrap: 'wrap',
17 | marginLeft: 15
18 | },
19 | top: {
20 | flex: 1,
21 | flexDirection: 'row',
22 | // justifyContent: 'space-between'
23 | },
24 | username: {
25 | fontWeight: 'bold'
26 | },
27 | bottom: {
28 |
29 | },
30 | text: {
31 | fontSize: 14
32 | },
33 | deleted: {
34 | fontStyle: 'italic',
35 | opacity: 0.8
36 | },
37 | date: {
38 | marginLeft: 4,
39 | fontSize: 14
40 | },
41 | url: {
42 | color: 'blue'
43 | },
44 | readStatus: {
45 | width: 15,
46 | marginTop: 3
47 | },
48 | readStatusIcon: {
49 | width: 15,
50 | height: 15
51 | }
52 | })
53 |
54 | export default style
55 |
--------------------------------------------------------------------------------
/app/screens/Room/Message/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const style = StyleSheet.create({
4 | container: {
5 | flex: 1,
6 | flexDirection: 'row',
7 | flexWrap: 'wrap',
8 | paddingLeft: 15,
9 | paddingRight: 15,
10 | paddingTop: 5,
11 | paddingBottom: 5
12 | },
13 | content: {
14 | flex: 1,
15 | flexDirection: 'column',
16 | flexWrap: 'wrap',
17 | marginLeft: 15
18 | },
19 | top: {
20 | flex: 1,
21 | flexDirection: 'row',
22 | // justifyContent: 'space-between'
23 | },
24 | username: {
25 | fontWeight: 'bold'
26 | },
27 | bottom: {
28 |
29 | },
30 | text: {
31 | fontSize: 14
32 | },
33 | deleted: {
34 | fontStyle: 'italic',
35 | opacity: 0.8
36 | },
37 | date: {
38 | marginLeft: 4,
39 | fontSize: 14
40 | },
41 | url: {
42 | color: 'blue'
43 | },
44 | readStatus: {
45 | width: 15,
46 | marginTop: 3
47 | },
48 | readStatusIcon: {
49 | width: 15,
50 | height: 15
51 | }
52 | })
53 |
54 | export default style
55 |
--------------------------------------------------------------------------------
/app/components/Button/index.ios.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React, { Children } from 'react'
3 | import {TouchableOpacity, View} from 'react-native';
4 | import s from './styles'
5 |
6 | const noop = () => {}
7 |
8 | const Button = ({
9 | onPress = noop,
10 | onLongPress = noop,
11 | onLayout = noop,
12 | children,
13 | rippleColor,
14 | style,
15 | background
16 | }) => (
17 |
21 |
22 | {Children.map(children, child => child)}
23 |
24 |
25 | )
26 |
27 | Button.defaultProps = {
28 | onPress: noop,
29 | onLongPress: noop,
30 | onLayout: noop,
31 | rippleColor: '#f0eef0',
32 | // style: s.button
33 | }
34 |
35 | Button.propTypes = {
36 | onPress: PropTypes.func,
37 | children: PropTypes.any,
38 | style: PropTypes.any,
39 | onLongPress: PropTypes.func,
40 | onLayout: PropTypes.func,
41 | rippleColor: PropTypes.string
42 | }
43 |
44 | export default Button
45 |
--------------------------------------------------------------------------------
/app/screens/RoomUsers/RoomUserItem/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {View, Text} from 'react-native';
4 | import s from './styles'
5 |
6 | import Avatar from '../../../components/Avatar'
7 | import Button from '../../../components/Button'
8 |
9 | const RoomUserItem = ({onUserItemPress, id, username, displayName, avatarUrlSmall}) => {
10 | return (
11 |
22 | )
23 | }
24 |
25 | RoomUserItem.propTypes = {
26 | onUserItemPress: PropTypes.func,
27 | id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
28 | username: PropTypes.string,
29 | displayName: PropTypes.string,
30 | avatarUrlSmall: PropTypes.string
31 | }
32 |
33 | export default RoomUserItem
34 |
--------------------------------------------------------------------------------
/app/screens/Search/SearchUserItem/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {View, Text} from 'react-native';
4 | import Button from '../../../components/Button'
5 | import s from '../../Home/HomeRoomItem/styles'
6 | import Avatar from '../../../components/Avatar'
7 |
8 | const SearchUserItem = ({id, username, displayName, avatarUrlMedium, onPress}) => {
9 | return (
10 |
22 |
23 | )
24 | }
25 |
26 | SearchUserItem.propTypes = {
27 | displayName: PropTypes.string,
28 | username: PropTypes.string,
29 | id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
30 | avatarUrlMedium: PropTypes.string,
31 | onPress: PropTypes.func
32 | }
33 |
34 | export default SearchUserItem
35 |
--------------------------------------------------------------------------------
/app/configureStore.js:
--------------------------------------------------------------------------------
1 | import {createStore, applyMiddleware, compose} from 'redux'
2 | import thunkMiddleware from 'redux-thunk'
3 |
4 | import rootReducer from './modules'
5 |
6 |
7 | export default function configureStore(initialState) {
8 | const devTools = require('remote-redux-devtools')
9 | /**
10 | * Create store with remote-devtools and logger middleware. Do it only
11 | * in development to reduce performance issues.
12 | */
13 | if (__DEV__) {
14 | // const createLogger = require('redux-logger')
15 | // const logger = createLogger()
16 |
17 | const finalCreateStore = compose(
18 | applyMiddleware(thunkMiddleware),
19 | devTools()
20 | )(createStore)
21 |
22 | const store = finalCreateStore(rootReducer, initialState)
23 |
24 | return store
25 | } else {
26 | // const finalCreateStore = compose(applyMiddleware(thunkMiddleware), devTools())(createStore)
27 | const finalCreateStore = applyMiddleware(thunkMiddleware)(createStore)
28 | const store = finalCreateStore(rootReducer, initialState)
29 |
30 | return store
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/components/Emoji/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {Image, Text, PixelRatio, Platform} from 'react-native';
4 | import {emoji} from '../../images/emoji'
5 | const iOS = Platform.OS === 'ios'
6 |
7 | const Emoji = ({name, styles}) => {
8 | const source = emoji[name]
9 |
10 | if (!source) {
11 | return (
12 |
13 | )
14 | }
15 |
16 | return (
17 |
18 |
21 |
22 | )
23 | }
24 |
25 | Emoji.defaultProps = {
26 | styles: {
27 | wrapper: {
28 | fontSize: 14
29 | },
30 | image: iOS
31 | ? { height: 20, width: 20 }
32 | : {
33 | height: PixelRatio.getPixelSizeForLayoutSize(20),
34 | width: PixelRatio.getPixelSizeForLayoutSize(20)
35 | }
36 | }
37 | }
38 |
39 | Emoji.propTypes = {
40 | name: PropTypes.string,
41 | styles: PropTypes.object
42 | }
43 |
44 | export default Emoji
45 |
--------------------------------------------------------------------------------
/app/screens/RoomInfo/UserInfo/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {View, Text, TouchableOpacity} from 'react-native';
4 | import s from '../RoomInfo/styles'
5 |
6 | import Avatar from '../../../components/Avatar'
7 | import Divider from '../../../components/Divider'
8 |
9 | const RoomInfo = ({name, user, onAvatarPress}) => {
10 | return (
11 |
12 |
13 | onAvatarPress(user.avatarUrlSmall, name)}>
15 |
18 |
19 |
20 | {name}
21 | @{user.username}
22 |
23 |
24 |
25 |
26 | )
27 | }
28 |
29 | RoomInfo.propTypes = {
30 | name: PropTypes.string,
31 | user: PropTypes.object,
32 | onAvatarPress: PropTypes.func
33 | }
34 |
35 | export default RoomInfo
36 |
--------------------------------------------------------------------------------
/app/screens/Message/ReadBy/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {View, TouchableOpacity} from 'react-native';
4 | import s from './styles'
5 |
6 | import Avatar from '../../../components/Avatar'
7 | import Heading from '../../../components/Heading'
8 |
9 | const ReadBy = ({items, onAvatarPress}) => {
10 | return (
11 |
12 |
14 |
15 | {items.map(item => (
16 | onAvatarPress(item.id, item.username)}
18 | key={item.id}>
19 |
22 |
25 |
26 |
27 | ))}
28 |
29 |
30 | )
31 | }
32 |
33 | ReadBy.propTypes = {
34 | items: PropTypes.array,
35 | onAvatarPress: PropTypes.func
36 | }
37 |
38 | export default ReadBy
39 |
--------------------------------------------------------------------------------
/app/screens/Login/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet, Dimensions} from 'react-native'
2 | import {THEMES} from '../../constants'
3 | const {colors} = THEMES.gitterDefault
4 |
5 | const styles = StyleSheet.create({
6 | container: {
7 | flex: 1,
8 | backgroundColor: colors.raspberry,
9 | justifyContent: 'center',
10 | alignItems: 'center'
11 | },
12 | logo: {
13 | fontSize: 40,
14 | color: 'white',
15 | backgroundColor: 'transparent'
16 | },
17 | hero: {
18 | marginTop: 20,
19 | marginHorizontal: 20,
20 | fontSize: 24,
21 | color: 'white',
22 | lineHeight: 40,
23 | backgroundColor: 'transparent'
24 | },
25 | buttonGroup: {
26 | position: 'absolute',
27 | bottom: 20
28 | },
29 | buttonStyle: {
30 | backgroundColor: 'white',
31 | marginBottom: 16,
32 | height: 35,
33 | borderRadius: 2,
34 | justifyContent: 'center',
35 | alignItems: 'center',
36 | elevation: 4
37 | },
38 | buttonText: {
39 | fontWeight: 'bold',
40 | paddingHorizontal: 40,
41 | color: colors.raspberry
42 | }
43 | })
44 |
45 |
46 | export default styles
47 |
--------------------------------------------------------------------------------
/app/screens/User/UserTop/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 | container: {
5 | backgroundColor: 'white',
6 | alignItems: 'center'
7 | },
8 | avatarWrapper: {
9 | marginVertical: 30,
10 | justifyContent: 'center',
11 | alignItems: 'center'
12 | },
13 | displayNameWapper: {
14 | // flex: 1,
15 | paddingHorizontal: 30,
16 | alignItems: 'center',
17 | justifyContent: 'center',
18 | marginBottom: 15,
19 | },
20 | displayName: {
21 | textAlign: 'center',
22 | color: 'black',
23 | fontSize: 24,
24 | fontWeight: 'bold'
25 | },
26 | username: {
27 | fontSize: 18
28 | },
29 | github: {
30 | // height: 50,
31 | paddingHorizontal: 15,
32 | flexDirection: 'row',
33 | alignItems: 'center'
34 | },
35 | githubItem: {
36 | flexDirection: 'column',
37 | justifyContent: 'center',
38 | alignItems: 'center',
39 | margin: 15
40 | },
41 | githubItemText: {
42 | fontSize: 18
43 | },
44 | bold: {
45 | fontSize: 18,
46 | fontWeight: 'bold'
47 | }
48 | })
49 |
50 | export default styles
51 |
--------------------------------------------------------------------------------
/ios/Pods/MZFayeClient/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2013 Michał Zaborowski
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/app/screens/LoginByToken/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 | import {THEMES} from '../../constants'
3 | const {colors} = THEMES.gitterDefault
4 |
5 | const styles = StyleSheet.create({
6 | container: {
7 | flex: 1,
8 | backgroundColor: 'white',
9 | paddingHorizontal: 16
10 | },
11 | buttonContainer: {
12 | alignSelf: 'center'
13 | },
14 | buttonStyle: {
15 | margin: 16,
16 | backgroundColor: colors.raspberry,
17 | paddingHorizontal: 40,
18 | marginBottom: 40,
19 | height: 35,
20 | borderRadius: 2,
21 | justifyContent: 'center',
22 | alignItems: 'center',
23 | elevation: 2
24 | },
25 | buttonText: {
26 | color: 'white',
27 | fontWeight: 'bold'
28 | },
29 | textfield: {
30 | height: 40,
31 | backgroundColor: 'white',
32 | paddingLeft: 0,
33 | color: colors.raspberry
34 | },
35 | textfieldContainer: {
36 | marginVertical: 16,
37 | borderBottomWidth: 1,
38 | borderBottomColor: colors.raspberry
39 | },
40 | hint: {
41 | color: colors.secondaryFont
42 | },
43 | error: {
44 | color: colors.red,
45 | marginBottom: 16,
46 | fontSize: 18
47 | }
48 | })
49 |
50 |
51 | export default styles
52 |
--------------------------------------------------------------------------------
/app/screens/Home/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 | import {THEMES} from '../../constants'
3 | const {colors} = THEMES.gitterDefault
4 |
5 |
6 | const styles = StyleSheet.create({
7 | container: {
8 | backgroundColor: 'white',
9 |
10 | flex: 1,
11 | },
12 | scrollContainer: {
13 | // justifyContent: 'center',
14 | // alignItems: 'center'
15 | },
16 | toolbar: {
17 | height: 56,
18 | backgroundColor: colors.raspberry,
19 | elevation: 4
20 | },
21 | welcome: {
22 |
23 | fontSize: 20,
24 | textAlign: 'center',
25 | color: 'white',
26 | paddingBottom: 20
27 | },
28 | loadingWrap: {
29 | height: 200
30 | },
31 | instructions: {
32 | textAlign: 'center',
33 | color: '#333333',
34 | marginBottom: 5
35 | },
36 | heading: {
37 | flex: 1
38 | },
39 | foreground: {
40 | alignItems: 'center',
41 | justifyContent: 'center'
42 | },
43 | bottom: {
44 | flex: 1,
45 | backgroundColor: 'white',
46 | alignSelf: 'stretch',
47 | paddingTop: 20
48 | },
49 | bottomSectionHeading: {
50 | fontSize: 24,
51 | color: 'black',
52 | marginBottom: 10,
53 | marginLeft: 20
54 | }
55 | })
56 |
57 | export default styles
58 |
--------------------------------------------------------------------------------
/app/screens/Home/HomeRoomItemMy/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const styles = StyleSheet.create({
4 | container: {
5 | flex: 1,
6 | height: 80,
7 | padding: 20,
8 | paddingLeft: 20,
9 | alignSelf: 'stretch',
10 | flexDirection: 'row',
11 | justifyContent: 'flex-start',
12 | alignItems: 'center'
13 | },
14 | headingContainer: {
15 | flex: 1,
16 | flexDirection: 'column',
17 | marginLeft: 10
18 | },
19 | heading: {
20 | fontSize: 16,
21 | color: 'black'
22 | },
23 | userCount: {
24 | fontSize: 14,
25 | color: 'gray'
26 | },
27 | unread: {
28 | alignSelf: 'flex-end'
29 | }
30 | })
31 |
32 | export default styles
33 | //
34 | // container: {
35 | // height: 80,
36 | // padding: 20,
37 | // paddingLeft: 20,
38 | // alignSelf: 'stretch',
39 | // flexDirection: 'row',
40 | // justifyContent: 'flex-start',
41 | // alignItems: 'center'
42 | // },
43 | // infoContainer: {
44 | // flexDirection: 'column',
45 | // marginLeft: 16
46 | // },
47 | // name: {
48 | // fontSize: 16,
49 | // color: 'black'
50 | // },
51 | // userCount: {
52 | // fontSize: 14,
53 | // color: 'gray'
54 | // }
55 | // })
56 |
--------------------------------------------------------------------------------
/app/screens/Room/SendMessageField/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 |
3 | const padding = 12
4 | const button = 35
5 | const buttonMargin = 8
6 |
7 | const style = StyleSheet.create({
8 | container: {
9 | flexDirection: 'row',
10 | alignItems: 'center',
11 | justifyContent: 'center',
12 | paddingHorizontal: padding,
13 | backgroundColor: 'white',
14 | elevation: 8,
15 | borderTopWidth: 1,
16 | borderTopColor: '#f0eef0'
17 | },
18 | innerContainer: {
19 | flex: 1,
20 | // alignItems: 'center',
21 | justifyContent: 'center'
22 | },
23 | textInput: {
24 | backgroundColor: 'white',
25 | fontSize: 16,
26 | paddingTop: 0,
27 | paddingBottom: 0,
28 | textAlignVertical: 'center'
29 | },
30 | button: {
31 | height: button,
32 | margin: buttonMargin,
33 | alignItems: 'center',
34 | justifyContent: 'center'
35 | },
36 | sendIcon: {
37 | width: 30,
38 | height: 30
39 | },
40 | hidden: {
41 | position: 'absolute',
42 | top: 10000, // way off screen
43 | left: 10000, // way off screen
44 | backgroundColor: 'transparent',
45 | borderColor: 'transparent',
46 | color: 'transparent'
47 | }
48 | })
49 |
50 | export default style
51 |
--------------------------------------------------------------------------------
/libs/react-native-android-bottom-sheet/src/main/java/com/terrysahaidak/bottomsheet/AndroidBottomSheetPackage.java:
--------------------------------------------------------------------------------
1 | package com.terrysahaidak.bottomsheet;
2 |
3 | import android.app.Activity;
4 |
5 | import com.facebook.react.ReactPackage;
6 | import com.facebook.react.bridge.JavaScriptModule;
7 | import com.facebook.react.bridge.NativeModule;
8 | import com.facebook.react.bridge.ReactApplicationContext;
9 | import com.facebook.react.uimanager.ViewManager;
10 |
11 | import java.util.ArrayList;
12 | import java.util.Collections;
13 | import java.util.List;
14 |
15 | public class AndroidBottomSheetPackage implements ReactPackage {
16 |
17 | public AndroidBottomSheetPackage() {
18 | super();
19 | }
20 |
21 | @Override
22 | public List createNativeModules(ReactApplicationContext reactContext) {
23 | List modules = new ArrayList<>();
24 |
25 | modules.add(new AndroidBottomSheet(reactContext));
26 |
27 | return modules;
28 | }
29 |
30 | @Override
31 | public List> createJSModules() {
32 | return Collections.emptyList();
33 | }
34 |
35 | @Override
36 | public List createViewManagers(ReactApplicationContext reactContext) {
37 | return Collections.emptyList();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/app/screens/Home/HomeRoomItem/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {View, Text} from 'react-native';
4 | import Button from '../../../components/Button'
5 | import s from './styles'
6 |
7 | import Avatar from '../../../components/Avatar'
8 | import {createGhAvatarLink} from '../../../utils/links'
9 |
10 | const HomeRoomItem = ({id, name, userCount, oneToOne, onPress, ...props}) => {
11 | const src = oneToOne
12 | ? createGhAvatarLink(props.user.username, 200)
13 | : createGhAvatarLink(name.split('/')[0], 200)
14 | return (
15 |
32 |
33 | )
34 | }
35 |
36 | HomeRoomItem.propTypes = {
37 | name: PropTypes.string.isRequired,
38 | userCount: PropTypes.number.isRequired,
39 | id: PropTypes.string.isRequired,
40 | user: PropTypes.object,
41 | onPress: PropTypes.func
42 | }
43 |
44 | export default HomeRoomItem
45 |
--------------------------------------------------------------------------------
/app/screens/RoomUsers/RoomUsersSearchResult/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {View, Text, ScrollView} from 'react-native';
4 | import s from './styles'
5 |
6 | import RoomUserItem from '../RoomUserItem'
7 | import Loading from '../../../components/Loading'
8 |
9 | const RoomUsersSearchResult = ({resultItems, onUserItemPress, isLoading}) => {
10 | if (isLoading) {
11 | return (
12 |
13 |
14 |
15 |
16 |
17 | )
18 | }
19 |
20 | if (resultItems.length === 0) {
21 | return (
22 |
23 |
24 | No result
25 |
26 |
27 | )
28 | }
29 |
30 | return (
31 |
32 |
33 | {resultItems.map(item => (
34 |
37 | ))}
38 |
39 |
40 | )
41 | }
42 |
43 | RoomUsersSearchResult.propTypes = {
44 | resultItems: PropTypes.array,
45 | onUserItemPress: PropTypes.func,
46 | isLoading: PropTypes.bool
47 | }
48 |
49 | export default RoomUsersSearchResult
50 |
--------------------------------------------------------------------------------
/android/app/src/main/java/com/gittermobile/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.gittermobile;
2 |
3 | // import com.facebook.react.ReactActivity;
4 | import android.widget.LinearLayout;
5 | import android.graphics.Color;
6 | import android.widget.TextView;
7 | import android.view.Gravity;
8 | import android.util.TypedValue;
9 | import com.reactnativenavigation.controllers.SplashActivity;
10 |
11 | public class MainActivity extends SplashActivity {
12 |
13 | @Override
14 | public LinearLayout createSplashLayout() {
15 | LinearLayout view = new LinearLayout(this);
16 | TextView textView = new TextView(this);
17 |
18 | view.setBackgroundColor(Color.parseColor("#E20354"));
19 | view.setGravity(Gravity.CENTER);
20 |
21 | textView.setTextColor(Color.parseColor("#FFFFFF"));
22 | textView.setText("GitterMobile");
23 | textView.setGravity(Gravity.CENTER);
24 | textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 40);
25 |
26 | view.addView(textView);
27 | return view;
28 | }
29 |
30 | // /**
31 | // * Returns the name of the main component registered from JavaScript.
32 | // * This is used to schedule rendering of the component.
33 | // */
34 | // @Override
35 | // protected String getMainComponentName() {
36 | // return "GitterMobile";
37 | // }
38 | }
39 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'gittermobile'
2 | include ':react-native-fetch-blob'
3 | project(':react-native-fetch-blob').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fetch-blob/android')
4 |
5 | include ':app', ':react-native-android-bottom-sheet', ':react-native-gitter-faye', ':react-native-dialogs'
6 | project(':react-native-android-bottom-sheet').projectDir = new File(rootProject.projectDir, '../libs/react-native-android-bottom-sheet')
7 | project(':react-native-gitter-faye').projectDir = new File(rootProject.projectDir, '../libs/react-native-gitter-faye')
8 | project(':react-native-dialogs').projectDir = file('../node_modules/react-native-dialogs/android')
9 | include ':react-native-vector-icons'
10 | project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android')
11 | include ':react-native-device-info'
12 | project(':react-native-device-info').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-device-info/android')
13 | include ':react-native-share'
14 | project(':react-native-share').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-share/android')
15 | include ':react-native-navigation'
16 | project(':react-native-navigation').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-navigation/android/app/')
17 |
--------------------------------------------------------------------------------
/libs/react-native-gitter-faye/src/main/java/com/terrysahaidak/faye/FayeGitterPackage.java:
--------------------------------------------------------------------------------
1 | package com.terrysahaidak.faye;
2 |
3 | import android.app.Activity;
4 |
5 | import com.facebook.react.ReactPackage;
6 | import com.facebook.react.bridge.JavaScriptModule;
7 | import com.facebook.react.bridge.NativeModule;
8 | import com.facebook.react.bridge.ReactApplicationContext;
9 | import com.facebook.react.uimanager.ViewManager;
10 |
11 | import java.util.ArrayList;
12 | import java.util.Arrays;
13 | import java.util.Collections;
14 | import java.util.List;
15 |
16 | /**
17 | * Created by Nishanth Shankar on 9/23/15.
18 | */
19 | public class FayeGitterPackage implements ReactPackage {
20 | private Activity mActivity = null;
21 |
22 | public FayeGitterPackage(){
23 |
24 | }
25 |
26 | @Override
27 | public List createNativeModules(ReactApplicationContext reactApplicationContext) {
28 | List modules = new ArrayList();
29 | modules.add(new FayeGitterModule(reactApplicationContext));
30 | return modules;
31 | }
32 |
33 | @Override
34 | public List> createJSModules() {
35 | return Collections.emptyList();
36 | }
37 |
38 | @Override
39 | public List createViewManagers(ReactApplicationContext reactContext) {
40 | return Arrays.asList();
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/app/utils/createMessage.js:
--------------------------------------------------------------------------------
1 | export function createMessage(user, text) {
2 | const temporaryId = randomId()
3 | return {
4 | sending: true,
5 | failed: false,
6 | id: `send-${temporaryId}`,
7 | text,
8 | sent: 'sending...',
9 | fromUser: user
10 | }
11 | }
12 |
13 | export function createStatusMessage(user, text) {
14 | const temporaryId = randomId()
15 | return {
16 | sending: true,
17 | failed: false,
18 | id: `send-${temporaryId}`,
19 | text,
20 | status: true,
21 | sent: 'sending...',
22 | fromUser: user
23 | }
24 | }
25 |
26 | // https://gist.github.com/jed/982883
27 | function randomId(
28 | a // placeholder
29 | ) {
30 | return a // if the placeholder was passed, return
31 | ? ( // a random number from 0 to 15
32 | (// unless b is 8,
33 | (a ^ Math.random() // in which case
34 | * 16 // a random number from
35 | >> a / 4)) // 8 to 11
36 | ).toString(16) // in hexadecimal
37 | : ( // or otherwise a concatenated string:
38 | (// -80000000 +
39 | ([1e7] + // 10000000 +
40 | -1e3 + // -1000 +
41 | -4e3 + // -4000 +
42 | -8e3 + -1e11)) // -100000000000,
43 | ).replace( // replacing
44 | /[018]/g, // zeroes, ones, and eights with
45 | randomId // random hex digits
46 | )
47 | }
48 |
--------------------------------------------------------------------------------
/app/screens/NoInternet/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React, { Component } from 'react'
3 | import {Text, Image} from 'react-native';
4 | import Button from '../../components/Button'
5 | import {connect} from 'react-redux'
6 | import s from './styles'
7 | import {THEMES} from '../../constants'
8 | import {init} from '../../modules/app'
9 | const {colors} = THEMES.gitterDefault
10 | import {rootNavigator} from '../index'
11 |
12 | class NoInternetScreen extends Component {
13 | constructor(props) {
14 | super(props)
15 |
16 | this.handleRetry = this.handleRetry.bind(this)
17 | }
18 |
19 | handleRetry() {
20 | const {dispatch} = this.props
21 | rootNavigator.startAppWithScreen({screen: 'gm.Launch'})
22 | dispatch(init())
23 | }
24 |
25 | render() {
26 | return (
27 |
29 |
30 |
31 | No internet connection.
32 |
33 |
34 |
42 |
43 | )
44 | }
45 | }
46 |
47 | NoInternetScreen.propTypes = {
48 | dispatch: PropTypes.func
49 | }
50 |
51 | export default connect()(NoInternetScreen)
52 |
--------------------------------------------------------------------------------
/app/screens/Search/SearchRoomsTab/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {View, Text, ScrollView} from 'react-native';
4 | import s from './styles'
5 | import {THEMES} from '../../../constants'
6 | import Loading from '../../../components/Loading'
7 | import SearchRoomItem from '../SearchRoomItem'
8 | const {colors} = THEMES.gitterDefault
9 |
10 | const SearchRoomsTab = ({isLoadingRooms, roomsResult, value, onPress}) => {
11 | if (isLoadingRooms) {
12 | return (
13 |
15 | )
16 | }
17 |
18 | if (!value.trim()) {
19 | return (
20 |
21 | )
22 | }
23 |
24 | if (roomsResult.length === 0) {
25 | return (
26 |
27 |
28 | No result to display.
29 |
30 |
31 | )
32 | }
33 |
34 | const content = roomsResult.map(item => (
35 |
39 | ))
40 |
41 | return (
42 |
43 |
45 | {content}
46 |
47 |
48 | )
49 | }
50 |
51 | SearchRoomsTab.propTypes = {
52 | isLoadingRooms: PropTypes.bool,
53 | roomsResult: PropTypes.array,
54 | value: PropTypes.string,
55 | onPress: PropTypes.func
56 | }
57 |
58 | export default SearchRoomsTab
59 |
--------------------------------------------------------------------------------
/app/screens/RoomUserAdd/SearchResult/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {View, Text, ScrollView} from 'react-native';
4 | import s from './styles'
5 |
6 | import RoomUserItem from '../RoomUserItem'
7 | import Loading from '../../../components/Loading'
8 |
9 | const SearchResult = ({resultItems, onUserItemPress, isLoading, onAddPress}) => {
10 | if (isLoading) {
11 | return (
12 |
13 |
14 |
15 |
16 |
17 | )
18 | }
19 |
20 | if (resultItems.length === 0) {
21 | return (
22 |
23 |
24 | No result
25 |
26 |
27 | )
28 | }
29 |
30 | return (
31 |
32 |
34 | {resultItems.map(item => (
35 |
40 | ))}
41 |
42 |
43 | )
44 | }
45 |
46 | SearchResult.propTypes = {
47 | resultItems: PropTypes.array,
48 | onUserItemPress: PropTypes.func,
49 | isLoading: PropTypes.bool,
50 | onAddPress: PropTypes.func
51 | }
52 |
53 | export default SearchResult
54 |
--------------------------------------------------------------------------------
/app/screens/RoomUserAdd/RoomUserItem/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {View, Text} from 'react-native';
4 | import s from './styles'
5 | import Icon from 'react-native-vector-icons/MaterialIcons'
6 |
7 | import Avatar from '../../../components/Avatar'
8 | import Button from '../../../components/Button'
9 |
10 | const RoomUserItem = ({onUserItemPress, id, username, displayName, avatarUrlSmall, onAddPress, noButton}) => {
11 | return (
12 |
35 | )
36 | }
37 |
38 | RoomUserItem.propTypes = {
39 | onUserItemPress: PropTypes.func,
40 | id: PropTypes.string,
41 | username: PropTypes.string,
42 | displayName: PropTypes.string,
43 | avatarUrlSmall: PropTypes.string,
44 | onAddPress: PropTypes.func,
45 | noButton: PropTypes.bool
46 | }
47 |
48 | export default RoomUserItem
49 |
--------------------------------------------------------------------------------
/app/screens/Search/SearchUsersTab/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {View, Text, ScrollView} from 'react-native';
4 | import s from '../SearchRoomsTab/styles'
5 | import {THEMES} from '../../../constants'
6 | import Loading from '../../../components/Loading'
7 | import SearchUserItem from '../SearchUserItem'
8 | const {colors} = THEMES.gitterDefault
9 |
10 | const SearchUsersTab = ({isLoadingUsers, usersResult, value, onPress}) => {
11 | if (isLoadingUsers) {
12 | return (
13 |
15 | )
16 | }
17 |
18 | if (!value.trim()) {
19 | return (
20 |
21 | )
22 | }
23 |
24 | if (usersResult.length === 0) {
25 | return (
26 |
27 |
28 | No result to display.
29 |
30 |
31 | )
32 | }
33 |
34 | const content = usersResult.map(item => (
35 |
39 | ))
40 |
41 | return (
42 |
43 |
45 | {content}
46 |
47 |
48 | )
49 | }
50 |
51 | SearchUsersTab.propTypes = {
52 | isLoadingUsers: PropTypes.bool,
53 | usersResult: PropTypes.array,
54 | value: PropTypes.string,
55 | onPress: PropTypes.func
56 | }
57 |
58 | export default SearchUsersTab
59 |
--------------------------------------------------------------------------------
/app/screens/RoomInfo/RoomInfo/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {View, Text, TouchableOpacity} from 'react-native';
4 | import s from './styles'
5 |
6 | import {createGhAvatarLink} from '../../../utils/links'
7 | import channelNameAndOwner from '../../../utils/channelNameAndOwner'
8 |
9 | import Avatar from '../../../components/Avatar'
10 | import Divider from '../../../components/Divider'
11 |
12 | const RoomInfo = ({name, onAvatarPress}) => {
13 | const avatarSrc = createGhAvatarLink(name.split('/')[0], 200)
14 | const channel = channelNameAndOwner(name)
15 |
16 | return (
17 |
18 |
19 | onAvatarPress(avatarSrc, !channel.name ? channel.owner : channel.name)}>
21 |
24 |
25 | {!channel.name
26 | ? (
27 |
28 | {channel.owner}
29 |
30 | ) : (
31 |
32 | {channel.name}
33 | by {channel.owner}
34 |
35 | )}
36 |
37 |
38 |
39 | )
40 | }
41 |
42 | RoomInfo.propTypes = {
43 | name: PropTypes.string,
44 | onAvatarPress: PropTypes.func
45 | }
46 |
47 | export default RoomInfo
48 |
--------------------------------------------------------------------------------
/.flowconfig:
--------------------------------------------------------------------------------
1 | [ignore]
2 | ; We fork some components by platform
3 | .*/*[.]android.js
4 |
5 | ; Ignore "BUCK" generated dirs
6 | /\.buckd/
7 |
8 | ; Ignore unexpected extra "@providesModule"
9 | .*/node_modules/.*/node_modules/fbjs/.*
10 |
11 | ; Ignore duplicate module providers
12 | ; For RN Apps installed via npm, "Libraries" folder is inside
13 | ; "node_modules/react-native" but in the source repo it is in the root
14 | .*/Libraries/react-native/React.js
15 | .*/Libraries/react-native/ReactNative.js
16 |
17 | [include]
18 |
19 | [libs]
20 | node_modules/react-native/Libraries/react-native/react-native-interface.js
21 | node_modules/react-native/flow
22 | flow/
23 |
24 | [options]
25 | emoji=true
26 |
27 | module.system=haste
28 |
29 | experimental.strict_type_args=true
30 |
31 | munge_underscores=true
32 |
33 | module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'
34 |
35 | suppress_type=$FlowIssue
36 | suppress_type=$FlowFixMe
37 | suppress_type=$FixMe
38 |
39 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(4[0-5]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
40 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(4[0-5]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
41 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
42 | suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
43 |
44 | unsafe.enable_getters_and_setters=true
45 |
46 | [version]
47 | ^0.45.0
48 |
--------------------------------------------------------------------------------
/app/components/CustomSearch/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {TextInput, View, Platform} from 'react-native';
4 | import s from './styles'
5 | import Button from '../Button'
6 | import Icon from 'react-native-vector-icons/MaterialIcons'
7 |
8 | const CustomSearch = (props) => {
9 | const {value, onChange, onBackPress, onClearPress} = props
10 |
11 | return (
12 |
13 | onBackPress()}>
16 |
21 |
22 |
30 | {!!value && value.length !== 0 ? (
31 | onClearPress()}>
34 |
39 |
40 | ) : ()}
41 |
42 | )
43 | }
44 |
45 | CustomSearch.propTypes = {
46 | value: PropTypes.string,
47 | onChange: PropTypes.func,
48 | onBackPress: PropTypes.func,
49 | onClearPress: PropTypes.func
50 | }
51 |
52 | export default CustomSearch
53 |
--------------------------------------------------------------------------------
/app/screens/Search/SearchRoomItem/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {View, Text} from 'react-native';
4 | import Button from '../../../components/Button'
5 | import s from '../../Home/HomeRoomItem/styles'
6 | // import {THEMES} from '../constants'
7 | // const {colors} = THEMES.gitterDefault
8 | import Avatar from '../../../components/Avatar'
9 | import {createGhAvatarLink} from '../../../utils/links'
10 |
11 |
12 | const SearchRoomItem = ({id, name, userCount, oneToOne, onPress, exists, room, ...props}) => {
13 | const src = oneToOne
14 | ? createGhAvatarLink(props.user.username, 200)
15 | : createGhAvatarLink(name.split('/')[0], 200)
16 |
17 | const roomId = !!exists && exists === true && !!room ? room.id : id
18 | return (
19 | onPress(roomId, exists)}
22 | rippleColor="#ECECEC">
23 |
26 |
27 |
28 | {name}
29 | {userCount} people
30 |
31 |
32 |
33 | )
34 | }
35 |
36 | SearchRoomItem.defaultProps = {
37 | exists: true
38 | }
39 |
40 | SearchRoomItem.propTypes = {
41 | name: PropTypes.string.isRequired,
42 | userCount: PropTypes.number.isRequired,
43 | id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
44 | user: PropTypes.object,
45 | onPress: PropTypes.func,
46 | exists: PropTypes.bool,
47 | room: PropTypes.object
48 | }
49 |
50 | export default SearchRoomItem
51 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
15 |
16 |
22 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/app/modules/viewer.js:
--------------------------------------------------------------------------------
1 | import * as Api from '../api/gitter'
2 | import {LOGOUT} from './auth'
3 |
4 | /**
5 | * Constants
6 | */
7 |
8 | export const CURRENT_USER = 'viewer/CURRENT_USER'
9 | export const CURRENT_USER_RECEIVED = 'viewer/CURRENT_USER_RECEIVED'
10 | export const CURRENT_USER_FAILED = 'viewer/CURRENT_USER_FAILED'
11 |
12 | /**
13 | * Action creators
14 | */
15 |
16 | /**
17 | * Returns current user info by token
18 | */
19 | export function getCurrentUser() {
20 | return async (dispatch, getState) => {
21 | const {token} = getState().auth
22 | try {
23 | dispatch({type: CURRENT_USER})
24 | const payload = await Api.currentUser(token)
25 | dispatch({type: CURRENT_USER_RECEIVED, payload: payload[0]})
26 | } catch (error) {
27 | dispatch({CURRENT_USER_FAILED, error})
28 | }
29 | }
30 | }
31 |
32 | /**
33 | * Reducer
34 | */
35 |
36 | const initialState = {
37 | isLoading: false,
38 | error: false,
39 | errors: [],
40 | user: {}
41 | }
42 |
43 | export default function viewer(state = initialState, action) {
44 | switch (action.type) {
45 | case CURRENT_USER: {
46 | return {...state,
47 | isLoading: true
48 | }
49 | }
50 |
51 | case CURRENT_USER_RECEIVED: {
52 | return {...state,
53 | isLoading: false,
54 | user: action.payload
55 | }
56 | }
57 |
58 | case LOGOUT: {
59 | return Object.assign({}, initialState)
60 | }
61 |
62 | case CURRENT_USER_FAILED: {
63 | return {...state,
64 | isLoading: false,
65 | error: true,
66 | errors: action.error
67 | }
68 | }
69 |
70 | default:
71 | return state
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/app/screens/Login/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React, { Component } from 'react'
3 | import {Text, View} from 'react-native';
4 | import Button from '../../components/Button'
5 | import s from './styles'
6 | import {connect} from 'react-redux'
7 | import {THEMES} from '../../constants'
8 | const {colors} = THEMES.gitterDefault
9 |
10 |
11 | class LoginScreen extends Component {
12 | render() {
13 | const {navigator} = this.props
14 | return (
15 |
16 |
17 | GitterMobile
18 |
19 |
20 | navigator.push({screen: 'gm.LoginByWebView', animated: true, title: 'Login'})}>
23 |
25 | Login
26 |
27 |
28 | navigator.push({screen: 'gm.LoginByToken', animated: true, title: 'Paste token'})}>
31 |
33 | Paste token
34 |
35 |
36 |
37 |
38 | )
39 | }
40 | }
41 |
42 | LoginScreen.propTypes = {
43 | dispatch: PropTypes.func,
44 | navigator: PropTypes.object
45 | }
46 |
47 | LoginScreen.navigatorStyle = {
48 | navBarHidden: true,
49 | statusBarBlur: true,
50 | statusBarColor: colors.darkRed
51 | }
52 |
53 | export default connect()(LoginScreen)
54 |
--------------------------------------------------------------------------------
/app/screens/RoomUsers/RoomUsersList/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React, { Component } from 'react'
3 | import {ListView, View} from 'react-native';
4 | import s from './styles'
5 |
6 | import RoomUserItem from '../RoomUserItem'
7 |
8 | export default class RoomUsersList extends Component {
9 | constructor(props) {
10 | super(props)
11 |
12 | this.renderRow = this.renderRow.bind(this)
13 | }
14 |
15 | renderRow(rowData, rowId) {
16 | const {onItemPress, onUserItemPress} = this.props
17 |
18 | return (
19 |
24 | )
25 | }
26 |
27 | render() {
28 | const {listViewData} = this.props
29 |
30 | if (!listViewData) {
31 | return
32 | }
33 |
34 | return (
35 |
36 | this.renderRow(rowData, rowId)} />
47 |
48 | )
49 | }
50 | }
51 |
52 | RoomUsersList.propTypes = {
53 | listViewData: PropTypes.object,
54 | onItemPress: PropTypes.func,
55 | onEndReached: PropTypes.func,
56 | onUserItemPress: PropTypes.func
57 | }
58 |
--------------------------------------------------------------------------------
/app/components/Toolbar/styles.js:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native'
2 | import {THEMES} from '../../constants'
3 | const {colors} = THEMES.gitterDefault
4 |
5 | const styles = StyleSheet.create({
6 | globalContainer: {
7 | flex: 1,
8 | backgroundColor: '#FFF'
9 | },
10 | container: {
11 | height: 64,
12 | paddingTop: 20,
13 | flexDirection: 'row',
14 | alignItems: 'center',
15 | // alignSelf: 'stretch'
16 | justifyContent: 'space-between'
17 | },
18 | titleContainer: {
19 | // flex: 1,
20 | // backgroundColor: 'gray',
21 | // justifyContent: 'center',
22 | // alignItems: 'center'
23 | },
24 | title: {
25 | fontSize: 16,
26 | fontWeight: 'bold',
27 | color: 'white'
28 | },
29 | iconButton: {
30 | backgroundColor: colors.raspberry,
31 | // marginHorizontal: 4,
32 | height: 35,
33 | flexDirection: 'row',
34 | alignItems: 'center',
35 | width: 44,
36 | justifyContent: 'center'
37 | },
38 | showIcon: {
39 | // marginRight: 4
40 | },
41 | icon: {
42 | width: 25,
43 | height: 25
44 | },
45 | addContainer: {
46 | // paddingHorizontal: 8,
47 | height: 44,
48 | flexDirection: 'row',
49 | alignItems: 'center',
50 | width: 44,
51 | justifyContent: 'flex-end',
52 | // alignSelf: 'flex-end'
53 | },
54 | addContainerInner: {
55 | flex: 1,
56 | flexDirection: 'row',
57 | justifyContent: 'center',
58 | alignItems: 'center'
59 | },
60 | iconTitle: {
61 | color: '#FFF',
62 | paddingRight: 20,
63 | fontSize: 20
64 | },
65 | childrenContainer: {
66 | flex: 1
67 | }
68 | })
69 |
70 | export default styles
71 |
--------------------------------------------------------------------------------
/app/screens/Home/HomeRoomItemMy/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {View, Text} from 'react-native';
4 | import Button from '../../../components/Button'
5 | import UnreadBadge from '../../../components/UnreadBadge'
6 | import s from './styles'
7 | import Avatar from '../../../components/Avatar'
8 |
9 | import {createGhAvatarLink} from '../../../utils/links'
10 |
11 | const HomeRoomItemMy = ({
12 | id, name, oneToOne, user, onPress,
13 | unreadItems, mentions, lurk, userCount
14 | }) => {
15 | const src = oneToOne
16 | ? createGhAvatarLink(user.username, 200)
17 | : createGhAvatarLink(name.split('/')[0], 200)
18 |
19 | return (
20 | onPress(id)}>
24 |
27 |
28 |
29 |
33 | {name}
34 |
35 | {userCount} people
36 |
37 | {(!!unreadItems || !!mentions || !!lurk) &&
38 |
39 |
43 | }
44 |
45 |
46 | )
47 | }
48 |
49 |
50 | HomeRoomItemMy.propTypes = {
51 | name: PropTypes.string.isRequired,
52 | userCount: PropTypes.number.isRequired,
53 | id: PropTypes.string.isRequired,
54 | user: PropTypes.object,
55 | onPress: PropTypes.func
56 | }
57 |
58 |
59 | export default HomeRoomItemMy
60 |
--------------------------------------------------------------------------------
/app/screens/Drawer/ChannelListSection/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {View} from 'react-native'
4 | import s from './styles'
5 | import ChannelListItem from '../ChannelListItem'
6 | import Heading from '../../../components/Heading'
7 | import Button from '../../../components/Button'
8 | import Icon from 'react-native-vector-icons/MaterialIcons'
9 |
10 | const ChannelListSection = ({
11 | name,
12 | items,
13 | onRoomPress,
14 | activeRoom,
15 | onLongRoomPress,
16 | onToggleCollapsed,
17 | sectionsState
18 | }) => {
19 | const icon = sectionsState[name] ? 'expand-more' : 'expand-less'
20 |
21 | return (
22 |
23 | onToggleCollapsed(name, sectionsState[name])}>
26 |
27 |
31 |
32 |
33 | {!sectionsState[name] && items && items.map(item => (
34 |
40 | ))}
41 |
42 |
43 | )
44 | }
45 |
46 |
47 | ChannelListSection.propTypes = {
48 | name: PropTypes.string,
49 | items: PropTypes.array,
50 | onRoomPress: PropTypes.func,
51 | activeRoom: PropTypes.string,
52 | onLongRoomPress: PropTypes.func,
53 | collapsed: PropTypes.bool,
54 | sectionsState: PropTypes.object
55 | }
56 |
57 | export default ChannelListSection
58 |
--------------------------------------------------------------------------------
/app/screens/Drawer/DrawerUserInfo/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {Image, View, Text} from 'react-native';
4 | import Button from '../../../components/Button'
5 | import s from './styles'
6 | import Avatar from '../../../components/Avatar'
7 | import SearchField from '../SearchField'
8 |
9 | import {THEMES} from '../../../constants'
10 | const {colors} = THEMES.gitterDefault
11 |
12 | import Icon from 'react-native-vector-icons/MaterialIcons'
13 |
14 | const DrawerUserInfo = ({username, displayName, avatarUrlMedium, onSettingsPress, onSearchPress}) => {
15 | return (
16 |
20 |
21 |
22 |
23 |
24 | {displayName}
25 | @{username}
26 |
27 |
28 |
32 |
33 |
34 |
35 |
36 |
37 | onSearchPress()} />
39 |
40 | )
41 | }
42 |
43 | DrawerUserInfo.propTypes = {
44 | username: PropTypes.string,
45 | displayName: PropTypes.string,
46 | avatarUrlMedium: PropTypes.string,
47 | onSettingsPress: PropTypes.func,
48 | onSearchPress: PropTypes.func
49 | }
50 |
51 | export default DrawerUserInfo
52 |
--------------------------------------------------------------------------------
/ios/gittermobile.xcworkspace/xcshareddata/gittermobile.xcscmblueprint:
--------------------------------------------------------------------------------
1 | {
2 | "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "5F21F0E3235FB84632695194147A453A6E6793CF",
3 | "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : {
4 |
5 | },
6 | "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : {
7 | "5F21F0E3235FB84632695194147A453A6E6793CF" : 9223372036854775807,
8 | "2D744A5E2DBE6045F4BDE5587E93CD9E116BC6F4" : 9223372036854775807
9 | },
10 | "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "ED1D968B-5A19-4871-A08D-A2ADAC173F62",
11 | "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : {
12 | "5F21F0E3235FB84632695194147A453A6E6793CF" : "GitterMobile\/",
13 | "2D744A5E2DBE6045F4BDE5587E93CD9E116BC6F4" : "..\/khmarka\/megabank"
14 | },
15 | "DVTSourceControlWorkspaceBlueprintNameKey" : "gittermobile",
16 | "DVTSourceControlWorkspaceBlueprintVersion" : 204,
17 | "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "ios\/gittermobile.xcworkspace",
18 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [
19 | {
20 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:khmarka\/mgb.git",
21 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
22 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "2D744A5E2DBE6045F4BDE5587E93CD9E116BC6F4"
23 | },
24 | {
25 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:terrysahaidak\/GitterMobile.git",
26 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
27 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "5F21F0E3235FB84632695194147A453A6E6793CF"
28 | }
29 | ]
30 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Terry Sahaidak
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
24 |
25 | Copyright 2016 Terry Sahaidak
26 |
27 | Licensed under the Apache License, Version 2.0 (the "License");
28 | you may not use this file except in compliance with the License.
29 | You may obtain a copy of the License at
30 |
31 | http://www.apache.org/licenses/LICENSE-2.0
32 |
33 | Unless required by applicable law or agreed to in writing, software
34 | distributed under the License is distributed on an "AS IS" BASIS,
35 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
36 | See the License for the specific language governing permissions and
37 | limitations under the License.
38 |
--------------------------------------------------------------------------------
/app/screens/User/UserTop/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {View, Text, TouchableOpacity} from 'react-native'
4 | import Avatar from '../../../components/Avatar'
5 | import s from './styles'
6 | import {createGhAvatarLink} from '../../../utils/links'
7 |
8 | const UserTop = ({displayName, username, github, gravatarImageUrl, onAvatarPress}) => {
9 | const avatar = github ? createGhAvatarLink(username, 200) : gravatarImageUrl
10 |
11 | return (
12 |
13 | onAvatarPress(avatar)}>
15 |
16 |
19 |
20 |
21 |
22 |
23 | {displayName}
24 |
25 |
26 | @{username}
27 |
28 |
29 | {github &&
30 |
31 | {github.followers}
32 | followers
33 |
34 |
35 | {github.public_repos}
36 | repos
37 |
38 |
39 | {github.following}
40 | following
41 |
42 | }
43 |
44 | )
45 | }
46 |
47 | UserTop.propTypes = {
48 | displayName: PropTypes.string,
49 | username: PropTypes.string,
50 | github: PropTypes.object
51 | }
52 |
53 | export default UserTop
54 |
--------------------------------------------------------------------------------
/ios/gittermobile-tvOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UIViewControllerBasedStatusBarAppearance
38 |
39 | NSLocationWhenInUseUsageDescription
40 |
41 | NSAppTransportSecurity
42 |
43 |
44 | NSExceptionDomains
45 |
46 | localhost
47 |
48 | NSExceptionAllowsInsecureHTTPLoads
49 |
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/android/app/BUCK:
--------------------------------------------------------------------------------
1 | # To learn about Buck see [Docs](https://buckbuild.com/).
2 | # To run your application with Buck:
3 | # - install Buck
4 | # - `npm start` - to start the packager
5 | # - `cd android`
6 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"`
7 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck
8 | # - `buck install -r android/app` - compile, install and run application
9 | #
10 |
11 | lib_deps = []
12 |
13 | for jarfile in glob(['libs/*.jar']):
14 | name = 'jars__' + jarfile[jarfile.rindex('/') + 1: jarfile.rindex('.jar')]
15 | lib_deps.append(':' + name)
16 | prebuilt_jar(
17 | name = name,
18 | binary_jar = jarfile,
19 | )
20 |
21 | for aarfile in glob(['libs/*.aar']):
22 | name = 'aars__' + aarfile[aarfile.rindex('/') + 1: aarfile.rindex('.aar')]
23 | lib_deps.append(':' + name)
24 | android_prebuilt_aar(
25 | name = name,
26 | aar = aarfile,
27 | )
28 |
29 | android_library(
30 | name = "all-libs",
31 | exported_deps = lib_deps,
32 | )
33 |
34 | android_library(
35 | name = "app-code",
36 | srcs = glob([
37 | "src/main/java/**/*.java",
38 | ]),
39 | deps = [
40 | ":all-libs",
41 | ":build_config",
42 | ":res",
43 | ],
44 | )
45 |
46 | android_build_config(
47 | name = "build_config",
48 | package = "com.gittermobile",
49 | )
50 |
51 | android_resource(
52 | name = "res",
53 | package = "com.gittermobile",
54 | res = "src/main/res",
55 | )
56 |
57 | android_binary(
58 | name = "app",
59 | keystore = "//android/keystores:debug",
60 | manifest = "src/main/AndroidManifest.xml",
61 | package_type = "debug",
62 | deps = [
63 | ":app-code",
64 | ],
65 | )
66 |
--------------------------------------------------------------------------------
/app/components/Button/index.android.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React, { Children } from 'react'
3 | import {TouchableNativeFeedback, TouchableOpacity, View} from 'react-native';
4 | import s from './styles'
5 | import DeviceInfo from 'react-native-device-info'
6 | import {OLD_ANDROID_VERSIONS} from '../../constants'
7 |
8 | const noop = () => {}
9 |
10 | const Button = ({
11 | onPress = noop,
12 | onLongPress = noop,
13 | onLayout = noop,
14 | children,
15 | rippleColor,
16 | style,
17 | background
18 | }) => {
19 | const version = DeviceInfo.getSystemVersion()
20 |
21 | if (!!OLD_ANDROID_VERSIONS.find(oldVersion => oldVersion === version)) {
22 | return (
23 |
27 |
28 | {Children.map(children, child => child)}
29 |
30 |
31 | )
32 | } else {
33 | return (
34 |
39 |
40 | {Children.map(children, child => child)}
41 |
42 |
43 | )
44 | }
45 | }
46 |
47 | Button.defaultProps = {
48 | onPress: noop,
49 | onLongPress: noop,
50 | onLayout: noop,
51 | rippleColor: '#f0eef0',
52 | // style: s.button
53 | }
54 |
55 | Button.propTypes = {
56 | onPress: PropTypes.func,
57 | children: PropTypes.any,
58 | style: PropTypes.any,
59 | onLongPress: PropTypes.func,
60 | onLayout: PropTypes.func,
61 | rippleColor: PropTypes.string
62 | }
63 |
64 | export default Button
65 |
--------------------------------------------------------------------------------
/app/screens/Room/StatusMessage/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {View} from 'react-native';
4 | import Parser from 'react-native-parsed-text'
5 | import Icon from 'react-native-vector-icons/MaterialIcons'
6 |
7 | import s from './styles'
8 | import Button from '../../../components/Button'
9 | import renderEmoji from './renderEmoji'
10 |
11 | const EMOJI_REGEX = /:([a-z0-9A-Z_-]+):/
12 | const THUMBSUP = /:\+1:/
13 | const THUMBSDOWN = /:\-1:/
14 |
15 | const StatusMessage = ({onPress, onLongPress, text, handleUrlPress, backgroundColor, opacity, onLayout}) => {
16 | const patterns = [
17 | {type: 'url', style: s.url, onPress: handleUrlPress},
18 | {pattern: EMOJI_REGEX, style: s.emoji, renderText: renderEmoji},
19 | {pattern: THUMBSUP, style: s.emoji, renderText: renderEmoji},
20 | {pattern: THUMBSDOWN, style: s.emoji, renderText: renderEmoji}
21 | ]
22 |
23 | return (
24 | onPress()}
27 | onLayout={e => onLayout(e)}
28 | onLongPress={() => onLongPress()}>
29 |
32 |
33 |
34 |
37 | {text}
38 |
39 |
40 |
41 |
42 |
47 |
48 |
49 | )
50 | }
51 |
52 | StatusMessage.propTypes = {
53 | onPress: PropTypes.func,
54 | onLongPress: PropTypes.func,
55 | text: PropTypes.string,
56 | handleUrlPress: PropTypes.func,
57 | backgroundColor: PropTypes.string,
58 | opacity: PropTypes.number
59 | }
60 |
61 | export default StatusMessage
62 |
--------------------------------------------------------------------------------
/app/components/ParsedText/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {Text} from 'react-native';
4 | import Parser from 'react-native-parsed-text'
5 | import Emoji from '../Emoji'
6 | import s from './styles'
7 |
8 | const MENTION_REGEX = /(([^`]|^)@([a-zA-Z0-9_\-]+))/
9 | const GROUP_MENTION_REGEX = /^(@\/([a-zA-Z0-9_\-]+))/
10 | const EMOJI_REGEX = /:([a-z0-9A-Z_-]+):/
11 | const THUMBSUP = /:\+1:/
12 | const THUMBSDOWN = /:\-1:/
13 | const CODE_REGEX = /(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/m
14 |
15 | const renderEmoji = (matchingString, matches) => {
16 | const name = matches[0].replace(/:/g, '')
17 | return (
18 |
19 | )
20 | }
21 |
22 | const renderCodespan = (matchingString, matches) => {
23 | let component
24 | matchingString.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm,
25 | (wholeMatch, m1, m2, m3) => {
26 | let c = m3;
27 | c = c.replace(/^([ \t]*)/g, ''); // leading whitespace
28 | c = c.replace(/[ \t]*$/g, ''); // trailing whitespace
29 | component = (
30 | {c}
31 | )
32 | })
33 | return component
34 | }
35 |
36 | const ParsedText = ({text, username, handleUrlPress}) => {
37 | const patterns = [
38 | {type: 'url', style: s.url, onPress: handleUrlPress},
39 | {pattern: new RegExp(`@${username}`), style: s.selfMention},
40 | {pattern: MENTION_REGEX, style: s.mention},
41 | {pattern: GROUP_MENTION_REGEX, style: s.groupMention},
42 | {pattern: EMOJI_REGEX, style: s.emoji, renderText: renderEmoji},
43 | {pattern: THUMBSUP, style: s.emoji, renderText: renderEmoji},
44 | {pattern: THUMBSDOWN, style: s.emoji, renderText: renderEmoji},
45 | {pattern: CODE_REGEX, renderText: renderCodespan}
46 | ]
47 |
48 | return (
49 |
52 | {text}
53 |
54 | )
55 | }
56 |
57 | ParsedText.propTypes = {
58 | text: PropTypes.string,
59 | handleUrlPress: PropTypes.func
60 | }
61 |
62 | export default ParsedText
63 |
--------------------------------------------------------------------------------
/ios/Pods/Target Support Files/Pods-GitterMobile/Pods-GitterMobile-acknowledgements.markdown:
--------------------------------------------------------------------------------
1 | # Acknowledgements
2 | This application makes use of the following third party libraries:
3 |
4 | ## MZFayeClient
5 |
6 | The MIT License (MIT)
7 |
8 | Copyright (c) 2013 Michał Zaborowski
9 |
10 | Permission is hereby granted, free of charge, to any person obtaining a copy of
11 | this software and associated documentation files (the "Software"), to deal in
12 | the Software without restriction, including without limitation the rights to
13 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
14 | the Software, and to permit persons to whom the Software is furnished to do so,
15 | subject to the following conditions:
16 |
17 | The above copyright notice and this permission notice shall be included in all
18 | copies or substantial portions of the Software.
19 |
20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
22 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
23 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
24 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 |
27 |
28 | ## SocketRocket
29 |
30 |
31 | Copyright 2012 Square Inc.
32 |
33 | Licensed under the Apache License, Version 2.0 (the "License");
34 | you may not use this file except in compliance with the License.
35 | You may obtain a copy of the License at
36 |
37 | http://www.apache.org/licenses/LICENSE-2.0
38 |
39 | Unless required by applicable law or agreed to in writing, software
40 | distributed under the License is distributed on an "AS IS" BASIS,
41 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
42 | See the License for the specific language governing permissions and
43 | limitations under the License.
44 |
45 |
46 | Generated by CocoaPods - https://cocoapods.org
47 |
--------------------------------------------------------------------------------
/app/constants.js:
--------------------------------------------------------------------------------
1 | import {Platform} from 'react-native'
2 | const iOS = Platform.OS === 'ios'
3 |
4 | export const THEMES = {
5 | gitterDefault: {
6 | name: 'Gitter default theme',
7 | colors: {
8 | brand: '#E20354',
9 |
10 | sidebarBackground: '#383435',
11 |
12 | primaryButton: '#46bc99',
13 | secondaryButton: '#d6d6d6',
14 |
15 | green: '#1dce73',
16 | orange: '#ea9448',
17 | yellow: '#f1c40f',
18 | blue: '#3498db',
19 | red: '#e74c3c',
20 | purple: '#935991',
21 |
22 | mention: '#e67e22',
23 | unReadBackground: 'rgba(213,245,226,.8)',
24 |
25 | mainFont: '#333',
26 | secondaryFont: '#777',
27 | whiteFont: 'white',
28 | link: '#3498db',
29 | blockquoteBorder: '#eee',
30 |
31 | codeInlineBorder: 'rgba(192,201,200,.4)',
32 | codeInlineBackground: 'rgba(192,201,200,.2',
33 |
34 | darkRed: '#b70345',
35 | raspberry: '#E20354',
36 | white: '#ffffff',
37 | gray: '#E0E0E0',
38 | dark: '#424242',
39 |
40 | androidGray: '#f0eef0'
41 | }
42 | }
43 | }
44 |
45 | export const OLD_ANDROID_VERSIONS = ['4.4.4', '4.4.3', '4.4.2', '4.4.1', '4.4', '4.3.1', '4.3', '4.2.2', '4.2.1', '4.2', '4.1.2']
46 |
47 | export const icons = {
48 | 'menu': {icon: 'menu', color: 'black', size: 24},
49 | 'menu-white': {icon: 'menu', color: 'white', size: 24},
50 | 'search': {icon: 'search', color: 'black', size: 24},
51 | 'search-white': {icon: 'search', color: 'white', size: 24},
52 | 'more-vert': {icon: 'more-vert', color: 'white', size: 24},
53 | 'info-outline': {icon: 'info-outline', color: 'white', size: 24},
54 | 'back': {icon: iOS ? 'chevron-left' : 'arrow-back', color: 'white', size: 24},
55 | 'forward': iOS ? {icon: 'chevron-right', color: 'white', size: 40} : {icon: 'arrow-forward', color: 'white', size: 24},
56 | 'expand-more': {icon: 'expand-more', color: 'white', size: 24},
57 | 'checkmark': {icon: 'check', color: 'white', size: 24},
58 | 'browser': {icon: 'open-in-browser', color: 'white', size: 24},
59 | 'closeIcon': {icon: 'close', color: 'white', size: 24}
60 | }
61 |
--------------------------------------------------------------------------------
/ios/gittermobile/AppDelegate.m:
--------------------------------------------------------------------------------
1 | #import "AppDelegate.h"
2 | #import
3 |
4 | // **********************************************
5 | // *** DON'T MISS: THE NEXT LINE IS IMPORTANT ***
6 | // **********************************************
7 | #import "RCCManager.h"
8 |
9 | // IMPORTANT: if you're getting an Xcode error that RCCManager.h isn't found, you've probably ran "npm install"
10 | // with npm ver 2. You'll need to "npm install" with npm 3 (see https://github.com/wix/react-native-navigation/issues/1)
11 |
12 | #import
13 |
14 | @implementation AppDelegate
15 |
16 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
17 | {
18 | NSURL *jsCodeLocation;
19 | #ifdef DEBUG
20 | // jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"];
21 | jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
22 | #else
23 | jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
24 | #endif
25 |
26 |
27 | // **********************************************
28 | // *** DON'T MISS: THIS IS HOW WE BOOTSTRAP *****
29 | // **********************************************
30 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
31 | self.window.backgroundColor = [UIColor whiteColor];
32 | [[RCCManager sharedInstance] initBridgeWithBundleURL:jsCodeLocation];
33 |
34 | /*
35 | // original RN bootstrap - remove this part
36 | RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
37 | moduleName:@"example"
38 | initialProperties:nil
39 | launchOptions:launchOptions];
40 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
41 | UIViewController *rootViewController = [UIViewController new];
42 | rootViewController.view = rootView;
43 | self.window.rootViewController = rootViewController;
44 | [self.window makeKeyAndVisible];
45 | */
46 |
47 |
48 | return YES;
49 | }
50 |
51 | @end
52 |
--------------------------------------------------------------------------------
/app/screens/Drawer/ChannelListItem/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {View, Text} from 'react-native';
4 | import s from './styles'
5 |
6 | import Avatar from '../../../components/Avatar'
7 | import UnreadBadge from '../../../components/UnreadBadge'
8 | import Button from '../../../components/Button'
9 |
10 | import {createGhAvatarLink} from '../../../utils/links'
11 | import {THEMES} from '../../../constants'
12 | const {colors} = THEMES.gitterDefault
13 |
14 | const ChannelListItem = ({
15 | id, name, oneToOne, user, activeRoom, onRoomPress,
16 | unreadItems, mentions, lurk, onLongRoomPress
17 | }) => {
18 | const src = oneToOne
19 | ? createGhAvatarLink(user.username, 200)
20 | : createGhAvatarLink(name.split('/')[0], 200)
21 |
22 | const itemStyles = activeRoom === id
23 | ? {backgroundColor: colors.androidGray, color: colors.raspberry}
24 | : {backgroundColor: colors.white}
25 |
26 | return (
27 | onRoomPress(id)}
29 | onLongPress={() => onLongRoomPress(id)}
30 | style={[s.container,
31 | {backgroundColor: itemStyles.backgroundColor}
32 | ]}
33 | key={id}>
34 |
35 |
38 |
39 |
40 |
44 | {name}
45 |
46 |
47 | {(!!unreadItems || !!mentions || !!lurk) &&
48 | }
52 |
53 |
54 |
55 | )
56 | }
57 |
58 | ChannelListItem.propTypes = {
59 | // id: PropTypes.stings,
60 | onLongRoomPress: PropTypes.func,
61 | name: PropTypes.string,
62 | oneToOne: PropTypes.bool,
63 | user: PropTypes.object,
64 | activeRoom: PropTypes.string,
65 | onRoomPress: PropTypes.func,
66 | unreadItems: PropTypes.number,
67 | mentions: PropTypes.number,
68 | lurk: PropTypes.bool
69 | }
70 |
71 | export default ChannelListItem
72 |
--------------------------------------------------------------------------------
/ios/gittermobile/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UIViewControllerBasedStatusBarAppearance
6 |
7 | CFBundleDevelopmentRegion
8 | en
9 | CFBundleDisplayName
10 | GitterMobile
11 | CFBundleExecutable
12 | $(EXECUTABLE_NAME)
13 | CFBundleIdentifier
14 | $(PRODUCT_BUNDLE_IDENTIFIER)
15 | CFBundleInfoDictionaryVersion
16 | 6.0
17 | CFBundleName
18 | $(PRODUCT_NAME)
19 | CFBundlePackageType
20 | APPL
21 | CFBundleShortVersionString
22 | 1.0
23 | CFBundleSignature
24 | ????
25 | CFBundleVersion
26 | 1
27 | LSRequiresIPhoneOS
28 |
29 | NSAppTransportSecurity
30 |
31 | NSExceptionDomains
32 |
33 | localhost
34 |
35 | NSExceptionAllowsInsecureHTTPLoads
36 |
37 |
38 |
39 |
40 | NSLocationWhenInUseUsageDescription
41 |
42 | UIAppFonts
43 |
44 | Entypo.ttf
45 | Evillicons.ttf
46 | FontAwesome.ttf
47 | Foundation.ttf
48 | Ionicons.ttf
49 | MaterialIcons.ttf
50 | Octicons.ttf
51 | Zocia.ttf
52 | EvilIcons.ttf
53 | MaterialCommunityIcons.ttf
54 | SimpleLineIcons.ttf
55 | Zocial.ttf
56 |
57 | UILaunchStoryboardName
58 | LaunchScreen
59 | UIRequiredDeviceCapabilities
60 |
61 | armv7
62 |
63 | UISupportedInterfaceOrientations
64 |
65 | UIInterfaceOrientationPortrait
66 | UIInterfaceOrientationLandscapeLeft
67 | UIInterfaceOrientationLandscapeRight
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/ios/Pods/MZFayeClient/MZFayeClient/MZFayeMessage.h:
--------------------------------------------------------------------------------
1 | //
2 | // MZFayeMessage.h
3 | // MZFayeClient
4 | //
5 | // Created by Michał Zaborowski on 12.12.2013.
6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy
9 | // of this software and associated documentation files (the "Software"), to deal
10 | // in the Software without restriction, including without limitation the rights
11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | // copies of the Software, and to permit persons to whom the Software is
13 | // furnished to do so, subject to the following conditions:
14 | //
15 | // The above copyright notice and this permission notice shall be included in
16 | // all copies or substantial portions of the Software.
17 | //
18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 | // THE SOFTWARE.
25 |
26 | #import
27 |
28 | @interface MZFayeMessage : NSObject
29 |
30 | @property (nonatomic, strong) NSString *Id;
31 | @property (nonatomic, strong) NSString *channel;
32 | @property (nonatomic, strong) NSString *clientId;
33 | @property (nonatomic, strong) NSNumber *successful;
34 | @property (nonatomic, strong) NSNumber *authSuccessful;
35 | @property (nonatomic, strong) NSString *version;
36 | @property (nonatomic, strong) NSString *minimumVersion;
37 | @property (nonatomic, strong) NSArray *supportedConnectionTypes;
38 | @property (nonatomic, strong) NSDictionary *advice;
39 | @property (nonatomic, strong) NSString *error;
40 | @property (nonatomic, strong) NSString *subscription;
41 | @property (nonatomic, strong) NSDate *timestamp;
42 | @property (nonatomic, strong) NSDictionary *data;
43 | @property (nonatomic, strong) NSDictionary *ext;
44 |
45 | + (instancetype)messageFromDictionary:(NSDictionary *)dictionary;
46 |
47 | @end
48 |
--------------------------------------------------------------------------------
/app/screens/RoomInfo/Activity/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React, { Component } from 'react'
3 | import {View, Text} from 'react-native';
4 | import s from './styles'
5 | import ParsedText from '../../../components/ParsedText'
6 | import Heading from '../../../components/Heading'
7 | import Divider from '../../../components/Divider'
8 |
9 | import moment from 'moment'
10 |
11 | class Activity extends Component {
12 | constructor(props) {
13 | super(props)
14 |
15 | this.renderItem = this.renderItem.bind(this)
16 | this.renderList = this.renderList.bind(this)
17 | }
18 |
19 | renderList() {
20 | const {data} = this.props
21 | const lastIndex = data.length - 1
22 | return (
23 |
24 | {data.map((item, index) => {
25 | const bottom = lastIndex !== index
26 | return this.renderItem(item, bottom)
27 | })}
28 |
29 | )
30 | }
31 |
32 | renderItem(item, bottom) {
33 | const {onUrlPress} = this.props
34 | return (
35 |
36 |
37 | onUrlPress(url)} />
41 | {this.renderDate(item.sent)}
42 |
43 | {bottom && }
44 |
45 | )
46 | }
47 |
48 | renderDate(sent) {
49 | const now = moment()
50 | const date = moment(sent)
51 | if (now.year() > date.year()) {
52 | return date.format('YYYY MMM D HH:mm')
53 | }
54 |
55 | if (now.diff(date, 'hours') > 24) {
56 | return date.format('MMM D HH:mm')
57 | }
58 |
59 | return date.format('HH:mm')
60 | }
61 |
62 | render() {
63 | const {data} = this.props
64 | if (!data) {
65 | return null
66 | }
67 |
68 | return (
69 |
70 |
72 | {data.length === 0
73 | ? Nothing to display
74 | : this.renderList()
75 | }
76 |
77 | )
78 | }
79 | }
80 |
81 | Activity.propTypes = {
82 | data: PropTypes.array,
83 | onUrlPress: PropTypes.func
84 | }
85 |
86 | export default Activity
87 |
--------------------------------------------------------------------------------
/libs/react-native-android-bottom-sheet/src/main/java/com/terrysahaidak/bottomsheet/AndroidBottomSheet.java:
--------------------------------------------------------------------------------
1 | package com.terrysahaidak.bottomsheet;
2 |
3 | import android.app.Activity;
4 | import android.content.DialogInterface;
5 | import android.content.Intent;
6 |
7 | import com.cocosw.bottomsheet.BottomSheet;
8 | import com.facebook.react.bridge.Callback;
9 | import com.facebook.react.bridge.ReactApplicationContext;
10 | import com.facebook.react.bridge.ReactContextBaseJavaModule;
11 | import com.facebook.react.bridge.ReactMethod;
12 | import com.facebook.react.bridge.ReadableArray;
13 | import com.facebook.react.bridge.ReadableMap;
14 |
15 | class AndroidBottomSheet extends ReactContextBaseJavaModule {
16 |
17 | public AndroidBottomSheet(ReactApplicationContext reactContext) {
18 | super(reactContext);
19 | }
20 |
21 | @Override
22 | public String getName() {
23 | return "AndroidBottomSheet";
24 | }
25 |
26 | @ReactMethod
27 | public void showBotttomSheetWithOptions(ReadableMap options, final Callback onSelect) {
28 | final ReadableArray itemsArray = options.getArray("items");
29 | final String title = options.getString("title");
30 |
31 | BottomSheet.Builder builder = new BottomSheet.Builder(getCurrentActivity()).title(title);
32 |
33 | // create options
34 | Integer size = itemsArray.size();
35 | for (int i = 0; i < size; i++) {
36 | builder.sheet(i, itemsArray.getString(i));
37 | }
38 |
39 | builder.listener(new DialogInterface.OnClickListener() {
40 | @Override
41 | public void onClick(DialogInterface dialog, int which) {
42 | onSelect.invoke(which, itemsArray.getString(which));
43 | }
44 | });
45 |
46 | builder.build().show();
47 | }
48 |
49 | @ReactMethod
50 | public void showShareActionSheetWithOptions(ReadableMap options, Callback failureCallback, Callback successCallback) {
51 | String url = options.getString("url");
52 | String message = options.getString("message");
53 |
54 | BottomSheet.Builder builder = new BottomSheet.Builder(getCurrentActivity());
55 | final Intent shareIntent = new Intent(Intent.ACTION_SEND);
56 |
57 | failureCallback.invoke("not support this method");
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/app/screens/LoginByWebView/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React, { Component } from 'react'
3 | import {
4 | WebView,
5 | View
6 | } from 'react-native'
7 | import {connect} from 'react-redux'
8 |
9 | import LoadingOverlay from '../../components/LoadingOverlay'
10 |
11 | import {THEMES} from '../../constants'
12 | const {colors} = THEMES.gitterDefault
13 |
14 | import s from './styles'
15 | import {loginByToken} from '../../modules/auth'
16 | import {gitterLoginUrl} from '../../api/gitter'
17 |
18 | class LoginByWebView extends Component {
19 | constructor(props) {
20 | super(props)
21 |
22 | this.handleNavigationStateChange = this.handleNavigationStateChange.bind(this)
23 |
24 | this.state = {
25 | url: '',
26 | loading: false
27 | }
28 | }
29 |
30 |
31 | handleNavigationStateChange(state) {
32 | if (state.url !== this.state.url) {
33 | if (state.url.indexOf('gittermobile://code') !== -1 &&
34 | state.url.indexOf('https://gitter.im') === -1) {
35 | const {dispatch} = this.props
36 | const code = state.url.split('gittermobile://code?code=')[1]
37 | this.setState({url: state.url, loading: true})
38 | dispatch(loginByToken({code}))
39 | } else {
40 | this.setState({url: state.url})
41 | }
42 | }
43 | }
44 |
45 | renderLoading() {
46 | return (
47 |
48 | )
49 | }
50 |
51 | render() {
52 | const {loading} = this.state
53 | return (
54 |
55 |
62 | {loading && this.renderLoading()}
63 |
64 | )
65 | }
66 | }
67 |
68 | LoginByWebView.propTypes = {
69 | dispatch: PropTypes.func
70 | }
71 |
72 | LoginByWebView.navigatorStyle = {
73 | navBarBackgroundColor: colors.raspberry,
74 | navBarButtonColor: 'white',
75 | navBarTextColor: 'white',
76 | topBarElevationShadowEnabled: true,
77 | statusBarColor: colors.darkRed,
78 | statusBarTextColorScheme: 'dark'
79 | }
80 |
81 | export default connect()(LoginByWebView)
82 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "GitterMobile",
3 | "version": "0.6.0-beta-2",
4 | "description": "Gitter client for mobile devices.",
5 | "author": "Terry Sahaidak (http://sahaidak.com)",
6 | "repository": {
7 | "type": "git",
8 | "url": "git+https://github.com/terrysahaidak/GitterMobile.git"
9 | },
10 | "bugs": {
11 | "url": "https://github.com/terrysahaidak/GitterMobile/issues"
12 | },
13 | "homepage": "https://github.com/terrysahaidak/GitterMobile#readme",
14 | "private": true,
15 | "scripts": {
16 | "start": "node node_modules/react-native/local-cli/cli.js start",
17 | "test": "jest",
18 | "android:check": "adb devices && adb reverse tcp:8081 tcp:8081",
19 | "android": "node node_modules/react-native/local-cli/cli.js run-android",
20 | "lint": "node node_modules/eslint/bin/eslint -c .eslintrc ./",
21 | "release": "cd android && ./gradlew assembleRelease",
22 | "android-release": "node node_modules/react-native/local-cli/cli.js run-android --variant=release"
23 | },
24 | "dependencies": {
25 | "lodash": "^4.2.1",
26 | "moment": "^2.11.2",
27 | "prop-types": "^15.5.10",
28 | "react": "16.0.0-alpha.6",
29 | "react-native": "^0.44.3",
30 | "react-native-device-info": "^0.10.2",
31 | "react-native-dialogs": "0.0.19",
32 | "react-native-drawer-layout": "^1.3.0",
33 | "react-native-fetch-blob": "^0.10.6",
34 | "react-native-invertible-scroll-view": "^1.0.0",
35 | "react-native-navigation": "^1.1.125",
36 | "react-native-parsed-text": "0.0.16",
37 | "react-native-scrollable-tab-view": "^0.6.7",
38 | "react-native-share": "^1.0.16",
39 | "react-native-transformable-image": "github:terrysahaidak/react-native-transformable-image",
40 | "react-native-vector-icons": "^4.0.1",
41 | "react-redux": "^5.0.3",
42 | "redux": "^3.2.1",
43 | "redux-logger": "^3.0.1",
44 | "redux-thunk": "^1.0.3",
45 | "remote-redux-devtools": "^0.1.1"
46 | },
47 | "devDependencies": {
48 | "babel-jest": "19.0.0",
49 | "babel-preset-react-native": "1.9.1",
50 | "jest": "19.0.2",
51 | "react-test-renderer": "16.0.0-alpha.6",
52 | "eslint": "~1.10.3",
53 | "eslint-config-airbnb": "~2.1.1",
54 | "eslint-plugin-react": "~3.13.1",
55 | "babel-eslint": "~4.1.6"
56 | },
57 | "jest": {
58 | "preset": "react-native"
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/ios/gittermobileTests/gittermobileTests.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
3 | * All rights reserved.
4 | *
5 | * This source code is licensed under the BSD-style license found in the
6 | * LICENSE file in the root directory of this source tree. An additional grant
7 | * of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 | #import
12 |
13 | #import
14 | #import
15 |
16 | #define TIMEOUT_SECONDS 600
17 | #define TEXT_TO_LOOK_FOR @"Welcome to React Native!"
18 |
19 | @interface GitterMobileTests : XCTestCase
20 |
21 | @end
22 |
23 | @implementation GitterMobileTests
24 |
25 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test
26 | {
27 | if (test(view)) {
28 | return YES;
29 | }
30 | for (UIView *subview in [view subviews]) {
31 | if ([self findSubviewInView:subview matching:test]) {
32 | return YES;
33 | }
34 | }
35 | return NO;
36 | }
37 |
38 | - (void)testRendersWelcomeScreen
39 | {
40 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController];
41 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
42 | BOOL foundElement = NO;
43 |
44 | __block NSString *redboxError = nil;
45 | RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
46 | if (level >= RCTLogLevelError) {
47 | redboxError = message;
48 | }
49 | });
50 |
51 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {
52 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
53 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
54 |
55 | foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) {
56 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {
57 | return YES;
58 | }
59 | return NO;
60 | }];
61 | }
62 |
63 | RCTSetLogFunction(RCTDefaultLogFunction);
64 |
65 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError);
66 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);
67 | }
68 |
69 |
70 | @end
71 |
--------------------------------------------------------------------------------
/app/components/ScrollToTop/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React, { Component } from 'react'
3 | import {
4 | TouchableOpacity,
5 | Animated
6 | } from 'react-native'
7 | import s from './styles'
8 | import Icon from 'react-native-vector-icons/MaterialIcons'
9 |
10 | class ScrollToTop extends Component {
11 | constructor(props) {
12 | super(props)
13 |
14 | this.state = {
15 | bottom: new Animated.Value(-54)
16 | }
17 | }
18 |
19 | componentWillReceiveProps(nextProps) {
20 | if (this.props.visible !== nextProps.visible) {
21 | Animated.timing(
22 | this.state.bottom,
23 | {
24 | toValue: nextProps.visible ? 0 : -54,
25 | duration: 200
26 | },
27 | ).start()
28 | }
29 | }
30 |
31 | _onPress() {
32 | this.props.root.refs.listview.scrollTo({x: 0, y: 0, animated: true});
33 | }
34 |
35 | render() {
36 | const {
37 | isRadius,
38 | borderRadius,
39 | backgroundColor,
40 | width,
41 | height,
42 | right,
43 | bottom,
44 | icon,
45 | iconSize
46 | } = this.props
47 |
48 | return (
49 |
51 |
61 |
65 |
66 |
67 | );
68 | }
69 | }
70 |
71 | ScrollToTop.defaultProps = {
72 | isRadius: true,
73 | width: 60,
74 | height: 60,
75 | borderRadius: 30,
76 | backgroundColor: 'white'
77 | }
78 |
79 | ScrollToTop.propTypes = {
80 | isRadius: PropTypes.bool,
81 | borderRadius: PropTypes.number,
82 | backgroundColor: PropTypes.string,
83 | width: PropTypes.number,
84 | height: PropTypes.number,
85 | right: PropTypes.number,
86 | children: PropTypes.element,
87 | root: PropTypes.object,
88 | bottom: PropTypes.number,
89 | icon: PropTypes.string,
90 | iconSize: PropTypes.number,
91 | visible: PropTypes.bool
92 | }
93 |
94 | export default ScrollToTop
95 |
--------------------------------------------------------------------------------
/app/screens/Message/Message/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React, { Component } from 'react'
3 | import {TouchableOpacity, Linking, View, Text} from 'react-native';
4 | import s from './styles'
5 | import moment from 'moment'
6 | import ParsedText from '../../../components/ParsedText'
7 |
8 | import Avatar from '../../../components/Avatar'
9 |
10 | class Message extends Component {
11 | constructor(props) {
12 | super(props)
13 |
14 | this.renderMessageText = this.renderMessageText.bind(this)
15 | this.renderDate = this.renderDate.bind(this)
16 | }
17 |
18 | handleUrlPress(url) {
19 | Linking.openURL(url)
20 | }
21 |
22 | renderDate() {
23 | const {sent} = this.props
24 | return moment(sent).format('YYYY MMM D HH:mm')
25 | }
26 |
27 | renderMessageText() {
28 | const {text, username} = this.props
29 |
30 | if (this.props.hasOwnProperty('editedAt') && !text) {
31 | return (
32 |
33 | This message was deleted
34 |
35 | )
36 | }
37 | return (
38 |
42 | )
43 | }
44 |
45 | render() {
46 | const {fromUser, onAvatarPress} = this.props
47 |
48 | return (
49 |
50 | onAvatarPress(fromUser.id, fromUser.username)}>
52 |
53 |
54 |
55 |
56 |
58 | {fromUser.username}
59 |
60 |
61 | {this.renderDate()}
62 |
63 |
64 |
65 | {this.renderMessageText()}
66 |
67 |
68 |
69 | )
70 | }
71 | }
72 |
73 | Message.propTypes = {
74 | id: PropTypes.string,
75 | text: PropTypes.string,
76 | sent: PropTypes.string,
77 | fromUser: PropTypes.object,
78 | dispatch: PropTypes.func,
79 | onAvatarPress: PropTypes.func,
80 | username: PropTypes.string,
81 | status: PropTypes.bool
82 | }
83 |
84 | export default Message
85 |
--------------------------------------------------------------------------------
/app/screens/RoomInfo/RoomUsers/index.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types'
2 | import React from 'react'
3 | import {View, Text, TouchableOpacity} from 'react-native';
4 | import s from './styles'
5 |
6 | import Avatar from '../../../components/Avatar'
7 | import Heading from '../../../components/Heading'
8 | import Button from '../../../components/Button'
9 |
10 | const RoomUsers = ({ids, entities, onPress, userCount, onAllUsersPress, onAddPress, oneToOne}) => {
11 | const displayUserHeader = oneToOne === true ? 'People' : `People (${userCount})`
12 | let content = []
13 |
14 | if (ids.length >= 30) {
15 | for (let i = 0; i < 30; i++) {
16 | const id = ids[i]
17 | content.push(
18 | onPress(id, entities[id].username)}
20 | key={id}>
21 |
24 |
27 |
28 |
29 | )
30 | }
31 | } else {
32 | content = ids.map(id => (
33 | onPress(id, entities[id].username)}
35 | key={id}>
36 |
39 |
42 |
43 |
44 | ))
45 | }
46 | return (
47 |
48 |
50 |
51 | {content}
52 |
53 | {!oneToOne && (
54 |
55 | onAddPress()}
57 | style={[s.button, s.primaryButton]}>
58 | Add
59 |
60 | onAllUsersPress()}
62 | style={s.button}>
63 | See all
64 |
65 |
66 | )}
67 |
68 | )
69 | }
70 |
71 | RoomUsers.propTypes = {
72 | ids: PropTypes.array,
73 | entities: PropTypes.object,
74 | onPress: PropTypes.func,
75 | userCount: PropTypes.number,
76 | onAllUsersPress: PropTypes.func,
77 | oneToOne: PropTypes.bool,
78 | onAddPress: PropTypes.func
79 | }
80 |
81 | export default RoomUsers
82 |
--------------------------------------------------------------------------------
/app/modules/ui.js:
--------------------------------------------------------------------------------
1 | import {getItem, setItem, removeItem} from '../utils/storage'
2 |
3 | export const INITIALIZE_UI = 'ui/INITIALIZE_UI'
4 | export const CHANGE_ROOM_INFO_DRAWER_STATE = 'ui/RoomInfo/CHANGE_ROOM_INFO_DRAWER_STATE'
5 | export const TOGGLE_DRAWER_SECTION_STATE = 'ui/TOGGLE_DRAWER_SECTION_STATE'
6 | export const SET_ROOM_INPUT_STATE = 'ui/SET_ROOM_INPUT_STATE'
7 |
8 | export function initializeUi() {
9 | return async dispatch => {
10 | const payload = await getItem('uiReducer')
11 |
12 | dispatch({
13 | type: INITIALIZE_UI,
14 | payload: typeof payload === 'string'
15 | ? JSON.parse(payload)
16 | : payload
17 | })
18 | }
19 | }
20 |
21 | export function toggleDrawerSectionState(sectionName, oldState) {
22 | return async dispatch => {
23 | dispatch({type: TOGGLE_DRAWER_SECTION_STATE, sectionName, newState: !oldState})
24 |
25 | await dispatch(saveReducerToStorage())
26 | }
27 | }
28 |
29 | export function setRoomTextInputState(roomId, text) {
30 | return async dispatch => {
31 | dispatch({type: SET_ROOM_INPUT_STATE, roomId, text})
32 |
33 | await dispatch(saveReducerToStorage())
34 | }
35 | }
36 |
37 | export function changeRoomInfoDrawerState(state) {
38 | return {
39 | type: CHANGE_ROOM_INFO_DRAWER_STATE,
40 | state
41 | }
42 | }
43 |
44 | function saveReducerToStorage() {
45 | return async (dispatch, getState) => {
46 | await setItem('uiReducer', JSON.stringify(getState().ui))
47 | }
48 | }
49 |
50 | const initialState = {
51 | roomInfoDrawerState: 'close',
52 | sectionsState: {
53 | Favorites: false,
54 | Unread: false,
55 | Channels: false,
56 | Organizations: false
57 | },
58 | roomInputStateById: {}
59 | }
60 |
61 | export default function ui(state = initialState, action) {
62 | switch (action.type) {
63 |
64 | case INITIALIZE_UI:
65 | return Object.assign({}, state, action.payload || initialState)
66 |
67 | case CHANGE_ROOM_INFO_DRAWER_STATE:
68 | return {...state,
69 | roomInfoDrawerState: action.state
70 | }
71 |
72 | case TOGGLE_DRAWER_SECTION_STATE:
73 | return {...state,
74 | sectionsState: {...state.sectionsState,
75 | [action.sectionName]: action.newState
76 | }
77 | }
78 |
79 | case SET_ROOM_INPUT_STATE:
80 | return {...state,
81 | roomInputStateById: {...state.roomInputStateById,
82 | [action.roomId]: action.text
83 | }
84 | }
85 |
86 | default:
87 | return state
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/android/app/src/main/java/com/gittermobile/MainApplication.java:
--------------------------------------------------------------------------------
1 | package com.gittermobile;
2 |
3 | import android.app.Application;
4 |
5 | import com.facebook.react.ReactApplication;
6 | import com.RNFetchBlob.RNFetchBlobPackage;
7 | import com.facebook.react.ReactNativeHost;
8 | import com.facebook.react.ReactPackage;
9 | import com.facebook.react.shell.MainReactPackage;
10 | import com.facebook.soloader.SoLoader;
11 |
12 | import java.util.Arrays;
13 | import java.util.List;
14 |
15 | import com.oblador.vectoricons.VectorIconsPackage;
16 | import com.terrysahaidak.faye.FayeGitterPackage;
17 | import com.aakashns.reactnativedialogs.ReactNativeDialogsPackage;
18 | import com.terrysahaidak.bottomsheet.AndroidBottomSheetPackage;
19 | import com.learnium.RNDeviceInfo.RNDeviceInfo;
20 | import cl.json.RNSharePackage;
21 | import com.reactnativenavigation.NavigationApplication;
22 |
23 | // public class MainApplication extends Application implements ReactApplication {
24 | //
25 | // private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
26 | // @Override
27 | // public boolean getUseDeveloperSupport() {
28 | // return BuildConfig.DEBUG;
29 | // }
30 | //
31 | // @Override
32 | // protected List getPackages() {
33 | // return Arrays.asList(
34 | // new MainReactPackage(),
35 | // new RNSharePackage(),
36 | // new VectorIconsPackage(),
37 | // new ReactNativeDialogsPackage(),
38 | // new FayeGitterPackage(),
39 | // new RNDeviceInfo(),
40 | // new AndroidBottomSheetPackage()
41 | // );
42 | // }
43 | // };
44 | //
45 | // @Override
46 | // public ReactNativeHost getReactNativeHost() {
47 | // return mReactNativeHost;
48 | // }
49 | public class MainApplication extends NavigationApplication {
50 | @Override
51 | public boolean isDebug() {
52 | // Make sure you are using BuildConfig from your own application
53 | return BuildConfig.DEBUG;
54 | }
55 |
56 | @Override
57 | public List createAdditionalReactPackages() {
58 | return Arrays.asList(
59 | new RNSharePackage(),
60 | new VectorIconsPackage(),
61 | new ReactNativeDialogsPackage(),
62 | new FayeGitterPackage(),
63 | new RNDeviceInfo(),
64 | new RNFetchBlobPackage(),
65 | new AndroidBottomSheetPackage()
66 | );
67 | }
68 |
69 | @Override
70 | public void onCreate() {
71 | super.onCreate();
72 | SoLoader.init(this, /* native exopackage */ false);
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/app/modules/roomInfo.js:
--------------------------------------------------------------------------------
1 | import * as Api from '../api/gitter'
2 | import {subscribeToRoomEvents} from './realtime'
3 |
4 | export const REPO_INFO = 'roomInfo/REPO_INFO'
5 | export const REPO_INFO_OK = 'roomInfo/REPO_INFO_OK'
6 | export const REPO_INFO_ERROR = 'roomInfo/REPO_INFO_ERROR'
7 | export const ROOM_INFO = 'roomInfo/ROOM_INFO'
8 | export const CLEAR_ERROR = 'roomInfo/CLEAR_ERROR'
9 |
10 | export function getRoomInfo(repoName, roomId) {
11 | return async (dispatch, getState) => {
12 | const {token} = getState().auth
13 | const room = getState().rooms.rooms[roomId]
14 |
15 | if (room.githubType !== 'ONETOONE') {
16 | dispatch(subscribeToRoomEvents(roomId))
17 | }
18 |
19 | if (room.githubType !== 'REPO') {
20 | dispatch({type: ROOM_INFO, payload: room})
21 | } else {
22 | dispatch({type: REPO_INFO, repoName})
23 |
24 | try {
25 | const res = await Api.getRepoInfo(token, repoName)
26 | const resText = await res.text()
27 |
28 | if (resText.length > 0) {
29 | const payload = JSON.parse(resText)
30 | dispatch({type: REPO_INFO_OK, payload, repoName})
31 | }
32 | } catch (error) {
33 | dispatch({type: REPO_INFO_ERROR, error})
34 | }
35 | }
36 | }
37 | }
38 |
39 | export function clearRoomInfoError() {
40 | return {
41 | type: CLEAR_ERROR
42 | }
43 | }
44 |
45 | const initialState = {
46 | isFetching: false,
47 | ids: [],
48 | entities: {},
49 | isError: false,
50 | error: {}
51 | }
52 |
53 | export default function roomInfo(state = initialState, action) {
54 | switch (action.type) {
55 | case REPO_INFO:
56 | return {...state,
57 | isFetching: true
58 | }
59 |
60 | case REPO_INFO_OK: {
61 | const {payload, repoName} = action
62 | return {...state,
63 | isFetching: false,
64 | ids: state.ids.concat(repoName),
65 | entities: {...state.entities,
66 | [repoName]: payload
67 | }
68 | }
69 | }
70 |
71 | case ROOM_INFO:
72 | return {...state,
73 | isFetching: false,
74 | ids: state.ids.concat(action.payload.name),
75 | entities: {...state.entities,
76 | [action.payload.name]: action.payload
77 | }
78 | }
79 |
80 | case CLEAR_ERROR:
81 | return {...state,
82 | isFetching: false,
83 | isError: false,
84 | error: {}
85 | }
86 |
87 | case REPO_INFO_ERROR:
88 | return {...state,
89 | isFetching: false,
90 | isError: true,
91 | error: action.error
92 | }
93 |
94 | default:
95 | return state
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/ios/Pods/MZFayeClient/MZFayeClient/MZFayeMessage.m:
--------------------------------------------------------------------------------
1 | //
2 | // MZFayeMessage.m
3 | // MZFayeClient
4 | //
5 | // Created by Michał Zaborowski on 12.12.2013.
6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy
9 | // of this software and associated documentation files (the "Software"), to deal
10 | // in the Software without restriction, including without limitation the rights
11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | // copies of the Software, and to permit persons to whom the Software is
13 | // furnished to do so, subject to the following conditions:
14 | //
15 | // The above copyright notice and this permission notice shall be included in
16 | // all copies or substantial portions of the Software.
17 | //
18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 | // THE SOFTWARE.
25 |
26 | #import "MZFayeMessage.h"
27 |
28 | @implementation MZFayeMessage
29 |
30 | - (instancetype)initWithDictionary:(NSDictionary *)dictionary
31 | {
32 | self = [super init];
33 | if (self) {
34 | [self importFromDictionary:dictionary];
35 | }
36 | return self;
37 | }
38 |
39 | + (instancetype)messageFromDictionary:(NSDictionary *)dictionary
40 | {
41 | return [[[self class] alloc] initWithDictionary:dictionary];
42 | }
43 |
44 | - (void)importFromDictionary:(NSDictionary *)dictionary
45 | {
46 | if (dictionary[@"id"] != nil) {
47 | self.Id = dictionary[@"id"];
48 | }
49 |
50 | if (dictionary[@"timestamp"] != nil) {
51 | self.timestamp = [NSDate dateWithTimeIntervalSince1970:[dictionary[@"timestamp"] timeInterval]];
52 | }
53 |
54 | NSArray *objectAttributes = @[@"channel", @"clientId", @"successful", @"authSuccessful", @"version", @"minimumVersion", @"supportedConnectionTypes", @"advice", @"error", @"subscription", @"data", @"ext"];
55 | for (NSString *attribute in objectAttributes) {
56 | if (dictionary[attribute] != nil) {
57 | [self setValue:dictionary[attribute] forKey:attribute];
58 | }
59 | }
60 | }
61 |
62 | @end
63 |
--------------------------------------------------------------------------------
/app/screens/ImageLightbox/index.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react'
2 | import PropTypes from 'prop-types'
3 | import {Linking, Image} from 'react-native'
4 | import TransformableImage from 'react-native-transformable-image'
5 | import s from './styles'
6 | import navigationStyles from '../../styles/common/navigationStyles'
7 | import {iconsMap} from '../../utils/iconsMap'
8 |
9 | class ImageLightbox extends Component {
10 | constructor(props) {
11 | super(props)
12 |
13 | this.handleToggleNavbar = this.handleToggleNavbar.bind(this)
14 |
15 | props.navigator.setOnNavigatorEvent(this.onNavigatorEvent.bind(this))
16 | props.navigator.setButtons({
17 | leftButtons: [{
18 | title: 'Close',
19 | id: 'close',
20 | icon: iconsMap.closeIcon,
21 | iconColor: 'white',
22 | showAsAction: 'always'
23 | }],
24 | rightButtons: [{
25 | title: 'Open in Browser',
26 | icon: iconsMap.browser,
27 | id: 'open-in-browser',
28 | iconColor: 'white',
29 | showAsAction: 'always'
30 | }]
31 | })
32 |
33 | this.state = {
34 | pixels: {},
35 | showNavBar: true
36 | }
37 | }
38 |
39 | componentWillMount() {
40 | Image.getSize(this.props.url, (width, height) =>
41 | this.setState({pixels: {width, height}})
42 | )
43 | }
44 |
45 | onNavigatorEvent(event) {
46 | if (event.type === 'NavBarButtonPress') {
47 | if (event.id === 'close') {
48 | this.props.navigator.dismissModal({
49 | animationType: 'slide-down'
50 | })
51 | }
52 | if (event.id === 'open-in-browser') {
53 | Linking.openURL(this.props.url)
54 | }
55 | }
56 | }
57 |
58 | handleToggleNavbar() {
59 | const {showNavBar} = this.state
60 | this.props.navigator.toggleNavBar({
61 | to: showNavBar ? 'hidden' : 'shown',
62 | animated: false
63 | })
64 | this.setState({showNavBar: !showNavBar})
65 | }
66 |
67 | render() {
68 | const {url} = this.props
69 | const {pixels} = this.state
70 |
71 | return (
72 |
80 | )
81 | }
82 | }
83 |
84 | ImageLightbox.navigatorStyle = {
85 | ...navigationStyles,
86 | drawUnderNavBar: true
87 | }
88 |
89 | ImageLightbox.propTypes = {
90 | navigator: PropTypes.object,
91 | url: PropTypes.string
92 | }
93 |
94 | export default ImageLightbox
95 |
--------------------------------------------------------------------------------
/app/screens/index.js:
--------------------------------------------------------------------------------
1 | import {Navigation} from 'react-native-navigation'
2 | import {iconsLoaded} from '../utils/iconsMap'
3 |
4 | import {init} from '../modules/app'
5 |
6 | import Launch from './Launch'
7 | import Login from './Login'
8 | import LoginByToken from './LoginByToken'
9 | import NoInternet from './NoInternet'
10 | import Home from './Home'
11 | import Room from './Room'
12 | import Search from './Search'
13 | import User from './User'
14 | import Drawer from './Drawer'
15 | import RoomUsers from './RoomUsers'
16 | import RoomUserAdd from './RoomUserAdd'
17 | import Message from './Message'
18 | import Settings from './Settings'
19 | import SearchMessages from './SearchMessages'
20 | import RoomInfo from './RoomInfo'
21 | import RoomSettings from './RoomSettings'
22 | import LoginByWebView from './LoginByWebView'
23 | import ImageLightbox from './ImageLightbox'
24 |
25 | export default class Application {
26 | constructor(store, Provider) {
27 | this._store = store
28 | this._provider = Provider
29 | this._iconsLoaded = false
30 |
31 | this._configureScreens(store, Provider)
32 | }
33 |
34 | _configureScreens(store, Provider) {
35 | const screens = {
36 | Launch,
37 | Login,
38 | LoginByToken,
39 | NoInternet,
40 | Home,
41 | Room,
42 | Search,
43 | User,
44 | Drawer,
45 | RoomUsers,
46 | RoomUserAdd,
47 | RoomInfo,
48 | Message,
49 | Settings,
50 | SearchMessages,
51 | RoomSettings,
52 | LoginByWebView,
53 | ImageLightbox
54 | }
55 |
56 | Object.keys(screens).map(key => {
57 | Navigation.registerComponent(`gm.${key}`, () => screens[key], store, Provider)
58 | })
59 | }
60 |
61 | run() {
62 | this._store.dispatch(init())
63 | }
64 |
65 | startAppWithScreen(opts) {
66 | if (this._iconsLoaded) {
67 | this.startApp(opts)
68 | } else {
69 | iconsLoaded
70 | .then(() => {
71 | this._iconsLoaded = true
72 | this.startApp(opts)
73 | }).catch(error => {
74 | console.error(error) // eslint-disable-line
75 | })
76 | }
77 | }
78 |
79 | startApp({screen, passProps, showDrawer = false}) {
80 | const app = {
81 | screen: {
82 | screen,
83 | passProps,
84 | navigatorStyle: {
85 | tabBarHidden: true,
86 | drawUnderTabBar: true,
87 | disabledBackGesture: true
88 | }
89 | }
90 | }
91 |
92 | Navigation.startSingleScreenApp(Object.assign(
93 | app,
94 | showDrawer ? {drawer: {left: {screen: 'gm.Drawer'}}} : {}
95 | ))
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/app/modules/navigation.js:
--------------------------------------------------------------------------------
1 | import {nav} from '../screens'
2 |
3 | const NAVIGATE_TO = 'navigation/NAVIGATE_TO'
4 | const NAVIGATE_BACK = 'navigation/NAVIGATE_BACK'
5 | const NAVIGATE_REPLACE = 'navigation/NAVIGATE_REPLACE'
6 | const NAVIGATE_RESET = 'navigation/NAVIGATE_RESET'
7 | const NAVIGATE_RESET_WITH_STACK = 'navigation/NAVIGATE_RESET_WITH_STACK'
8 |
9 | export function goTo(route) {
10 | return dispatch => {
11 | dispatch({type: NAVIGATE_TO, route})
12 | nav.push(route)
13 | }
14 | }
15 |
16 | export function goBack() {
17 | return dispatch => {
18 | dispatch({type: NAVIGATE_BACK})
19 | nav.pop()
20 | }
21 | }
22 |
23 | export function goAndReplace(route) {
24 | return dispatch => {
25 | dispatch({type: NAVIGATE_REPLACE, route})
26 | nav.replace(route)
27 | }
28 | }
29 |
30 | export function resetTo(route) {
31 | return dispatch => {
32 | dispatch({type: NAVIGATE_RESET, route})
33 | nav.resetTo(route)
34 | }
35 | }
36 |
37 | export function resetWithStack(stack) {
38 | return dispatch => {
39 | dispatch({type: NAVIGATE_RESET_WITH_STACK, stack})
40 | nav.immediatelyResetRouteStack(stack)
41 | }
42 | }
43 |
44 | const initialState = {
45 | init: {name: 'launch'},
46 | current: {},
47 | prevision: {},
48 | history: []
49 | }
50 |
51 | export default function navigation(state = initialState, action) {
52 | switch (action.type) {
53 | case NAVIGATE_TO:
54 | return {...state,
55 | current: action.route,
56 | prevision: state.current,
57 | history: state.history.concat(action.route)
58 | }
59 |
60 | case NAVIGATE_BACK: {
61 | const {history} = state
62 | const newHistory = [].concat(history)
63 | newHistory.pop()
64 | return {...state,
65 | current: state.prevision,
66 | prevision: newHistory.length >= 2 ? newHistory[newHistory.length - 2] : {},
67 | history: newHistory
68 | }
69 | }
70 |
71 | case NAVIGATE_RESET:
72 | return {...state,
73 | current: action.route,
74 | prevision: {},
75 | history: [].concat(action.route)
76 | }
77 |
78 | case NAVIGATE_REPLACE: {
79 | const newHistory = [].concat(state.history)
80 | newHistory[state.history.length - 1] = action.route
81 | return {...state,
82 | current: action.route,
83 | history: newHistory
84 | }
85 | }
86 |
87 | case NAVIGATE_RESET_WITH_STACK:
88 | return {...state,
89 | current: action.stack[action.stack.length - 1],
90 | prevision: action.stack.length === 1 ? {} : action.stack[action.stack.length - 2],
91 | history: action.stack
92 | }
93 |
94 | default:
95 | return state
96 | }
97 | }
98 |
--------------------------------------------------------------------------------