You've already forked matrix-react-sdk
							
							
				mirror of
				https://github.com/matrix-org/matrix-react-sdk.git
				synced 2025-11-04 11:51:45 +03:00 
			
		
		
		
	test commit for confetti changes
This commit is contained in:
		@@ -44,6 +44,7 @@ import { ensureDMExists } from "./createRoom";
 | 
				
			|||||||
import { ViewUserPayload } from "./dispatcher/payloads/ViewUserPayload";
 | 
					import { ViewUserPayload } from "./dispatcher/payloads/ViewUserPayload";
 | 
				
			||||||
import { Action } from "./dispatcher/actions";
 | 
					import { Action } from "./dispatcher/actions";
 | 
				
			||||||
import { EffectiveMembership, getEffectiveMembership } from "./utils/membership";
 | 
					import { EffectiveMembership, getEffectiveMembership } from "./utils/membership";
 | 
				
			||||||
 | 
					import {func} from "prop-types";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// XXX: workaround for https://github.com/microsoft/TypeScript/issues/31816
 | 
					// XXX: workaround for https://github.com/microsoft/TypeScript/issues/31816
 | 
				
			||||||
interface HTMLInputEvent extends Event {
 | 
					interface HTMLInputEvent extends Event {
 | 
				
			||||||
@@ -1026,6 +1027,18 @@ export const Commands = [
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
        category: CommandCategories.actions,
 | 
					        category: CommandCategories.actions,
 | 
				
			||||||
    }),
 | 
					    }),
 | 
				
			||||||
 | 
					    new Command({
 | 
				
			||||||
 | 
					        command: "confetti",
 | 
				
			||||||
 | 
					        description: _td("Throws confetti animation in the chat room"),
 | 
				
			||||||
 | 
					        args: '/confetti + <message>',
 | 
				
			||||||
 | 
					        runFn: function(roomId, args, command) {
 | 
				
			||||||
 | 
					            return success((async () => {
 | 
				
			||||||
 | 
					              const cli = MatrixClientPeg.get();
 | 
				
			||||||
 | 
					              await cli.sendHtmlMessage(roomId, args);
 | 
				
			||||||
 | 
					            })());
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        category: CommandCategories.messages,
 | 
				
			||||||
 | 
					    }),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Command definitions for autocompletion ONLY:
 | 
					    // Command definitions for autocompletion ONLY:
 | 
				
			||||||
    // /me is special because its not handled by SlashCommands.js and is instead done inside the Composer classes
 | 
					    // /me is special because its not handled by SlashCommands.js and is instead done inside the Composer classes
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -57,6 +57,7 @@ import MatrixClientContext from "../../contexts/MatrixClientContext";
 | 
				
			|||||||
import { shieldStatusForRoom } from '../../utils/ShieldUtils';
 | 
					import { shieldStatusForRoom } from '../../utils/ShieldUtils';
 | 
				
			||||||
import {Action} from "../../dispatcher/actions";
 | 
					import {Action} from "../../dispatcher/actions";
 | 
				
			||||||
import {SettingLevel} from "../../settings/SettingLevel";
 | 
					import {SettingLevel} from "../../settings/SettingLevel";
 | 
				
			||||||
 | 
					import Confetti from "../views/elements/Confetti";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const DEBUG = false;
 | 
					const DEBUG = false;
 | 
				
			||||||
let debuglog = function() {};
 | 
					let debuglog = function() {};
 | 
				
			||||||
@@ -67,7 +68,7 @@ if (DEBUG) {
 | 
				
			|||||||
    // using bind means that we get to keep useful line numbers in the console
 | 
					    // using bind means that we get to keep useful line numbers in the console
 | 
				
			||||||
    debuglog = console.log.bind(console);
 | 
					    debuglog = console.log.bind(console);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					let confetti;
 | 
				
			||||||
export default createReactClass({
 | 
					export default createReactClass({
 | 
				
			||||||
    displayName: 'RoomView',
 | 
					    displayName: 'RoomView',
 | 
				
			||||||
    propTypes: {
 | 
					    propTypes: {
 | 
				
			||||||
@@ -624,12 +625,14 @@ export default createReactClass({
 | 
				
			|||||||
            ev.preventDefault();
 | 
					            ev.preventDefault();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					 | 
				
			||||||
    onAction: function(payload) {
 | 
					    onAction: function(payload) {
 | 
				
			||||||
        switch (payload.action) {
 | 
					        switch (payload.action) {
 | 
				
			||||||
            case 'message_send_failed':
 | 
					            case 'message_send_failed':
 | 
				
			||||||
            case 'message_sent':
 | 
					            case 'message_sent':
 | 
				
			||||||
                this._checkIfAlone(this.state.room);
 | 
					                this._checkIfAlone(this.state.room);
 | 
				
			||||||
 | 
					                confetti = new Confetti('100', '100');
 | 
				
			||||||
 | 
					                console.log('confetti sent');
 | 
				
			||||||
 | 
					                confetti.animateConfetti('test', 'message');
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case 'post_sticker_message':
 | 
					            case 'post_sticker_message':
 | 
				
			||||||
              this.injectSticker(
 | 
					              this.injectSticker(
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										209
									
								
								src/components/views/elements/Confetti.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										209
									
								
								src/components/views/elements/Confetti.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,209 @@
 | 
				
			|||||||
 | 
					import React from "react";
 | 
				
			||||||
 | 
					import SettingsStore from "../../../../lib/settings/SettingsStore";
 | 
				
			||||||
 | 
					import PropTypes from "prop-types";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default class Confetti extends React.Component {
 | 
				
			||||||
 | 
					    displayName: 'confetti';
 | 
				
			||||||
 | 
					    constructor(props) {
 | 
				
			||||||
 | 
					        super(props);
 | 
				
			||||||
 | 
					        this.animateConfetti = this.animateConfetti.bind(this);
 | 
				
			||||||
 | 
					        this.confetti.start = this.startConfetti;
 | 
				
			||||||
 | 
					        this.startConfetti = this.startConfetti.bind(this);
 | 
				
			||||||
 | 
					        this.confetti.stop = this.stopConfetti;
 | 
				
			||||||
 | 
					        this.confetti.remove = this.removeConfetti;
 | 
				
			||||||
 | 
					        this.confetti.isRunning = this.isConfettiRunning;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					   static propTypes = {
 | 
				
			||||||
 | 
					        width: PropTypes.string.isRequired,
 | 
				
			||||||
 | 
					        height: PropTypes.string.isRequired,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    confetti = {
 | 
				
			||||||
 | 
					        //set max confetti count
 | 
				
			||||||
 | 
					        maxCount: 150,
 | 
				
			||||||
 | 
					        //set the particle animation speed
 | 
				
			||||||
 | 
					        speed: 3,
 | 
				
			||||||
 | 
					        //the confetti animation frame interval in milliseconds
 | 
				
			||||||
 | 
					        frameInterval: 15,
 | 
				
			||||||
 | 
					        //the alpha opacity of the confetti (between 0 and 1, where 1 is opaque and 0 is invisible)
 | 
				
			||||||
 | 
					        alpha: 1.0,
 | 
				
			||||||
 | 
					        start: null,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    colors = ["rgba(30,144,255,", "rgba(107,142,35,", "rgba(255,215,0,",
 | 
				
			||||||
 | 
					        "rgba(255,192,203,", "rgba(106,90,205,", "rgba(173,216,230,",
 | 
				
			||||||
 | 
					        "rgba(238,130,238,", "rgba(152,251,152,", "rgba(70,130,180,",
 | 
				
			||||||
 | 
					        "rgba(244,164,96,", "rgba(210,105,30,", "rgba(220,20,60,"];
 | 
				
			||||||
 | 
					    streamingConfetti = false;
 | 
				
			||||||
 | 
					    animationTimer = null;
 | 
				
			||||||
 | 
					    lastFrameTime = Date.now();
 | 
				
			||||||
 | 
					    particles = [];
 | 
				
			||||||
 | 
					    waveAngle = 0;
 | 
				
			||||||
 | 
					    context = null;
 | 
				
			||||||
 | 
					    supportsAnimationFrame = window.requestAnimationFrame ||
 | 
				
			||||||
 | 
					        window.webkitRequestAnimationFrame ||
 | 
				
			||||||
 | 
					        window.mozRequestAnimationFrame ||
 | 
				
			||||||
 | 
					        window.oRequestAnimationFrame ||
 | 
				
			||||||
 | 
					        window.msRequestAnimationFrame;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    resetParticle(particle, width, height) {
 | 
				
			||||||
 | 
					        particle.color = this.colors[(Math.random() * this.colors.length) | 0] + (this.confetti.alpha + ")");
 | 
				
			||||||
 | 
					        particle.color2 = this.colors[(Math.random() * this.colors.length) | 0] + (this.confetti.alpha + ")");
 | 
				
			||||||
 | 
					        particle.x = Math.random() * width;
 | 
				
			||||||
 | 
					        particle.y = Math.random() * height - height;
 | 
				
			||||||
 | 
					        particle.diameter = Math.random() * 10 + 5;
 | 
				
			||||||
 | 
					        particle.tilt = Math.random() * 10 - 10;
 | 
				
			||||||
 | 
					        particle.tiltAngleIncrement = Math.random() * 0.07 + 0.05;
 | 
				
			||||||
 | 
					        particle.tiltAngle = Math.random() * Math.PI;
 | 
				
			||||||
 | 
					        return particle;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    startConfetti(timeout) {
 | 
				
			||||||
 | 
					        const width = window.innerWidth;
 | 
				
			||||||
 | 
					        const height = window.innerHeight;
 | 
				
			||||||
 | 
					        window.requestAnimationFrame = () => {
 | 
				
			||||||
 | 
					            return window.requestAnimationFrame ||
 | 
				
			||||||
 | 
					                window.webkitRequestAnimationFrame ||
 | 
				
			||||||
 | 
					                window.mozRequestAnimationFrame ||
 | 
				
			||||||
 | 
					                window.oRequestAnimationFrame ||
 | 
				
			||||||
 | 
					                window.msRequestAnimationFrame ||
 | 
				
			||||||
 | 
					                function(callback) {
 | 
				
			||||||
 | 
					                    return window.setTimeout(callback, this.confetti.frameInterval);
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        let canvas = document.getElementById("confetti-canvas");
 | 
				
			||||||
 | 
					        if (canvas === null) {
 | 
				
			||||||
 | 
					            canvas = document.createElement("canvas");
 | 
				
			||||||
 | 
					            canvas.setAttribute("id", "confetti-canvas");
 | 
				
			||||||
 | 
					            canvas.setAttribute("style", "display:block;z-index:999999;pointer-events:none;position:fixed;top:0");
 | 
				
			||||||
 | 
					            document.body.prepend(canvas);
 | 
				
			||||||
 | 
					            canvas.width = width;
 | 
				
			||||||
 | 
					            canvas.height = height;
 | 
				
			||||||
 | 
					            window.addEventListener("resize", function () {
 | 
				
			||||||
 | 
					                canvas.width = window.innerWidth;
 | 
				
			||||||
 | 
					                canvas.height = window.innerHeight;
 | 
				
			||||||
 | 
					            }, true);
 | 
				
			||||||
 | 
					            this.context = canvas.getContext("2d");
 | 
				
			||||||
 | 
					        } else if (this.context === null) {
 | 
				
			||||||
 | 
					            this.context = canvas.getContext("2d");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        const count = this.confetti.maxCount;
 | 
				
			||||||
 | 
					        while (this.particles.length < count) {
 | 
				
			||||||
 | 
					            this.particles.push(this.resetParticle({}, width, height));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        this.streamingConfetti = true;
 | 
				
			||||||
 | 
					        this.runAnimation();
 | 
				
			||||||
 | 
					        if (timeout) {
 | 
				
			||||||
 | 
					            window.setTimeout(this.stopConfetti, timeout);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    stopConfetti() {
 | 
				
			||||||
 | 
					        this.streamingConfetti = false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    runAnimation() {
 | 
				
			||||||
 | 
					        if (this.particles.length === 0) {
 | 
				
			||||||
 | 
					            this.context.clearRect(0, 0, window.innerWidth, window.innerHeight);
 | 
				
			||||||
 | 
					            this.animationTimer = null;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            const now = Date.now();
 | 
				
			||||||
 | 
					            const delta = now - this.lastFrameTime;
 | 
				
			||||||
 | 
					            if (!this.supportsAnimationFrame || delta > this.confetti.frameInterval) {
 | 
				
			||||||
 | 
					                this.context.clearRect(0, 0, window.innerWidth, window.innerHeight);
 | 
				
			||||||
 | 
					                this.updateParticles();
 | 
				
			||||||
 | 
					                this.drawParticles(this.context);
 | 
				
			||||||
 | 
					                this.lastFrameTime = now - (delta % this.confetti.frameInterval);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            this.animationTimer = requestAnimationFrame(this.runAnimation);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    removeConfetti() {
 | 
				
			||||||
 | 
					        stop();
 | 
				
			||||||
 | 
					        this.particles = [];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    isConfettiRunning() {
 | 
				
			||||||
 | 
					        return this.streamingConfetti;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    drawParticles(context) {
 | 
				
			||||||
 | 
					        let particle;
 | 
				
			||||||
 | 
					        let x;
 | 
				
			||||||
 | 
					        let x2;
 | 
				
			||||||
 | 
					        let y2;
 | 
				
			||||||
 | 
					        for (let i = 0; i < this.particles.length; i++) {
 | 
				
			||||||
 | 
					            particle = this.particles[i];
 | 
				
			||||||
 | 
					            context.beginPath();
 | 
				
			||||||
 | 
					            context.lineWidth = particle.diameter;
 | 
				
			||||||
 | 
					            x2 = particle.x + particle.tilt;
 | 
				
			||||||
 | 
					            x = x2 + particle.diameter / 2;
 | 
				
			||||||
 | 
					            y2 = particle.y + particle.tilt + particle.diameter / 2;
 | 
				
			||||||
 | 
					            context.strokeStyle = particle.color;
 | 
				
			||||||
 | 
					            context.moveTo(x, particle.y);
 | 
				
			||||||
 | 
					            context.lineTo(x2, y2);
 | 
				
			||||||
 | 
					            context.stroke();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    updateParticles() {
 | 
				
			||||||
 | 
					        const width = window.innerWidth;
 | 
				
			||||||
 | 
					        const height = window.innerHeight;
 | 
				
			||||||
 | 
					        let particle;
 | 
				
			||||||
 | 
					        this.waveAngle += 0.01;
 | 
				
			||||||
 | 
					        for (let i = 0; i < this.particles.length; i++) {
 | 
				
			||||||
 | 
					            particle = this.particles[i];
 | 
				
			||||||
 | 
					            if (!this.streamingConfetti && particle.y < -15) {
 | 
				
			||||||
 | 
					                particle.y = height + 100;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                particle.tiltAngle += particle.tiltAngleIncrement;
 | 
				
			||||||
 | 
					                particle.x += Math.sin(this.waveAngle) - 0.5;
 | 
				
			||||||
 | 
					                particle.y += (Math.cos(this.waveAngle) + particle.diameter + this.confetti.speed) * 0.5;
 | 
				
			||||||
 | 
					                particle.tilt = Math.sin(particle.tiltAngle) * 15;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (particle.x > width + 20 || particle.x < -20 || particle.y > height) {
 | 
				
			||||||
 | 
					                if (this.streamingConfetti && this.particles.length <= this.confetti.maxCount) {
 | 
				
			||||||
 | 
					                    this.resetParticle(particle, width, height);
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    this.particles.splice(i, 1);
 | 
				
			||||||
 | 
					                    i--;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    convertToHex(content) {
 | 
				
			||||||
 | 
					        const contentBodyToHexArray = [];
 | 
				
			||||||
 | 
					        let hex;
 | 
				
			||||||
 | 
					        for (let i = 0; i < content.body.length; i++) {
 | 
				
			||||||
 | 
					            hex = content.body.codePointAt(i).toString(16);
 | 
				
			||||||
 | 
					            contentBodyToHexArray.push(hex);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return contentBodyToHexArray;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    isChatEffectsDisabled() {
 | 
				
			||||||
 | 
					        console.log('return value', SettingsStore.getValue('dontShowChatEffects'));
 | 
				
			||||||
 | 
					        return SettingsStore.getValue('dontShowChatEffects');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    isConfettiEmoji(content) {
 | 
				
			||||||
 | 
					        const hexArray = this.convertToHex(content);
 | 
				
			||||||
 | 
					        return !!(hexArray.includes('1f389') || hexArray.includes('1f38a'));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     animateConfetti(userId, message) {
 | 
				
			||||||
 | 
					        // const shortendUserId = userId.slice(1).split(":").slice(0, 1);
 | 
				
			||||||
 | 
					         console.log('in animate confetti method');
 | 
				
			||||||
 | 
					        if (!this.isChatEffectsDisabled()) {
 | 
				
			||||||
 | 
					            this.confetti.start(3000);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (!message) {
 | 
				
			||||||
 | 
					            return ('*' + userId + ' throws confetti ');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    render() {
 | 
				
			||||||
 | 
					        return (<canvas id="confetti-canvas" style="display:block;z-index:999999;pointer-events:none;position:fixed;top:0"
 | 
				
			||||||
 | 
					        > </canvas>);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -2362,5 +2362,6 @@
 | 
				
			|||||||
    "Use your account to sign in to the latest version of the app at <a />": "Verwende dein Konto um dich an der neusten Version der App anzumelden<a />",
 | 
					    "Use your account to sign in to the latest version of the app at <a />": "Verwende dein Konto um dich an der neusten Version der App anzumelden<a />",
 | 
				
			||||||
    "We’re excited to announce Riot is now Element!": "Wir freuen uns bekanntzugeben: Riot ist jetzt Element!",
 | 
					    "We’re excited to announce Riot is now Element!": "Wir freuen uns bekanntzugeben: Riot ist jetzt Element!",
 | 
				
			||||||
    "Learn more at <a>element.io/previously-riot</a>": "Erfahre mehr unter <a>element.io/previously-riot</a>",
 | 
					    "Learn more at <a>element.io/previously-riot</a>": "Erfahre mehr unter <a>element.io/previously-riot</a>",
 | 
				
			||||||
    "Don't show chat effects": "Chat Effekte nicht zeigen"
 | 
					    "Don't show chat effects": "Chat Effekte nicht zeigen",
 | 
				
			||||||
 | 
					    "Throws confetti animation in the chat room": "Throws confetti animation in the chat room"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -213,6 +213,7 @@
 | 
				
			|||||||
    "Thank you!": "Thank you!",
 | 
					    "Thank you!": "Thank you!",
 | 
				
			||||||
    "Opens chat with the given user": "Opens chat with the given user",
 | 
					    "Opens chat with the given user": "Opens chat with the given user",
 | 
				
			||||||
    "Sends a message to the given user": "Sends a message to the given user",
 | 
					    "Sends a message to the given user": "Sends a message to the given user",
 | 
				
			||||||
 | 
					    "Throws confetti animation in the chat room": "Throws confetti animation in the chat room",
 | 
				
			||||||
    "Displays action": "Displays action",
 | 
					    "Displays action": "Displays action",
 | 
				
			||||||
    "Reason": "Reason",
 | 
					    "Reason": "Reason",
 | 
				
			||||||
    "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s accepted the invitation for %(displayName)s.",
 | 
					    "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s accepted the invitation for %(displayName)s.",
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user