Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc9006f2c0 | ||
|
|
9da7f2d1cd | ||
|
|
23f57e4d75 | ||
|
|
5be4287230 | ||
|
|
1dace08b23 | ||
|
|
807c240f22 | ||
|
|
31ac1cd864 |
No files matched your search
+10
-16
@@ -1,28 +1,22 @@
|
||||
# Docs: <https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/customizing-dependency-updates>
|
||||
# Docs: <https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/customizing-dependency-updates>
|
||||
|
||||
version: 2
|
||||
|
||||
updates:
|
||||
- package-ecosystem: github-actions
|
||||
directory: /
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: "tuesday"
|
||||
time: "01:00"
|
||||
timezone: "Asia/Kolkata"
|
||||
schedule: {interval: weekly}
|
||||
reviewers: [ajbura]
|
||||
assignees: [ajbura]
|
||||
|
||||
- package-ecosystem: docker
|
||||
directory: /
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: "tuesday"
|
||||
time: "01:00"
|
||||
timezone: "Asia/Kolkata"
|
||||
schedule: {interval: weekly}
|
||||
reviewers: [ajbura]
|
||||
assignees: [ajbura]
|
||||
|
||||
- package-ecosystem: npm
|
||||
directory: /
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: "tuesday"
|
||||
time: "01:00"
|
||||
timezone: "Asia/Kolkata"
|
||||
schedule: {interval: weekly}
|
||||
reviewers: [ajbura]
|
||||
assignees: [ajbura]
|
||||
@@ -1,39 +1,32 @@
|
||||
name: 'Build pull request'
|
||||
name: 'Build PR'
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: ['opened', 'synchronize']
|
||||
|
||||
jobs:
|
||||
build-pull-request:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
PR_NUMBER: ${{github.event.number}}
|
||||
steps:
|
||||
- name: Check out the repo
|
||||
uses: actions/checkout@v3.0.0
|
||||
- name: Build app
|
||||
run: npm ci && npm run build
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v3.0.0
|
||||
with:
|
||||
name: previewbuild
|
||||
path: dist
|
||||
retention-days: 1
|
||||
- name: Get PR info
|
||||
uses: actions/github-script@v6.0.0
|
||||
with:
|
||||
script: |
|
||||
var fs = require('fs');
|
||||
fs.writeFileSync('${{github.workspace}}/pr.json', JSON.stringify(context.payload.pull_request));
|
||||
- name: Upload PR Info
|
||||
uses: actions/upload-artifact@v3.0.0
|
||||
with:
|
||||
name: pr.json
|
||||
path: pr.json
|
||||
retention-days: 1
|
||||
- name: Build Docker image
|
||||
uses: docker/build-push-action@v2.10.0
|
||||
with:
|
||||
context: .
|
||||
push: false
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
PR_NUMBER: ${{github.event.number}}
|
||||
steps:
|
||||
- uses: actions/checkout@v3.0.0
|
||||
- name: Build
|
||||
run: npm ci && npm run build
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v3.0.0
|
||||
with:
|
||||
name: previewbuild
|
||||
path: dist
|
||||
retention-days: 1
|
||||
- uses: actions/github-script@v6.0.0
|
||||
with:
|
||||
script: |
|
||||
var fs = require('fs');
|
||||
fs.writeFileSync('${{github.workspace}}/pr.json', JSON.stringify(context.payload.pull_request));
|
||||
- name: Upload PR Info
|
||||
uses: actions/upload-artifact@v3.0.0
|
||||
with:
|
||||
name: pr.json
|
||||
path: pr.json
|
||||
retention-days: 1
|
||||
@@ -1,78 +1,78 @@
|
||||
name: Upload Preview Build to Netlify
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["Build pull request"]
|
||||
types:
|
||||
- completed
|
||||
workflow_run:
|
||||
workflows: ["Build PR"]
|
||||
types:
|
||||
- completed
|
||||
jobs:
|
||||
get-build-and-deploy:
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
steps:
|
||||
# There's a 'download artifact' action but it hasn't been updated for the
|
||||
# workflow_run action (https://github.com/actions/download-artifact/issues/60)
|
||||
# so instead we get this mess:
|
||||
- name: 'Download artifact'
|
||||
uses: actions/github-script@v6.0.0
|
||||
with:
|
||||
script: |
|
||||
var artifacts = await github.rest.actions.listWorkflowRunArtifacts({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
run_id: ${{github.event.workflow_run.id }},
|
||||
});
|
||||
var matchArtifact = artifacts.data.artifacts.filter((artifact) => {
|
||||
return artifact.name == "previewbuild"
|
||||
})[0];
|
||||
var download = await github.rest.actions.downloadArtifact({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
artifact_id: matchArtifact.id,
|
||||
archive_format: 'zip',
|
||||
});
|
||||
var fs = require('fs');
|
||||
fs.writeFileSync('${{github.workspace}}/previewbuild.zip', Buffer.from(download.data));
|
||||
var prInfoArtifact = artifacts.data.artifacts.filter((artifact) => {
|
||||
return artifact.name == "pr.json"
|
||||
})[0];
|
||||
var download = await github.rest.actions.downloadArtifact({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
artifact_id: prInfoArtifact.id,
|
||||
archive_format: 'zip',
|
||||
});
|
||||
var fs = require('fs');
|
||||
fs.writeFileSync('${{github.workspace}}/pr.json.zip', Buffer.from(download.data));
|
||||
- name: Extract Artifacts
|
||||
run: unzip -d dist previewbuild.zip && rm previewbuild.zip && unzip pr.json.zip && rm pr.json.zip
|
||||
- name: 'Read PR Info'
|
||||
id: readctx
|
||||
uses: actions/github-script@v6.0.0
|
||||
with:
|
||||
script: |
|
||||
var fs = require('fs');
|
||||
var pr = JSON.parse(fs.readFileSync('${{github.workspace}}/pr.json'));
|
||||
console.log(`::set-output name=prnumber::${pr.number}`);
|
||||
- name: Deploy to Netlify
|
||||
id: netlify
|
||||
uses: nwtgck/actions-netlify@v1.2.3
|
||||
with:
|
||||
publish-dir: dist
|
||||
deploy-message: "Deploy from GitHub Actions"
|
||||
# These don't work because we're in workflow_run
|
||||
enable-pull-request-comment: false
|
||||
enable-commit-comment: false
|
||||
env:
|
||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE3_ID }}
|
||||
timeout-minutes: 1
|
||||
- name: Edit PR Description
|
||||
uses: velas/pr-description@v1.0.1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
pull-request-number: ${{ steps.readctx.outputs.prnumber }}
|
||||
description-message: |
|
||||
Preview: ${{ steps.netlify.outputs.deploy-url }}
|
||||
⚠️ Exercise caution. Use test accounts. ⚠️
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
steps:
|
||||
# There's a 'download artifact' action but it hasn't been updated for the
|
||||
# workflow_run action (https://github.com/actions/download-artifact/issues/60)
|
||||
# so instead we get this mess:
|
||||
- name: 'Download artifact'
|
||||
uses: actions/github-script@v6.0.0
|
||||
with:
|
||||
script: |
|
||||
var artifacts = await github.rest.actions.listWorkflowRunArtifacts({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
run_id: ${{github.event.workflow_run.id }},
|
||||
});
|
||||
var matchArtifact = artifacts.data.artifacts.filter((artifact) => {
|
||||
return artifact.name == "previewbuild"
|
||||
})[0];
|
||||
var download = await github.rest.actions.downloadArtifact({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
artifact_id: matchArtifact.id,
|
||||
archive_format: 'zip',
|
||||
});
|
||||
var fs = require('fs');
|
||||
fs.writeFileSync('${{github.workspace}}/previewbuild.zip', Buffer.from(download.data));
|
||||
var prInfoArtifact = artifacts.data.artifacts.filter((artifact) => {
|
||||
return artifact.name == "pr.json"
|
||||
})[0];
|
||||
var download = await github.rest.actions.downloadArtifact({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
artifact_id: prInfoArtifact.id,
|
||||
archive_format: 'zip',
|
||||
});
|
||||
var fs = require('fs');
|
||||
fs.writeFileSync('${{github.workspace}}/pr.json.zip', Buffer.from(download.data));
|
||||
- name: Extract Artifacts
|
||||
run: unzip -d dist previewbuild.zip && rm previewbuild.zip && unzip pr.json.zip && rm pr.json.zip
|
||||
- name: 'Read PR Info'
|
||||
id: readctx
|
||||
uses: actions/github-script@v6.0.0
|
||||
with:
|
||||
script: |
|
||||
var fs = require('fs');
|
||||
var pr = JSON.parse(fs.readFileSync('${{github.workspace}}/pr.json'));
|
||||
console.log(`::set-output name=prnumber::${pr.number}`);
|
||||
- name: Deploy to Netlify
|
||||
id: netlify
|
||||
uses: nwtgck/actions-netlify@v1.2.3
|
||||
with:
|
||||
publish-dir: dist
|
||||
deploy-message: "Deploy from GitHub Actions"
|
||||
# These don't work because we're in workflow_run
|
||||
enable-pull-request-comment: false
|
||||
enable-commit-comment: false
|
||||
env:
|
||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE3_ID }}
|
||||
timeout-minutes: 1
|
||||
- name: Edit PR Description
|
||||
uses: velas/pr-description@v1.0.1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
pull-request-number: ${{ steps.readctx.outputs.prnumber }}
|
||||
description-message: |
|
||||
Preview: ${{ steps.netlify.outputs.deploy-url }}
|
||||
⚠️ Exercise caution. Use test accounts. ⚠️
|
||||
@@ -0,0 +1,34 @@
|
||||
name: Publish Docker image
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
push_to_registry:
|
||||
name: Push Docker image to Docker Hub
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Check out the repo
|
||||
uses: actions/checkout@v3.0.0
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@v1.14.1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@v3.6.2
|
||||
with:
|
||||
images: ajbura/cinny
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v2.9.0
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
@@ -0,0 +1,21 @@
|
||||
name: 'Deploy to Netlify (prod)'
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
name: 'Deploy'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.0.0
|
||||
- uses: jsmrcaga/action-netlify-deploy@v1.7.2
|
||||
with:
|
||||
install_command: "npm ci"
|
||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
|
||||
BUILD_DIRECTORY: "dist"
|
||||
NETLIFY_DEPLOY_MESSAGE: "Prod deploy v${{ github.ref }}"
|
||||
NETLIFY_DEPLOY_TO_PROD: true
|
||||
@@ -1,56 +0,0 @@
|
||||
name: 'Production deploy'
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
deploy-to-netlify:
|
||||
name: 'Deploy to Netlify'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out the repo
|
||||
uses: actions/checkout@v3.0.0
|
||||
- name: Build and deploy to Netlify
|
||||
uses: jsmrcaga/action-netlify-deploy@v1.7.2
|
||||
with:
|
||||
install_command: "npm ci"
|
||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
|
||||
BUILD_DIRECTORY: "dist"
|
||||
NETLIFY_DEPLOY_MESSAGE: "Prod deploy v${{ github.ref }}"
|
||||
NETLIFY_DEPLOY_TO_PROD: true
|
||||
- name: Get version from tag
|
||||
id: vars
|
||||
run: echo ::set-output name=tag::${GITHUB_REF#refs/*/}
|
||||
- name: Create tar.gz
|
||||
run: tar -czvf cinny-${{ steps.vars.outputs.tag }}.tar.gz dist
|
||||
- name: Upload tagged release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
files: |
|
||||
cinny-${{ steps.vars.outputs.tag }}.tar.gz
|
||||
|
||||
push_to_dockerhub:
|
||||
name: Push Docker image to Docker Hub
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out the repo
|
||||
uses: actions/checkout@v3.0.0
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v1.14.1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@v3.6.2
|
||||
with:
|
||||
images: ajbura/cinny
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v2.10.0
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
## Builder
|
||||
FROM node:17.7.1-alpine3.15 as builder
|
||||
FROM node:17.6.0-alpine3.15 as builder
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
|
||||
Generated
+17
-17
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "cinny",
|
||||
"version": "1.8.1",
|
||||
"version": "1.8.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "cinny",
|
||||
"version": "1.8.1",
|
||||
"version": "1.8.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@fontsource/inter": "^4.5.5",
|
||||
@@ -38,7 +38,7 @@
|
||||
"react-modal": "^3.14.4",
|
||||
"sanitize-html": "^2.7.0",
|
||||
"tippy.js": "^6.3.7",
|
||||
"twemoji": "^14.0.1"
|
||||
"twemoji": "^13.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.17.7",
|
||||
@@ -13137,20 +13137,20 @@
|
||||
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
|
||||
},
|
||||
"node_modules/twemoji": {
|
||||
"version": "14.0.1",
|
||||
"resolved": "https://registry.npmjs.org/twemoji/-/twemoji-14.0.1.tgz",
|
||||
"integrity": "sha512-eoqhea0sUhmC10iTacksyp1v9O4BP1jKmVqtK+Nztw40/dzawSHkXL3/xCpyh+mukmEvJ0Gw9VLvwZfQ9HKXDw==",
|
||||
"version": "13.1.0",
|
||||
"resolved": "https://registry.npmjs.org/twemoji/-/twemoji-13.1.0.tgz",
|
||||
"integrity": "sha512-e3fZRl2S9UQQdBFLYXtTBT6o4vidJMnpWUAhJA+yLGR+kaUTZAt3PixC0cGvvxWSuq2MSz/o0rJraOXrWw/4Ew==",
|
||||
"dependencies": {
|
||||
"fs-extra": "^8.0.1",
|
||||
"jsonfile": "^5.0.0",
|
||||
"twemoji-parser": "14.0.0",
|
||||
"twemoji-parser": "13.1.0",
|
||||
"universalify": "^0.1.2"
|
||||
}
|
||||
},
|
||||
"node_modules/twemoji-parser": {
|
||||
"version": "14.0.0",
|
||||
"resolved": "https://registry.npmjs.org/twemoji-parser/-/twemoji-parser-14.0.0.tgz",
|
||||
"integrity": "sha512-9DUOTGLOWs0pFWnh1p6NF+C3CkQ96PWmEFwhOVmT3WbecRC+68AIqpsnJXygfkFcp4aXbOp8Dwbhh/HQgvoRxA=="
|
||||
"version": "13.1.0",
|
||||
"resolved": "https://registry.npmjs.org/twemoji-parser/-/twemoji-parser-13.1.0.tgz",
|
||||
"integrity": "sha512-AQOzLJpYlpWMy8n+0ATyKKZzWlZBJN+G0C+5lhX7Ftc2PeEVdUU/7ns2Pn2vVje26AIZ/OHwFoUbdv6YYD/wGg=="
|
||||
},
|
||||
"node_modules/type-check": {
|
||||
"version": "0.4.0",
|
||||
@@ -24053,20 +24053,20 @@
|
||||
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
|
||||
},
|
||||
"twemoji": {
|
||||
"version": "14.0.1",
|
||||
"resolved": "https://registry.npmjs.org/twemoji/-/twemoji-14.0.1.tgz",
|
||||
"integrity": "sha512-eoqhea0sUhmC10iTacksyp1v9O4BP1jKmVqtK+Nztw40/dzawSHkXL3/xCpyh+mukmEvJ0Gw9VLvwZfQ9HKXDw==",
|
||||
"version": "13.1.0",
|
||||
"resolved": "https://registry.npmjs.org/twemoji/-/twemoji-13.1.0.tgz",
|
||||
"integrity": "sha512-e3fZRl2S9UQQdBFLYXtTBT6o4vidJMnpWUAhJA+yLGR+kaUTZAt3PixC0cGvvxWSuq2MSz/o0rJraOXrWw/4Ew==",
|
||||
"requires": {
|
||||
"fs-extra": "^8.0.1",
|
||||
"jsonfile": "^5.0.0",
|
||||
"twemoji-parser": "14.0.0",
|
||||
"twemoji-parser": "13.1.0",
|
||||
"universalify": "^0.1.2"
|
||||
}
|
||||
},
|
||||
"twemoji-parser": {
|
||||
"version": "14.0.0",
|
||||
"resolved": "https://registry.npmjs.org/twemoji-parser/-/twemoji-parser-14.0.0.tgz",
|
||||
"integrity": "sha512-9DUOTGLOWs0pFWnh1p6NF+C3CkQ96PWmEFwhOVmT3WbecRC+68AIqpsnJXygfkFcp4aXbOp8Dwbhh/HQgvoRxA=="
|
||||
"version": "13.1.0",
|
||||
"resolved": "https://registry.npmjs.org/twemoji-parser/-/twemoji-parser-13.1.0.tgz",
|
||||
"integrity": "sha512-AQOzLJpYlpWMy8n+0ATyKKZzWlZBJN+G0C+5lhX7Ftc2PeEVdUU/7ns2Pn2vVje26AIZ/OHwFoUbdv6YYD/wGg=="
|
||||
},
|
||||
"type-check": {
|
||||
"version": "0.4.0",
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cinny",
|
||||
"version": "1.8.1",
|
||||
"version": "1.8.0",
|
||||
"description": "Yet another matrix client",
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
@@ -44,7 +44,7 @@
|
||||
"react-modal": "^3.14.4",
|
||||
"sanitize-html": "^2.7.0",
|
||||
"tippy.js": "^6.3.7",
|
||||
"twemoji": "^14.0.1"
|
||||
"twemoji": "^13.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.17.7",
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
||||
<g>
|
||||
<rect x="7" y="12" fill="#010101" width="10" height="2"/>
|
||||
<g>
|
||||
<circle fill="#010101" cx="19" cy="6" r="4"/>
|
||||
</g>
|
||||
<path fill="#010101" d="M13.3,8H7v2h7.5C14,9.4,13.6,8.7,13.3,8z"/>
|
||||
<path fill="#010101" d="M19,12v5.6l-2.4-1.3L16.1,16h-0.5H5V6h8c0-0.7,0.1-1.4,0.3-2H4.8C3.8,4,3,4.9,3,6v10c0,1.1,0.8,2,1.8,2
|
||||
h10.8l5.4,3v-9.3C20.4,11.9,19.7,12,19,12z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 811 B |
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
||||
<g>
|
||||
<path fill="#010101" d="M19,6v11.6l-2.4-1.3L16.1,16h-0.5H5V6H19 M19.2,4H4.8C3.8,4,3,4.9,3,6v10c0,1.1,0.8,2,1.8,2h10.8l5.4,3V6
|
||||
C21,4.9,20.2,4,19.2,4L19.2,4z"/>
|
||||
<rect x="7" y="8" fill="#010101" width="10" height="2"/>
|
||||
<rect x="7" y="12" fill="#010101" width="10" height="2"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 732 B |
@@ -469,18 +469,6 @@ function isMedia(mE) {
|
||||
);
|
||||
}
|
||||
|
||||
// if editedTimeline has mEventId then pass editedMEvent else pass mEvent to openViewSource
|
||||
function handleOpenViewSource(mEvent, roomTimeline) {
|
||||
const eventId = mEvent.getId();
|
||||
const { editedTimeline } = roomTimeline ?? {};
|
||||
let editedMEvent;
|
||||
if (editedTimeline?.has(eventId)) {
|
||||
const editedList = editedTimeline.get(eventId);
|
||||
editedMEvent = editedList[editedList.length - 1];
|
||||
}
|
||||
openViewSource(editedMEvent !== undefined ? editedMEvent : mEvent);
|
||||
}
|
||||
|
||||
const MessageOptions = React.memo(({
|
||||
roomTimeline, mEvent, edit, reply,
|
||||
}) => {
|
||||
@@ -528,7 +516,7 @@ const MessageOptions = React.memo(({
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
iconSrc={CmdIC}
|
||||
onClick={() => handleOpenViewSource(mEvent, roomTimeline)}
|
||||
onClick={() => openViewSource(mEvent)}
|
||||
>
|
||||
View source
|
||||
</MenuItem>
|
||||
|
||||
@@ -6,7 +6,6 @@ import { twemojify } from '../../../util/twemojify';
|
||||
import initMatrix from '../../../client/initMatrix';
|
||||
import { openInviteUser } from '../../../client/action/navigation';
|
||||
import * as roomActions from '../../../client/action/room';
|
||||
import { markAsRead } from '../../../client/action/notifications';
|
||||
|
||||
import { MenuHeader, MenuItem } from '../../atoms/context-menu/ContextMenu';
|
||||
import RoomNotification from '../room-notification/RoomNotification';
|
||||
@@ -21,8 +20,10 @@ function RoomOptions({ roomId, afterOptionSelect }) {
|
||||
const canInvite = room?.canInvite(mx.getUserId());
|
||||
|
||||
const handleMarkAsRead = () => {
|
||||
markAsRead(roomId);
|
||||
afterOptionSelect();
|
||||
if (!room) return;
|
||||
const events = room.getLiveTimeline().getEvents();
|
||||
mx.sendReadReceipt(events[events.length - 1]);
|
||||
};
|
||||
|
||||
const handleInviteClick = () => {
|
||||
|
||||
@@ -13,46 +13,33 @@ import RoomSettings from './RoomSettings';
|
||||
import PeopleDrawer from './PeopleDrawer';
|
||||
|
||||
function Room() {
|
||||
const [roomInfo, setRoomInfo] = useState({
|
||||
roomTimeline: null,
|
||||
eventId: null,
|
||||
});
|
||||
const [roomTimeline, setRoomTimeline] = useState(null);
|
||||
const [eventId, setEventId] = useState(null);
|
||||
const [isDrawer, setIsDrawer] = useState(settings.isPeopleDrawer);
|
||||
|
||||
const mx = initMatrix.matrixClient;
|
||||
const handleRoomSelected = (rId, pRoomId, eId) => {
|
||||
if (mx.getRoom(rId)) {
|
||||
setRoomTimeline(new RoomTimeline(rId, initMatrix.notifications));
|
||||
setEventId(eId);
|
||||
} else {
|
||||
// TODO: add ability to join room if roomId is invalid
|
||||
setRoomTimeline(null);
|
||||
setEventId(null);
|
||||
}
|
||||
};
|
||||
const handleDrawerToggling = (visiblity) => setIsDrawer(visiblity);
|
||||
|
||||
useEffect(() => {
|
||||
const handleRoomSelected = (rId, pRoomId, eId) => {
|
||||
roomInfo.roomTimeline?.removeInternalListeners();
|
||||
if (mx.getRoom(rId)) {
|
||||
setRoomInfo({
|
||||
roomTimeline: new RoomTimeline(rId),
|
||||
eventId: eId ?? null,
|
||||
});
|
||||
} else {
|
||||
// TODO: add ability to join room if roomId is invalid
|
||||
setRoomInfo({
|
||||
roomTimeline: null,
|
||||
eventId: null,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
navigation.on(cons.events.navigation.ROOM_SELECTED, handleRoomSelected);
|
||||
return () => {
|
||||
navigation.removeListener(cons.events.navigation.ROOM_SELECTED, handleRoomSelected);
|
||||
};
|
||||
}, [roomInfo]);
|
||||
|
||||
useEffect(() => {
|
||||
const handleDrawerToggling = (visiblity) => setIsDrawer(visiblity);
|
||||
settings.on(cons.events.settings.PEOPLE_DRAWER_TOGGLED, handleDrawerToggling);
|
||||
return () => {
|
||||
navigation.removeListener(cons.events.navigation.ROOM_SELECTED, handleRoomSelected);
|
||||
settings.removeListener(cons.events.settings.PEOPLE_DRAWER_TOGGLED, handleDrawerToggling);
|
||||
roomTimeline?.removeInternalListeners();
|
||||
};
|
||||
}, []);
|
||||
|
||||
const { roomTimeline, eventId } = roomInfo;
|
||||
if (roomTimeline === null) return <Welcome />;
|
||||
|
||||
return (
|
||||
|
||||
@@ -14,7 +14,6 @@ import cons from '../../../client/state/cons';
|
||||
import navigation from '../../../client/state/navigation';
|
||||
import { openProfileViewer } from '../../../client/action/navigation';
|
||||
import { diffMinutes, isInSameDay, Throttle } from '../../../util/common';
|
||||
import { markAsRead } from '../../../client/action/notifications';
|
||||
|
||||
import Divider from '../../atoms/divider/Divider';
|
||||
import ScrollView from '../../atoms/scroll/ScrollView';
|
||||
@@ -146,12 +145,13 @@ function useTimeline(roomTimeline, eventId, readUptoEvtStore, eventLimitRef) {
|
||||
|
||||
if (isSpecificEvent) {
|
||||
focusEventIndex = roomTimeline.getEventIndex(eId);
|
||||
}
|
||||
if (!readUptoEvtStore.getItem() && roomTimeline.hasEventInTimeline(readUpToId)) {
|
||||
} else if (!readUptoEvtStore.getItem()) {
|
||||
// either opening live timeline or jump to unread.
|
||||
readUptoEvtStore.setItem(roomTimeline.findEventByIdInTimelineSet(readUpToId));
|
||||
}
|
||||
if (readUptoEvtStore.getItem() && !isSpecificEvent) {
|
||||
focusEventIndex = roomTimeline.getUnreadEventIndex(readUpToId);
|
||||
if (roomTimeline.hasEventInTimeline(readUpToId)) {
|
||||
readUptoEvtStore.setItem(roomTimeline.findEventByIdInTimelineSet(readUpToId));
|
||||
}
|
||||
} else {
|
||||
focusEventIndex = roomTimeline.getUnreadEventIndex(readUptoEvtStore.getItem().getId());
|
||||
}
|
||||
|
||||
@@ -167,6 +167,7 @@ function useTimeline(roomTimeline, eventId, readUptoEvtStore, eventLimitRef) {
|
||||
setEventTimeline(eventId);
|
||||
return () => {
|
||||
roomTimeline.removeListener(cons.events.roomTimeline.READY, initTimeline);
|
||||
roomTimeline.removeInternalListeners();
|
||||
limit.setFrom(0);
|
||||
};
|
||||
}, [roomTimeline, eventId]);
|
||||
@@ -254,7 +255,7 @@ function useHandleScroll(
|
||||
);
|
||||
roomTimeline.emit(cons.events.roomTimeline.AT_BOTTOM, isAtBottom);
|
||||
if (isAtBottom && readUptoEvtStore.getItem()) {
|
||||
requestAnimationFrame(() => markAsRead(roomTimeline.roomId));
|
||||
requestAnimationFrame(() => roomTimeline.markAllAsRead());
|
||||
}
|
||||
});
|
||||
autoPaginate();
|
||||
@@ -264,7 +265,7 @@ function useHandleScroll(
|
||||
const timelineScroll = timelineScrollRef.current;
|
||||
const limit = eventLimitRef.current;
|
||||
if (readUptoEvtStore.getItem()) {
|
||||
requestAnimationFrame(() => markAsRead(roomTimeline.roomId));
|
||||
requestAnimationFrame(() => roomTimeline.markAllAsRead());
|
||||
}
|
||||
if (roomTimeline.isServingLiveTimeline()) {
|
||||
limit.setFrom(roomTimeline.timeline.length - limit.maxEvents);
|
||||
@@ -285,39 +286,44 @@ function useEventArrive(roomTimeline, readUptoEvtStore, timelineScrollRef, event
|
||||
useEffect(() => {
|
||||
const timelineScroll = timelineScrollRef.current;
|
||||
const limit = eventLimitRef.current;
|
||||
const trySendReadReceipt = (event) => {
|
||||
const sendReadReceipt = (event) => {
|
||||
if (event.isSending()) return;
|
||||
if (myUserId === event.getSender()) {
|
||||
requestAnimationFrame(() => markAsRead(roomTimeline.roomId));
|
||||
roomTimeline.markAllAsRead();
|
||||
return;
|
||||
}
|
||||
const readUpToEvent = readUptoEvtStore.getItem();
|
||||
const readUpToId = roomTimeline.getReadUpToEventId();
|
||||
const isUnread = readUpToEvent ? readUpToEvent?.getId() === readUpToId : true;
|
||||
const isUnread = readUpToEvent?.getId() === readUpToId;
|
||||
|
||||
if (isUnread === false) {
|
||||
if (document.visibilityState === 'visible' && timelineScroll.bottom < 16) {
|
||||
requestAnimationFrame(() => markAsRead(roomTimeline.roomId));
|
||||
} else {
|
||||
readUptoEvtStore.setItem(roomTimeline.findEventByIdInTimelineSet(readUpToId));
|
||||
}
|
||||
// if user doesn't have focus on app don't mark messages as read.
|
||||
if (document.visibilityState === 'hidden' || timelineScroll.bottom >= 16) {
|
||||
if (isUnread) return;
|
||||
readUptoEvtStore.setItem(roomTimeline.findEventByIdInTimelineSet(readUpToId));
|
||||
return;
|
||||
}
|
||||
|
||||
// user has not mark room as read
|
||||
if (!isUnread) {
|
||||
roomTimeline.markAllAsRead();
|
||||
}
|
||||
const { timeline } = roomTimeline;
|
||||
const unreadMsgIsLast = timeline[timeline.length - 2].getId() === readUpToId;
|
||||
const unreadMsgIsLast = timeline[timeline.length - 2].getId() === readUpToEvent?.getId();
|
||||
if (unreadMsgIsLast) {
|
||||
requestAnimationFrame(() => markAsRead(roomTimeline.roomId));
|
||||
roomTimeline.markAllAsRead();
|
||||
}
|
||||
};
|
||||
|
||||
const handleEvent = (event) => {
|
||||
const tLength = roomTimeline.timeline.length;
|
||||
const isViewingLive = roomTimeline.isServingLiveTimeline() && limit.length >= tLength - 1;
|
||||
const isAttached = timelineScroll.bottom < SCROLL_TRIGGER_POS;
|
||||
|
||||
if (isViewingLive && isAttached) {
|
||||
const isUserViewingLive = (
|
||||
roomTimeline.isServingLiveTimeline()
|
||||
&& limit.length >= tLength - 1
|
||||
&& timelineScroll.bottom < SCROLL_TRIGGER_POS
|
||||
);
|
||||
if (isUserViewingLive) {
|
||||
limit.setFrom(tLength - limit.maxEvents);
|
||||
trySendReadReceipt(event);
|
||||
sendReadReceipt(event);
|
||||
setEvent(event);
|
||||
return;
|
||||
}
|
||||
@@ -326,8 +332,11 @@ function useEventArrive(roomTimeline, readUptoEvtStore, timelineScrollRef, event
|
||||
setEvent(event);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isViewingLive) {
|
||||
const isUserDitchedLive = (
|
||||
roomTimeline.isServingLiveTimeline()
|
||||
&& limit.length >= tLength - 1
|
||||
);
|
||||
if (isUserDitchedLive) {
|
||||
// This stateUpdate will help to put the
|
||||
// loading msg placeholder at bottom
|
||||
setEvent(event);
|
||||
@@ -344,7 +353,17 @@ function useEventArrive(roomTimeline, readUptoEvtStore, timelineScrollRef, event
|
||||
};
|
||||
}, [roomTimeline]);
|
||||
|
||||
return newEvent;
|
||||
useEffect(() => {
|
||||
const timelineScroll = timelineScrollRef.current;
|
||||
if (!roomTimeline.initialized) return;
|
||||
if (timelineScroll.bottom < 16
|
||||
&& !roomTimeline.canPaginateForward()
|
||||
&& document.visibilityState === 'visible') {
|
||||
timelineScroll.scrollToBottom();
|
||||
} else {
|
||||
timelineScroll.tryRestoringScroll();
|
||||
}
|
||||
}, [newEvent, roomTimeline]);
|
||||
}
|
||||
|
||||
let jumpToItemIndex = -1;
|
||||
@@ -375,7 +394,7 @@ function RoomViewContent({ eventId, roomTimeline }) {
|
||||
timelineScrollRef,
|
||||
eventLimitRef,
|
||||
);
|
||||
const newEvent = useEventArrive(roomTimeline, readUptoEvtStore, timelineScrollRef, eventLimitRef);
|
||||
useEventArrive(roomTimeline, readUptoEvtStore, timelineScrollRef, eventLimitRef);
|
||||
|
||||
const { timeline } = roomTimeline;
|
||||
|
||||
@@ -400,7 +419,7 @@ function RoomViewContent({ eventId, roomTimeline }) {
|
||||
if (timelineScroll.bottom < 16 && !roomTimeline.canPaginateForward()) {
|
||||
const readUpToId = roomTimeline.getReadUpToEventId();
|
||||
if (readUptoEvtStore.getItem()?.getId() === readUpToId || readUpToId === null) {
|
||||
requestAnimationFrame(() => markAsRead(roomTimeline.roomId));
|
||||
requestAnimationFrame(() => roomTimeline.markAllAsRead());
|
||||
}
|
||||
}
|
||||
jumpToItemIndex = -1;
|
||||
@@ -429,16 +448,6 @@ function RoomViewContent({ eventId, roomTimeline }) {
|
||||
timelineScroll.tryRestoringScroll();
|
||||
}, [onLimitUpdate]);
|
||||
|
||||
useEffect(() => {
|
||||
const timelineScroll = timelineScrollRef.current;
|
||||
if (!roomTimeline.initialized) return;
|
||||
if (timelineScroll.bottom < 16 && !roomTimeline.canPaginateForward() && document.visibilityState === 'visible') {
|
||||
timelineScroll.scrollToBottom();
|
||||
} else {
|
||||
timelineScroll.tryRestoringScroll();
|
||||
}
|
||||
}, [newEvent]);
|
||||
|
||||
const handleTimelineScroll = (event) => {
|
||||
const timelineScroll = timelineScrollRef.current;
|
||||
if (!event.target) return;
|
||||
|
||||
@@ -5,13 +5,11 @@ import './RoomViewFloating.scss';
|
||||
|
||||
import initMatrix from '../../../client/initMatrix';
|
||||
import cons from '../../../client/state/cons';
|
||||
import { markAsRead } from '../../../client/action/notifications';
|
||||
|
||||
import Text from '../../atoms/text/Text';
|
||||
import Button from '../../atoms/button/Button';
|
||||
import IconButton from '../../atoms/button/IconButton';
|
||||
|
||||
import MessageUnreadIC from '../../../../public/res/ic/outlined/message-unread.svg';
|
||||
import ChevronBottomIC from '../../../../public/res/ic/outlined/chevron-bottom.svg';
|
||||
import TickMarkIC from '../../../../public/res/ic/outlined/tick-mark.svg';
|
||||
|
||||
@@ -25,7 +23,7 @@ function useJumpToEvent(roomTimeline) {
|
||||
};
|
||||
|
||||
const cancelJumpToEvent = () => {
|
||||
markAsRead(roomTimeline.roomId);
|
||||
roomTimeline.markAllAsRead();
|
||||
setEventId(null);
|
||||
};
|
||||
|
||||
@@ -38,12 +36,11 @@ function useJumpToEvent(roomTimeline) {
|
||||
setEventId(readEventId);
|
||||
}
|
||||
|
||||
const { notifications } = initMatrix;
|
||||
const handleMarkAsRead = () => setEventId(null);
|
||||
notifications.on(cons.events.notifications.FULL_READ, handleMarkAsRead);
|
||||
roomTimeline.on(cons.events.roomTimeline.MARKED_AS_READ, handleMarkAsRead);
|
||||
|
||||
return () => {
|
||||
notifications.removeListener(cons.events.notifications.FULL_READ, handleMarkAsRead);
|
||||
roomTimeline.removeListener(cons.events.roomTimeline.MARKED_AS_READ, handleMarkAsRead);
|
||||
setEventId(null);
|
||||
};
|
||||
}, [roomTimeline]);
|
||||
@@ -99,12 +96,17 @@ function RoomViewFloating({
|
||||
return (
|
||||
<>
|
||||
<div className={`room-view__unread ${isJumpToEvent ? 'room-view__unread--open' : ''}`}>
|
||||
<Button iconSrc={MessageUnreadIC} onClick={jumpToEvent} variant="primary">
|
||||
<Text variant="b3" weight="medium">Jump to unread messages</Text>
|
||||
</Button>
|
||||
<Button iconSrc={TickMarkIC} onClick={cancelJumpToEvent} variant="primary">
|
||||
<Text variant="b3" weight="bold">Mark as read</Text>
|
||||
<Button onClick={jumpToEvent} variant="primary">
|
||||
<Text variant="b2">Jump to unread</Text>
|
||||
</Button>
|
||||
<IconButton
|
||||
onClick={cancelJumpToEvent}
|
||||
variant="primary"
|
||||
size="extra-small"
|
||||
src={TickMarkIC}
|
||||
tooltipPlacement="bottom"
|
||||
tooltip="Mark as read"
|
||||
/>
|
||||
</div>
|
||||
<div className={`room-view__typing${typingMembers.size > 0 ? ' room-view__typing--open' : ''}`}>
|
||||
<div className="bouncing-loader"><div /></div>
|
||||
|
||||
@@ -90,33 +90,33 @@
|
||||
|
||||
&__unread {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@include dir.prop(left, var(--sp-normal), unset);
|
||||
@include dir.prop(right, unset, var(--sp-normal));
|
||||
top: var(--sp-extra-tight);
|
||||
@include dir.prop(right, var(--sp-extra-tight), unset);
|
||||
@include dir.prop(left, unset, var(--sp-extra-tight));
|
||||
z-index: 999;
|
||||
|
||||
display: none;
|
||||
width: calc(100% - var(--sp-extra-loose));
|
||||
background-color: var(--bg-surface);
|
||||
border-radius: 0 0 var(--bo-radius) var(--bo-radius);
|
||||
border-radius: var(--bo-radius);
|
||||
box-shadow: var(--bs-primary-border);
|
||||
overflow: hidden;
|
||||
|
||||
&--open {
|
||||
display: flex;
|
||||
}
|
||||
& .btn-primary {
|
||||
justify-content: flex-start;
|
||||
|
||||
& .ic-btn {
|
||||
padding: 6px var(--sp-extra-tight);
|
||||
border-radius: 0;
|
||||
padding: 2px var(--sp-tight);
|
||||
& .ic-raw {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
& .btn-primary:first-child {
|
||||
& .btn-primary {
|
||||
@extend .cp-fx__item-one;
|
||||
padding: var(--sp-ultra-tight) var(--sp-extra-tight);
|
||||
@include dir.side(margin, 0, 1px);
|
||||
border-radius: 0;
|
||||
padding: 0 var(--sp-tight);
|
||||
&:focus {
|
||||
background-color: var(--bg-primary-hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
import initMatrix from '../initMatrix';
|
||||
|
||||
// eslint-disable-next-line import/prefer-default-export
|
||||
export async function markAsRead(roomId) {
|
||||
const mx = initMatrix.matrixClient;
|
||||
const room = mx.getRoom(roomId);
|
||||
if (!room) return;
|
||||
initMatrix.notifications.deleteNoti(roomId);
|
||||
|
||||
const timeline = room.getLiveTimeline().getEvents();
|
||||
const readEventId = room.getEventReadUpTo(mx.getUserId());
|
||||
|
||||
const getLatestValidEvent = () => {
|
||||
for (let i = timeline.length - 1; i >= 0; i -= 1) {
|
||||
const latestEvent = timeline[i];
|
||||
if (latestEvent.getId() === readEventId) return null;
|
||||
if (!latestEvent.isSending()) return latestEvent;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
if (timeline.length === 0) return;
|
||||
const latestEvent = getLatestValidEvent();
|
||||
if (latestEvent === null) return;
|
||||
|
||||
await mx.sendReadReceipt(latestEvent);
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import { openSearch, toggleRoomSettings } from '../action/navigation';
|
||||
import navigation from '../state/navigation';
|
||||
import { markAsRead } from '../action/notifications';
|
||||
|
||||
function listenKeyboard(event) {
|
||||
// Ctrl/Cmd +
|
||||
@@ -19,19 +18,11 @@ function listenKeyboard(event) {
|
||||
return;
|
||||
}
|
||||
|
||||
// esc
|
||||
if (event.keyCode === 27) {
|
||||
if (navigation.isRoomSettings) {
|
||||
toggleRoomSettings();
|
||||
return;
|
||||
}
|
||||
if (navigation.selectedRoomId) {
|
||||
markAsRead(navigation.selectedRoomId);
|
||||
return;
|
||||
}
|
||||
// esc - close room settings panel
|
||||
if (event.keyCode === 27 && navigation.isRoomSettings) {
|
||||
toggleRoomSettings();
|
||||
}
|
||||
|
||||
// Don't allow these keys to type/focus message field
|
||||
if ((event.keyCode !== 8 && event.keyCode < 48)
|
||||
|| (event.keyCode >= 91 && event.keyCode <= 93)
|
||||
|| (event.keyCode >= 112 && event.keyCode <= 183)) {
|
||||
|
||||
@@ -77,7 +77,7 @@ function isTimelineLinked(tm1, tm2) {
|
||||
}
|
||||
|
||||
class RoomTimeline extends EventEmitter {
|
||||
constructor(roomId) {
|
||||
constructor(roomId, notifications) {
|
||||
super();
|
||||
// These are local timelines
|
||||
this.timeline = [];
|
||||
@@ -88,6 +88,7 @@ class RoomTimeline extends EventEmitter {
|
||||
this.matrixClient = initMatrix.matrixClient;
|
||||
this.roomId = roomId;
|
||||
this.room = this.matrixClient.getRoom(roomId);
|
||||
this.notifications = notifications;
|
||||
|
||||
this.liveTimeline = this.room.getLiveTimeline();
|
||||
this.activeTimeline = this.liveTimeline;
|
||||
@@ -227,6 +228,16 @@ class RoomTimeline extends EventEmitter {
|
||||
return Promise.allSettled(decryptionPromises);
|
||||
}
|
||||
|
||||
markAllAsRead() {
|
||||
const readEventId = this.getReadUpToEventId();
|
||||
this.notifications.deleteNoti(this.roomId);
|
||||
if (this.timeline.length === 0) return;
|
||||
const latestEvent = this.timeline[this.timeline.length - 1];
|
||||
if (readEventId === latestEvent.getId()) return;
|
||||
this.matrixClient.sendReadReceipt(latestEvent);
|
||||
this.emit(cons.events.roomTimeline.MARKED_AS_READ, latestEvent);
|
||||
}
|
||||
|
||||
hasEventInTimeline(eventId, timeline = this.activeTimeline) {
|
||||
const timelineSet = this.getUnfilteredTimelineSet();
|
||||
const eventTimeline = timelineSet.getTimelineForEvent(eventId);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const cons = {
|
||||
version: '1.8.1',
|
||||
version: '1.8.0',
|
||||
secretKey: {
|
||||
ACCESS_TOKEN: 'cinny_access_token',
|
||||
DEVICE_ID: 'cinny_device_id',
|
||||
@@ -115,6 +115,7 @@ const cons = {
|
||||
PAGINATED: 'PAGINATED',
|
||||
TYPING_MEMBERS_UPDATED: 'TYPING_MEMBERS_UPDATED',
|
||||
LIVE_RECEIPT: 'LIVE_RECEIPT',
|
||||
MARKED_AS_READ: 'MARKED_AS_READ',
|
||||
EVENT_REDACTED: 'EVENT_REDACTED',
|
||||
AT_BOTTOM: 'AT_BOTTOM',
|
||||
SCROLL_TO_LIVE: 'SCROLL_TO_LIVE',
|
||||
|
||||
Reference in new issue
Block a user