Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: early web support #35

Merged
merged 21 commits into from
Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions .github/workflows/build.yml → .github/workflows/build-android.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
name: Build RVMob (debug)
name: Build RVMob for Android (debug)

on:
push:

jobs:
# build-win:
# build-android-debug-win:
# runs-on: windows-latest
# steps:
# - name: Checkout Repository
Expand All @@ -19,22 +19,22 @@ jobs:
# with:
# java-version: '11'
# distribution: 'microsoft'
# - name: Install and prepare dependencies
# run: yarn install && npx rn-nodeify -e
# - name: Install dependencies
# run: yarn install
# - name: Build the app
# run: npx react-native build-android --mode debug
# - name: Upload debug APK
# uses: actions/upload-artifact@v3
# with:
# path: D:\a\rvmob\rvmob\android\app\build\outputs\apk\debug\app-debug.apk
# name: RVMob-Debug-${{ github.sha }}.apk
build-linux:
build-android-debug-linux:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: Set up Node
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: 18
cache: 'yarn'
Expand All @@ -43,12 +43,12 @@ jobs:
with:
java-version: '17'
distribution: 'microsoft'
- name: Install and prepare dependencies
run: yarn install && npx rn-nodeify -e && npx react-native-asset
- name: Install dependencies and prepare assets
run: yarn install && npx react-native-asset
- name: Bundle the JS
run: npx react-native bundle --platform android --entry-file ./index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res
run: yarn react-native bundle --platform android --entry-file ./index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res
- name: Build the app
run: npx react-native build-android --tasks assembleDebug
run: yarn react-native build-android --tasks assembleDebug
- name: Rename debug APKs
run: |
mv app-arm64-v8a-debug.apk RVMob-Debug-${{ github.sha }}-arm64-v8a.apk
Expand Down
49 changes: 49 additions & 0 deletions .github/workflows/build-web.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Build and deploy RVMob for web

on:
push:
branches: ["main", "master"] # TODO: clean up after switching

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write

# Allow only one concurrent run, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: "pages"
cancel-in-progress: false

jobs:
build-and-deploy-web:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: 18
cache: "yarn"
- name: Install dependencies
run: yarn install
- name: Build the site
run: yarn web-release
- name: Set up Pages
uses: actions/configure-pages@v3
- name: Upload artifact
uses: actions/upload-pages-artifact@v1
with:
# Upload built files
path: './dist'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v2
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,7 @@ yarn-error.log
.metro-health-check*

# Testing
/coverage
/coverage

