# Start Here

## Start Matrix

### Password Login

```javascript
const login = async () => {
  const result = await rnm.loginWithPassword(
    username,
    password,
    homeserver,
    true, // enable crypto? default false
  );
  if (result.error) {
    setLoading(false);
    console.log('Error logging in: ', result);
    setError(result.message);
  }
};
```

### Token Login

```
rnm.createClient(homeserver, accessToken, mxid, deviceId?);
rnm.start(); // pass "true" to enable crypto
```

## Get a list of rooms

### Using Core

This is what's happening in `/ui` in the [RoomList](/rnm/ui/roomlist.md) component behind the scenes. Render rooms and invites however you'd like. `inviteList` is a list of rooms you are not a part of yet, but have been invited to. \
`updateLists` is a function which refreshes the lists, usually in the event of an invite rejection / acceptance.&#x20;

```javascript
import { useMatrix, useRoomList } from '@rn-matrix/core'
...
// within your component
const { isReady, isSynced } = useMatrix();
const { roomList, inviteList, updateLists } = useRoomList();

if (!isReady || !isSynced) // return a loader 

return (
  <FlatList data={roomList} renderItem={...} />
)
```

### Using UI&#x20;

The [RoomList](/rnm/ui/roomlist.md) component will show a simple inbox. However, you can override what it looks like by using the prop `renderListItem`. Read more at [RoomList](/rnm/ui/roomlist.md).

```javascript
import { RoomList } from '@rn-matrix/ui'
...
function RoomListView() {
  const { isReady, isSynced } = useMatrix(); // you should still wait for these

  const onRowPress = (item) => {}
  
  if (!isReady || !isSynced) // return a loader 

  return <RoomList onRowPress={onRowPress} />
}
```

## Join room

Be sure to update the lists after `joinRoom` resolves.

```javascript
import rnm from '@rn-matrix/core'
...
const joinRoom = () => {
  rnm.getClient().joinRoom(room.roomId).then(updateLists)
}
```

## Reject room invite

Be sure to update the lists after `leaveRoom` resolves.

```javascript
import rnm from '@rn-matrix/core'
...
const rejectInvite = () => {
  rnm.getClient().leaveRoom(room.roomId).then(updateLists)
}
```

## Get avatar for room

View the Room method [`getAvatarUrl`](/rnm/matrix-help/models/room.md#getavatarurl)

```javascript
import rnm from '@rn-matrix/core'
...
const avatarSize = 50
const avatar = room.getAvatarUrl(
    rnm.getClient().getHomeserverUrl(),
    avatarSize,
    avatarSize,
    'crop',
    false
  )
```

## Get messages in a room

### Using Core

`timeline` is the actual list of messages.

`updates` is an array of messages that are deleted, edited, etc and therefore should be re-rendered in the view. Using this, you can memoize your MessageItem, reducing the number of useless re-renders on your screen.

To see an implementation of this including fetching previous messages, handling touches on the screen, rendering a typing indicator, etc, you can see that [in the example app](https://gitlab.com/annie-elequin/rn-matrix/-/blob/hooks/RnMatrixUi/src/views/MessageList.tsx).

```javascript
import { useTimeline } from '@rn-matrix/core'
...
export default function MessageView() {
  const { timeline, updates } = useTimeline(room);

  const renderMessageItem = ({item}) => <MessageItem message={message} />

  return (
    <FlatList
        inverted
        data={timeline}
        renderItem={renderMessageItem}
        keyExtractor={(item) => item.getId()}
      />
  )
}
```

### Using UI

View the docs on [MessageList](/rnm/ui/messagelist.md) to see what you can do for handling touches (onPress, onLongPress).

To see this in a code example, view [this piece of the example app](https://gitlab.com/annie-elequin/rn-matrix/-/blob/hooks/RnMatrixExample/src/scenes/chat/ChatScreen.js).

```javascript
import { useTimeline } from '@rn-matrix/core'
...
export default function MessageView() {
  // Get "room" from navigation params, from clicking on it in the inbox 

  return <MessageList room={room} />
}
```

## Send message to a room

### Send message

#### Text

For automatic conversion of markdown to html:

`rnm.sendTextMessage(roomId, content) // content is your markdown string`

For basic sending (no alterations made):&#x20;

`rnm.getClient().sendTextMessage(roomId, content)`

#### Image or Video

`rnm.sendMediaMessage(roomId, content, type)`

In this case, content is something that is received directly from something like ImagePicker.&#x20;

`type` is either `m.image` or `m.video`

```javascript
const openImagePicker = () => {
  const options = {
    mediaType: 'mixed',
  };
  ImagePicker.launchImageLibrary(options, async (response) => {
    if (response.didCancel) return;
    rnm.sendMediaMessage(response, response.type ? 'm.image' : 'm.video');
  });
};
```

### Send reply&#x20;

`relatedMessage` is the MatrixEvent which is being replied to.

```javascript
rnm.sendReply(roomId, relatedMessage: MatrixEvent, messageText)
```

## Edit message

```javascript
import rnm from '@rn-matrix/core'
...
rnm.editMessage(roomId, messageId, newMessageContent: string)
```

## Delete a message

```javascript
import rnm from '@rn-matrix/core'
...
rnm.deleteMessage(MatrixEvent)
```

## Create a room

Not available yet.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://aelequin.gitbook.io/rnm/getting-started/start-here.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