# Webpack
dist
52 changes: 35 additions & 17 deletions App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -348,23 +348,41 @@ class MainView extends React.Component {
<View style={styles.app}>
{this.state.status === 'loggedIn' ? (
<>
<SideMenuBase
openMenuOffset={Dimensions.get('window').width - 50}
overlayColor={'#00000040'}
edgeHitWidth={Dimensions.get('window').width}
isOpen={this.state.leftMenuOpen}
onChange={open => this.setState({leftMenuOpen: open})}
menu={
<SideMenu
onChannelClick={this.setChannel.bind(this)}
currentChannel={this.state.currentChannel}
orderedServers={this.state.orderedServers}
/>
}
style={styles.app}
bounceBackOnOverdraw={false}>
<ChannelView state={this} channel={this.state.currentChannel} />
</SideMenuBase>
{Dimensions.get('window').width >
Dimensions.get('window').height ? (
<View style={{flex: 1, flexDirection: 'row'}}>
<View
style={{
width: '20%',
flexDirection: 'column',
}}>
<SideMenu
onChannelClick={this.setChannel.bind(this)}
currentChannel={this.state.currentChannel}
orderedServers={this.state.orderedServers}
/>
</View>
<ChannelView state={this} channel={this.state.currentChannel} />
</View>
) : (
<SideMenuBase
openMenuOffset={Dimensions.get('window').width - 50}
overlayColor={'#00000040'}
edgeHitWidth={Dimensions.get('window').width}
isOpen={this.state.leftMenuOpen}
onChange={open => this.setState({leftMenuOpen: open})}
menu={
<SideMenu
onChannelClick={this.setChannel.bind(this)}
currentChannel={this.state.currentChannel}
orderedServers={this.state.orderedServers}
/>
}
style={styles.app}
bounceBackOnOverdraw={false}>
<ChannelView state={this} channel={this.state.currentChannel} />
</SideMenuBase>
)}
<Modals />
<NetworkIndicator client={client} />
<View
Expand Down
31 changes: 20 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,29 @@
</a>
</div>

**RVMob** is a mobile Revolt client made in React Native.
**RVMob** is a Revolt client made with React Native. It is currently available for Android and will be available for web in the future.

**Please note that RVMob is currently in beta.** It is exclusive to Android and contains several bugs/incomplete features - use at your own discretion.
**Please note that RVMob is currently in beta.** It contains several bugs and incomplete features - use at your own discretion.

For development updates and other news, join [RVMob's support server][support-server].

## Installing

If you want to install RVMob, simply go to [the releases tab](https://github.com/revoltchat/rvmob/releases) and download the latest version. We plan on publishing RVMob to app stores in the future.
If you want to install RVMob for Android, simply go to [the releases tab](https://github.com/revoltchat/rvmob/releases) and download the latest version. We plan on publishing RVMob to app stores in the future.

<!-- You can try RVMob for web [here](). Note that, as the web version is still under development, some features are only available on Android or may not work as smoothly. You may also see some layout issues. -->

Debug builds are also produced for every commit. These are unoptimised - they're much larger and noticeably slower than the release builds, but you can try out new features early.

### Info about split builds

Also note that, from v0.7.0, RVMob's APKs are **split by architecture**. This helps to reduce file and app sizes - however, you'll need to make sure that you **download the APK that matches your device's architecture**, or **it won't install!**

If you're using an app store, this should be handled for you. If not, however, you'll need to check your device's architecture. I'd recommend using [Treble Info](https://gitlab.com/TrebleInfo/TrebleInfo/-/blob/dev/README.md) for this. Install and open the app - **don't worry about what it says on the home page!** - then open the Details tab and check the CPU architecture entry.
**If you're using an app store, this should be handled for you.**

If not, however, you'll need to check your device's architecture. I'd recommend using [Treble Info](https://gitlab.com/TrebleInfo/TrebleInfo/-/blob/dev/README.md) for this.

Depending on what it says:
Install and open the app - **don't worry about what it says on the home page!** - then open the Details tab and check the CPU architecture entry. Depending on what it says:

- if it says `ARM64`, you'll want the APK with **`arm64-v8a`** in its file name;
- if it says `ARM32`, you'll want the APK with **`armeabi-v7a`** in its file name;
Expand All @@ -38,21 +42,25 @@ If it says `Unknown`, please ask for help in [our support server][support-server

## Building

If you want to build RVMob, you'll need:
If you want to build RVMob for web, you'll need:

- [Node](https://nodejs.org/en/) (v18+) and
- [Yarn Classic](https://classic.yarnpkg.com).

If you want to build RVMob for Android, you'll also need:

- [Node](https://nodejs.org/en/) (v18+),
- [Yarn Classic](https://classic.yarnpkg.com),
- JDK 17 ([Microsoft's build](https://learn.microsoft.com/en-gb/java/openjdk/download) works well),
- the latest Android SDK (preferably via [Android Studio](https://developer.android.com/studio)'s SDK Manager), and
- [npx](https://www.npmjs.com/package/npx).

Then run the following:

```sh
yarn install
npx rn-nodeify -e
npx react-native-asset
yarn android # for the android app
# for web:
yarn web
# for android:
yarn android
yarn start
```

Expand All @@ -62,6 +70,7 @@ CLI commands:
| -------------- | ----------------------------------------- |
| `yarn start` | Starts Metro (the dev server). |
| `yarn test` | Tests to see if everything is working. |
| `yarn web` | Runs the web app. |
| `yarn android` | Runs the Android app. |
| `yarn ios` | Runs the iOS app (broken/requires a Mac). |
| `yarn lint` | Checks the code syntax using ESLint. |
Expand Down
15 changes: 3 additions & 12 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const {mobilePlugins} = require('./config/babel-shared');

module.exports = {
presets: ['module:@react-native/babel-preset'],
env: {
Expand All @@ -12,16 +14,5 @@ module.exports = {
],
},
},
plugins: [
[
'module-resolver',
{
alias: {
'@rvmob': './src',
'@rvmob-i18n': './i18n',
},
},
],
'react-native-reanimated/plugin',
],
plugins: mobilePlugins,
};
33 changes: 33 additions & 0 deletions config/babel-shared.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const regularAlias = {
'@rvmob': './src',
'@rvmob-i18n': './i18n',
};

const webAlias = {
...regularAlias,
'^react-native$': 'react-native-web',
};

const commonPlugins = ['react-native-reanimated/plugin'];

module.exports = {
mobilePlugins: [
...commonPlugins,
[
'module-resolver',
{
alias: regularAlias,
},
],
],
webPlugins: [
...commonPlugins,
[
'module-resolver',
{
alias: webAlias,
},
],
'react-native-web',
],
};
41 changes: 41 additions & 0 deletions index.web.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* @format
*/

import {AppRegistry} from 'react-native';

import {App} from './App';
import './i18n/i18n';

import {name as appName} from './app.json';

import MaterialIconFont from 'react-native-vector-icons/Fonts/MaterialIcons.ttf';
import MaterialCommunityIconFont from 'react-native-vector-icons/Fonts/MaterialCommunityIcons.ttf';

const iconFontStyles = `@font-face {
src: url(${MaterialCommunityIconFont});
font-family: MaterialCommunityIcons;
}

@font-face {
src: url(${MaterialIconFont});
font-family: MaterialIcons;
}`;

// Create a stylesheet
const style = document.createElement('style');
style.type = 'text/css';

// Append the iconFontStyles to the stylesheet
if (style.styleSheet) {
style.styleSheet.cssText = iconFontStyles;
} else {
style.appendChild(document.createTextNode(iconFontStyles));
}

// Inject the stylesheet into the document head
document.head.appendChild(style);

AppRegistry.registerComponent(appName, () => App);

AppRegistry.runApplication(appName, {rootTag: document.getElementById('root')});
Loading
Loading