Merge branch 'main' of https://git.extera.xyz/OfficialDakari/ExteraNext
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/sh
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
exec ./fluffychat
|
||||
exec ./extera_next
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
extera.svg
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
exec ./extera_next
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
[Desktop Entry]
|
||||
Type=Application
|
||||
Version=1.0
|
||||
Name=FluffyChat
|
||||
Name=Extera Next
|
||||
Comment=Matrix Client. Chat with your friends
|
||||
Exec=AppRun
|
||||
Icon=fluffychat
|
||||
Icon=extera
|
||||
Terminal=false
|
||||
Categories=Network;Chat;InstantMessaging;X-Matrix;
|
||||
Categories=Network;Chat;InstantMessaging;X-Matrix;
|
||||
|
|
@ -0,0 +1 @@
|
|||
assets/banner.png
assetassets/banner.pngassets/banner_transparent.png
assetassets/banner_transparent.pngassets/favicon.png
assetassets/favicon.pngassets/info-logo.png
assetassets/info-logo.pngassets/js/olm.zip
assetassets/js/olm.zipassets/logo.png
assetassets/logo.pngassets/logo.svg
assetassets/logo.svgassets/logo_transparent.png
assetassets/logo_transparent.pngassets/sas-emoji.json
assetassets/sas-emoji.jsonassets/sounds/call.ogg
assetassets/sounds/call.oggassets/sounds/notification.ogg
assetassets/sounds/notification.oggassets/sounds/phone.ogg
assetassets/sounds/phone.ogg2packages/cupertino_icons/assets/CupertinoIcons.ttf
asset2packages/cupertino_icons/assets/CupertinoIcons.ttf4packages/flutter_map/lib/assets/flutter_map_logo.png
asset4packages/flutter_map/lib/assets/flutter_map_logo.png2packages/handy_window/assets/handy-window-dark.css
asset2packages/handy_window/assets/handy-window-dark.css-packages/handy_window/assets/handy-window.css
asset-packages/handy_window/assets/handy-window.css(packages/material/lib/fonts/material.ttf
asset(packages/material/lib/fonts/material.ttf7packages/record_web/assets/js/record.fixwebmduration.js
asset7packages/record_web/assets/js/record.fixwebmduration.js/packages/record_web/assets/js/record.worklet.js
asset/packages/record_web/assets/js/record.worklet.js)packages/wakelock_plus/assets/no_sleep.js
asset)packages/wakelock_plus/assets/no_sleep.js
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"assets/banner.png":["assets/banner.png"],"assets/banner_transparent.png":["assets/banner_transparent.png"],"assets/favicon.png":["assets/favicon.png"],"assets/info-logo.png":["assets/info-logo.png"],"assets/js/olm.zip":["assets/js/olm.zip"],"assets/logo.png":["assets/logo.png"],"assets/logo.svg":["assets/logo.svg"],"assets/logo_transparent.png":["assets/logo_transparent.png"],"assets/sas-emoji.json":["assets/sas-emoji.json"],"assets/sounds/call.ogg":["assets/sounds/call.ogg"],"assets/sounds/notification.ogg":["assets/sounds/notification.ogg"],"assets/sounds/phone.ogg":["assets/sounds/phone.ogg"],"packages/cupertino_icons/assets/CupertinoIcons.ttf":["packages/cupertino_icons/assets/CupertinoIcons.ttf"],"packages/flutter_map/lib/assets/flutter_map_logo.png":["packages/flutter_map/lib/assets/flutter_map_logo.png"],"packages/handy_window/assets/handy-window-dark.css":["packages/handy_window/assets/handy-window-dark.css"],"packages/handy_window/assets/handy-window.css":["packages/handy_window/assets/handy-window.css"],"packages/material/lib/fonts/material.ttf":["packages/material/lib/fonts/material.ttf"],"packages/record_web/assets/js/record.fixwebmduration.js":["packages/record_web/assets/js/record.fixwebmduration.js"],"packages/record_web/assets/js/record.worklet.js":["packages/record_web/assets/js/record.worklet.js"],"packages/wakelock_plus/assets/no_sleep.js":["packages/wakelock_plus/assets/no_sleep.js"]}
|
||||
|
|
@ -0,0 +1 @@
|
|||
[{"family":"MaterialIcons","fonts":[{"asset":"fonts/MaterialIcons-Regular.otf"}]},{"family":"packages/material/Material","fonts":[{"asset":"packages/material/lib/fonts/material.ttf"}]},{"family":"packages/cupertino_icons/CupertinoIcons","fonts":[{"asset":"packages/cupertino_icons/assets/CupertinoIcons.ttf"}]}]
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"format-version":[1,0,0],"native-assets":{}}
|
||||
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
|
@ -0,0 +1 @@
|
|||
Not Found
|
||||
|
After Width: | Height: | Size: 16 KiB |
|
|
@ -0,0 +1,11 @@
|
|||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 70.82 81.78">
|
||||
<defs>
|
||||
<linearGradient id="a" x1="0" x2="0" y1="0" y2="1">
|
||||
<stop offset="0%" stop-color="#406FBF" />
|
||||
<stop offset="100%" stop-color="#23509D" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path fill-rule="evenodd"
|
||||
d="M70.82 44.98v16.36l-17.7 10.22-17.71 10.22-2.59-1.5L0 61.34V20.45l17.7-10.23L35.41 0l28.33 16.36 4.49 2.59 2.59 1.5v8.17L35.41 49.07l-7.08-4.09V36.8l21.25-12.27-14.17-8.17-21.25 12.26v24.54l21.25 12.26.03.02.02-.05z"
|
||||
style="fill:url(#a)" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 545 B |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
|
@ -0,0 +1 @@
|
|||
window{background-color:#252525}window.csd.unified decoration-overlay{box-shadow:none}window.csd.unified:not(.solid-csd):not(.fullscreen):not(.maximized) decoration-overlay{box-shadow:inset 0 0 0 1px rgba(255,255,255,.07)}window.csd.unified decoration{box-shadow:0 3px 9px 1px rgba(0,0,0,.5)}window.csd.unified decoration:backdrop{box-shadow:0 3px 9px 1px rgba(0,0,0,0),0 2px 6px 2px rgba(0,0,0,.2)}headerbar{min-height:47px;background:#303030;box-shadow:inset 0 -1px rgba(0,0,0,.36);border:none}headerbar:backdrop{background:#242424}button.titlebutton{padding:4px;margin:1px}
|
||||
|
|
@ -0,0 +1 @@
|
|||
window{background-color:#fff}window.csd.unified decoration-overlay{box-shadow:none}window.csd.unified:not(.solid-csd):not(.fullscreen):not(.maximized) decoration-overlay{box-shadow:inset 0 0 0 1px rgba(255,255,255,.07)}window.csd.unified decoration{box-shadow:0 3px 9px 1px rgba(0,0,0,.5)}window.csd.unified decoration:backdrop{box-shadow:0 3px 9px 1px rgba(0,0,0,0),0 2px 6px 2px rgba(0,0,0,.2)}headerbar{min-height:47px;background:#ebebeb;box-shadow:inset 0 -1px rgba(0,0,0,.07);border:none}headerbar:backdrop{background:#fafafa}button.titlebutton{padding:4px;margin:1px}
|
||||
|
|
@ -0,0 +1,507 @@
|
|||
(function (name, definition) {
|
||||
window.jsFixWebmDuration = definition();
|
||||
})('fix-webm-duration', function () {
|
||||
/*
|
||||
* This is the list of possible WEBM file sections by their IDs.
|
||||
* Possible types: Container, Binary, Uint, Int, String, Float, Date
|
||||
*/
|
||||
var sections = {
|
||||
0xa45dfa3: { name: 'EBML', type: 'Container' },
|
||||
0x286: { name: 'EBMLVersion', type: 'Uint' },
|
||||
0x2f7: { name: 'EBMLReadVersion', type: 'Uint' },
|
||||
0x2f2: { name: 'EBMLMaxIDLength', type: 'Uint' },
|
||||
0x2f3: { name: 'EBMLMaxSizeLength', type: 'Uint' },
|
||||
0x282: { name: 'DocType', type: 'String' },
|
||||
0x287: { name: 'DocTypeVersion', type: 'Uint' },
|
||||
0x285: { name: 'DocTypeReadVersion', type: 'Uint' },
|
||||
0x6c: { name: 'Void', type: 'Binary' },
|
||||
0x3f: { name: 'CRC-32', type: 'Binary' },
|
||||
0xb538667: { name: 'SignatureSlot', type: 'Container' },
|
||||
0x3e8a: { name: 'SignatureAlgo', type: 'Uint' },
|
||||
0x3e9a: { name: 'SignatureHash', type: 'Uint' },
|
||||
0x3ea5: { name: 'SignaturePublicKey', type: 'Binary' },
|
||||
0x3eb5: { name: 'Signature', type: 'Binary' },
|
||||
0x3e5b: { name: 'SignatureElements', type: 'Container' },
|
||||
0x3e7b: { name: 'SignatureElementList', type: 'Container' },
|
||||
0x2532: { name: 'SignedElement', type: 'Binary' },
|
||||
0x8538067: { name: 'Segment', type: 'Container' },
|
||||
0x14d9b74: { name: 'SeekHead', type: 'Container' },
|
||||
0xdbb: { name: 'Seek', type: 'Container' },
|
||||
0x13ab: { name: 'SeekID', type: 'Binary' },
|
||||
0x13ac: { name: 'SeekPosition', type: 'Uint' },
|
||||
0x549a966: { name: 'Info', type: 'Container' },
|
||||
0x33a4: { name: 'SegmentUID', type: 'Binary' },
|
||||
0x3384: { name: 'SegmentFilename', type: 'String' },
|
||||
0x1cb923: { name: 'PrevUID', type: 'Binary' },
|
||||
0x1c83ab: { name: 'PrevFilename', type: 'String' },
|
||||
0x1eb923: { name: 'NextUID', type: 'Binary' },
|
||||
0x1e83bb: { name: 'NextFilename', type: 'String' },
|
||||
0x444: { name: 'SegmentFamily', type: 'Binary' },
|
||||
0x2924: { name: 'ChapterTranslate', type: 'Container' },
|
||||
0x29fc: { name: 'ChapterTranslateEditionUID', type: 'Uint' },
|
||||
0x29bf: { name: 'ChapterTranslateCodec', type: 'Uint' },
|
||||
0x29a5: { name: 'ChapterTranslateID', type: 'Binary' },
|
||||
0xad7b1: { name: 'TimecodeScale', type: 'Uint' },
|
||||
0x489: { name: 'Duration', type: 'Float' },
|
||||
0x461: { name: 'DateUTC', type: 'Date' },
|
||||
0x3ba9: { name: 'Title', type: 'String' },
|
||||
0xd80: { name: 'MuxingApp', type: 'String' },
|
||||
0x1741: { name: 'WritingApp', type: 'String' },
|
||||
// 0xf43b675: { name: 'Cluster', type: 'Container' },
|
||||
0x67: { name: 'Timecode', type: 'Uint' },
|
||||
0x1854: { name: 'SilentTracks', type: 'Container' },
|
||||
0x18d7: { name: 'SilentTrackNumber', type: 'Uint' },
|
||||
0x27: { name: 'Position', type: 'Uint' },
|
||||
0x2b: { name: 'PrevSize', type: 'Uint' },
|
||||
0x23: { name: 'SimpleBlock', type: 'Binary' },
|
||||
0x20: { name: 'BlockGroup', type: 'Container' },
|
||||
0x21: { name: 'Block', type: 'Binary' },
|
||||
0x22: { name: 'BlockVirtual', type: 'Binary' },
|
||||
0x35a1: { name: 'BlockAdditions', type: 'Container' },
|
||||
0x26: { name: 'BlockMore', type: 'Container' },
|
||||
0x6e: { name: 'BlockAddID', type: 'Uint' },
|
||||
0x25: { name: 'BlockAdditional', type: 'Binary' },
|
||||
0x1b: { name: 'BlockDuration', type: 'Uint' },
|
||||
0x7a: { name: 'ReferencePriority', type: 'Uint' },
|
||||
0x7b: { name: 'ReferenceBlock', type: 'Int' },
|
||||
0x7d: { name: 'ReferenceVirtual', type: 'Int' },
|
||||
0x24: { name: 'CodecState', type: 'Binary' },
|
||||
0x35a2: { name: 'DiscardPadding', type: 'Int' },
|
||||
0xe: { name: 'Slices', type: 'Container' },
|
||||
0x68: { name: 'TimeSlice', type: 'Container' },
|
||||
0x4c: { name: 'LaceNumber', type: 'Uint' },
|
||||
0x4d: { name: 'FrameNumber', type: 'Uint' },
|
||||
0x4b: { name: 'BlockAdditionID', type: 'Uint' },
|
||||
0x4e: { name: 'Delay', type: 'Uint' },
|
||||
0x4f: { name: 'SliceDuration', type: 'Uint' },
|
||||
0x48: { name: 'ReferenceFrame', type: 'Container' },
|
||||
0x49: { name: 'ReferenceOffset', type: 'Uint' },
|
||||
0x4a: { name: 'ReferenceTimeCode', type: 'Uint' },
|
||||
0x2f: { name: 'EncryptedBlock', type: 'Binary' },
|
||||
0x654ae6b: { name: 'Tracks', type: 'Container' },
|
||||
0x2e: { name: 'TrackEntry', type: 'Container' },
|
||||
0x57: { name: 'TrackNumber', type: 'Uint' },
|
||||
0x33c5: { name: 'TrackUID', type: 'Uint' },
|
||||
0x3: { name: 'TrackType', type: 'Uint' },
|
||||
0x39: { name: 'FlagEnabled', type: 'Uint' },
|
||||
0x8: { name: 'FlagDefault', type: 'Uint' },
|
||||
0x15aa: { name: 'FlagForced', type: 'Uint' },
|
||||
0x1c: { name: 'FlagLacing', type: 'Uint' },
|
||||
0x2de7: { name: 'MinCache', type: 'Uint' },
|
||||
0x2df8: { name: 'MaxCache', type: 'Uint' },
|
||||
0x3e383: { name: 'DefaultDuration', type: 'Uint' },
|
||||
0x34e7a: { name: 'DefaultDecodedFieldDuration', type: 'Uint' },
|
||||
0x3314f: { name: 'TrackTimecodeScale', type: 'Float' },
|
||||
0x137f: { name: 'TrackOffset', type: 'Int' },
|
||||
0x15ee: { name: 'MaxBlockAdditionID', type: 'Uint' },
|
||||
0x136e: { name: 'Name', type: 'String' },
|
||||
0x2b59c: { name: 'Language', type: 'String' },
|
||||
0x6: { name: 'CodecID', type: 'String' },
|
||||
0x23a2: { name: 'CodecPrivate', type: 'Binary' },
|
||||
0x58688: { name: 'CodecName', type: 'String' },
|
||||
0x3446: { name: 'AttachmentLink', type: 'Uint' },
|
||||
0x1a9697: { name: 'CodecSettings', type: 'String' },
|
||||
0x1b4040: { name: 'CodecInfoURL', type: 'String' },
|
||||
0x6b240: { name: 'CodecDownloadURL', type: 'String' },
|
||||
0x2a: { name: 'CodecDecodeAll', type: 'Uint' },
|
||||
0x2fab: { name: 'TrackOverlay', type: 'Uint' },
|
||||
0x16aa: { name: 'CodecDelay', type: 'Uint' },
|
||||
0x16bb: { name: 'SeekPreRoll', type: 'Uint' },
|
||||
0x2624: { name: 'TrackTranslate', type: 'Container' },
|
||||
0x26fc: { name: 'TrackTranslateEditionUID', type: 'Uint' },
|
||||
0x26bf: { name: 'TrackTranslateCodec', type: 'Uint' },
|
||||
0x26a5: { name: 'TrackTranslateTrackID', type: 'Binary' },
|
||||
0x60: { name: 'Video', type: 'Container' },
|
||||
0x1a: { name: 'FlagInterlaced', type: 'Uint' },
|
||||
0x13b8: { name: 'StereoMode', type: 'Uint' },
|
||||
0x13c0: { name: 'AlphaMode', type: 'Uint' },
|
||||
0x13b9: { name: 'OldStereoMode', type: 'Uint' },
|
||||
0x30: { name: 'PixelWidth', type: 'Uint' },
|
||||
0x3a: { name: 'PixelHeight', type: 'Uint' },
|
||||
0x14aa: { name: 'PixelCropBottom', type: 'Uint' },
|
||||
0x14bb: { name: 'PixelCropTop', type: 'Uint' },
|
||||
0x14cc: { name: 'PixelCropLeft', type: 'Uint' },
|
||||
0x14dd: { name: 'PixelCropRight', type: 'Uint' },
|
||||
0x14b0: { name: 'DisplayWidth', type: 'Uint' },
|
||||
0x14ba: { name: 'DisplayHeight', type: 'Uint' },
|
||||
0x14b2: { name: 'DisplayUnit', type: 'Uint' },
|
||||
0x14b3: { name: 'AspectRatioType', type: 'Uint' },
|
||||
0xeb524: { name: 'ColourSpace', type: 'Binary' },
|
||||
0xfb523: { name: 'GammaValue', type: 'Float' },
|
||||
0x383e3: { name: 'FrameRate', type: 'Float' },
|
||||
0x61: { name: 'Audio', type: 'Container' },
|
||||
0x35: { name: 'SamplingFrequency', type: 'Float' },
|
||||
0x38b5: { name: 'OutputSamplingFrequency', type: 'Float' },
|
||||
0x1f: { name: 'Channels', type: 'Uint' },
|
||||
0x3d7b: { name: 'ChannelPositions', type: 'Binary' },
|
||||
0x2264: { name: 'BitDepth', type: 'Uint' },
|
||||
0x62: { name: 'TrackOperation', type: 'Container' },
|
||||
0x63: { name: 'TrackCombinePlanes', type: 'Container' },
|
||||
0x64: { name: 'TrackPlane', type: 'Container' },
|
||||
0x65: { name: 'TrackPlaneUID', type: 'Uint' },
|
||||
0x66: { name: 'TrackPlaneType', type: 'Uint' },
|
||||
0x69: { name: 'TrackJoinBlocks', type: 'Container' },
|
||||
0x6d: { name: 'TrackJoinUID', type: 'Uint' },
|
||||
0x40: { name: 'TrickTrackUID', type: 'Uint' },
|
||||
0x41: { name: 'TrickTrackSegmentUID', type: 'Binary' },
|
||||
0x46: { name: 'TrickTrackFlag', type: 'Uint' },
|
||||
0x47: { name: 'TrickMasterTrackUID', type: 'Uint' },
|
||||
0x44: { name: 'TrickMasterTrackSegmentUID', type: 'Binary' },
|
||||
0x2d80: { name: 'ContentEncodings', type: 'Container' },
|
||||
0x2240: { name: 'ContentEncoding', type: 'Container' },
|
||||
0x1031: { name: 'ContentEncodingOrder', type: 'Uint' },
|
||||
0x1032: { name: 'ContentEncodingScope', type: 'Uint' },
|
||||
0x1033: { name: 'ContentEncodingType', type: 'Uint' },
|
||||
0x1034: { name: 'ContentCompression', type: 'Container' },
|
||||
0x254: { name: 'ContentCompAlgo', type: 'Uint' },
|
||||
0x255: { name: 'ContentCompSettings', type: 'Binary' },
|
||||
0x1035: { name: 'ContentEncryption', type: 'Container' },
|
||||
0x7e1: { name: 'ContentEncAlgo', type: 'Uint' },
|
||||
0x7e2: { name: 'ContentEncKeyID', type: 'Binary' },
|
||||
0x7e3: { name: 'ContentSignature', type: 'Binary' },
|
||||
0x7e4: { name: 'ContentSigKeyID', type: 'Binary' },
|
||||
0x7e5: { name: 'ContentSigAlgo', type: 'Uint' },
|
||||
0x7e6: { name: 'ContentSigHashAlgo', type: 'Uint' },
|
||||
0xc53bb6b: { name: 'Cues', type: 'Container' },
|
||||
0x3b: { name: 'CuePoint', type: 'Container' },
|
||||
0x33: { name: 'CueTime', type: 'Uint' },
|
||||
0x37: { name: 'CueTrackPositions', type: 'Container' },
|
||||
0x77: { name: 'CueTrack', type: 'Uint' },
|
||||
0x71: { name: 'CueClusterPosition', type: 'Uint' },
|
||||
0x70: { name: 'CueRelativePosition', type: 'Uint' },
|
||||
0x32: { name: 'CueDuration', type: 'Uint' },
|
||||
0x1378: { name: 'CueBlockNumber', type: 'Uint' },
|
||||
0x6a: { name: 'CueCodecState', type: 'Uint' },
|
||||
0x5b: { name: 'CueReference', type: 'Container' },
|
||||
0x16: { name: 'CueRefTime', type: 'Uint' },
|
||||
0x17: { name: 'CueRefCluster', type: 'Uint' },
|
||||
0x135f: { name: 'CueRefNumber', type: 'Uint' },
|
||||
0x6b: { name: 'CueRefCodecState', type: 'Uint' },
|
||||
0x941a469: { name: 'Attachments', type: 'Container' },
|
||||
0x21a7: { name: 'AttachedFile', type: 'Container' },
|
||||
0x67e: { name: 'FileDescription', type: 'String' },
|
||||
0x66e: { name: 'FileName', type: 'String' },
|
||||
0x660: { name: 'FileMimeType', type: 'String' },
|
||||
0x65c: { name: 'FileData', type: 'Binary' },
|
||||
0x6ae: { name: 'FileUID', type: 'Uint' },
|
||||
0x675: { name: 'FileReferral', type: 'Binary' },
|
||||
0x661: { name: 'FileUsedStartTime', type: 'Uint' },
|
||||
0x662: { name: 'FileUsedEndTime', type: 'Uint' },
|
||||
0x43a770: { name: 'Chapters', type: 'Container' },
|
||||
0x5b9: { name: 'EditionEntry', type: 'Container' },
|
||||
0x5bc: { name: 'EditionUID', type: 'Uint' },
|
||||
0x5bd: { name: 'EditionFlagHidden', type: 'Uint' },
|
||||
0x5db: { name: 'EditionFlagDefault', type: 'Uint' },
|
||||
0x5dd: { name: 'EditionFlagOrdered', type: 'Uint' },
|
||||
0x36: { name: 'ChapterAtom', type: 'Container' },
|
||||
0x33c4: { name: 'ChapterUID', type: 'Uint' },
|
||||
0x1654: { name: 'ChapterStringUID', type: 'String' },
|
||||
0x11: { name: 'ChapterTimeStart', type: 'Uint' },
|
||||
0x12: { name: 'ChapterTimeEnd', type: 'Uint' },
|
||||
0x18: { name: 'ChapterFlagHidden', type: 'Uint' },
|
||||
0x598: { name: 'ChapterFlagEnabled', type: 'Uint' },
|
||||
0x2e67: { name: 'ChapterSegmentUID', type: 'Binary' },
|
||||
0x2ebc: { name: 'ChapterSegmentEditionUID', type: 'Uint' },
|
||||
0x23c3: { name: 'ChapterPhysicalEquiv', type: 'Uint' },
|
||||
0xf: { name: 'ChapterTrack', type: 'Container' },
|
||||
0x9: { name: 'ChapterTrackNumber', type: 'Uint' },
|
||||
0x0: { name: 'ChapterDisplay', type: 'Container' },
|
||||
0x5: { name: 'ChapString', type: 'String' },
|
||||
0x37c: { name: 'ChapLanguage', type: 'String' },
|
||||
0x37e: { name: 'ChapCountry', type: 'String' },
|
||||
0x2944: { name: 'ChapProcess', type: 'Container' },
|
||||
0x2955: { name: 'ChapProcessCodecID', type: 'Uint' },
|
||||
0x50d: { name: 'ChapProcessPrivate', type: 'Binary' },
|
||||
0x2911: { name: 'ChapProcessCommand', type: 'Container' },
|
||||
0x2922: { name: 'ChapProcessTime', type: 'Uint' },
|
||||
0x2933: { name: 'ChapProcessData', type: 'Binary' },
|
||||
0x254c367: { name: 'Tags', type: 'Container' },
|
||||
0x3373: { name: 'Tag', type: 'Container' },
|
||||
0x23c0: { name: 'Targets', type: 'Container' },
|
||||
0x28ca: { name: 'TargetTypeValue', type: 'Uint' },
|
||||
0x23ca: { name: 'TargetType', type: 'String' },
|
||||
0x23c5: { name: 'TagTrackUID', type: 'Uint' },
|
||||
0x23c9: { name: 'TagEditionUID', type: 'Uint' },
|
||||
0x23c4: { name: 'TagChapterUID', type: 'Uint' },
|
||||
0x23c6: { name: 'TagAttachmentUID', type: 'Uint' },
|
||||
0x27c8: { name: 'SimpleTag', type: 'Container' },
|
||||
0x5a3: { name: 'TagName', type: 'String' },
|
||||
0x47a: { name: 'TagLanguage', type: 'String' },
|
||||
0x484: { name: 'TagDefault', type: 'Uint' },
|
||||
0x487: { name: 'TagString', type: 'String' },
|
||||
0x485: { name: 'TagBinary', type: 'Binary' }
|
||||
};
|
||||
|
||||
function doInherit(newClass, baseClass) {
|
||||
newClass.prototype = Object.create(baseClass.prototype);
|
||||
newClass.prototype.constructor = newClass;
|
||||
}
|
||||
|
||||
function WebmBase(name, type) {
|
||||
this.name = name || 'Unknown';
|
||||
this.type = type || 'Unknown';
|
||||
}
|
||||
WebmBase.prototype.updateBySource = function () { };
|
||||
WebmBase.prototype.setSource = function (source) {
|
||||
this.source = source;
|
||||
this.updateBySource();
|
||||
};
|
||||
WebmBase.prototype.updateByData = function () { };
|
||||
WebmBase.prototype.setData = function (data) {
|
||||
this.data = data;
|
||||
this.updateByData();
|
||||
};
|
||||
|
||||
function WebmUint(name, type) {
|
||||
WebmBase.call(this, name, type || 'Uint');
|
||||
}
|
||||
doInherit(WebmUint, WebmBase);
|
||||
function padHex(hex) {
|
||||
return hex.length % 2 === 1 ? '0' + hex : hex;
|
||||
}
|
||||
WebmUint.prototype.updateBySource = function () {
|
||||
// use hex representation of a number instead of number value
|
||||
this.data = '';
|
||||
for (var i = 0; i < this.source.length; i++) {
|
||||
var hex = this.source[i].toString(16);
|
||||
this.data += padHex(hex);
|
||||
}
|
||||
};
|
||||
WebmUint.prototype.updateByData = function () {
|
||||
var length = this.data.length / 2;
|
||||
this.source = new Uint8Array(length);
|
||||
for (var i = 0; i < length; i++) {
|
||||
var hex = this.data.substr(i * 2, 2);
|
||||
this.source[i] = parseInt(hex, 16);
|
||||
}
|
||||
};
|
||||
WebmUint.prototype.getValue = function () {
|
||||
return parseInt(this.data, 16);
|
||||
};
|
||||
WebmUint.prototype.setValue = function (value) {
|
||||
this.setData(padHex(value.toString(16)));
|
||||
};
|
||||
|
||||
function WebmFloat(name, type) {
|
||||
WebmBase.call(this, name, type || 'Float');
|
||||
}
|
||||
doInherit(WebmFloat, WebmBase);
|
||||
WebmFloat.prototype.getFloatArrayType = function () {
|
||||
return this.source && this.source.length === 4 ? Float32Array : Float64Array;
|
||||
};
|
||||
WebmFloat.prototype.updateBySource = function () {
|
||||
var byteArray = this.source.reverse();
|
||||
var floatArrayType = this.getFloatArrayType();
|
||||
var floatArray = new floatArrayType(byteArray.buffer);
|
||||
this.data = floatArray[0];
|
||||
};
|
||||
WebmFloat.prototype.updateByData = function () {
|
||||
var floatArrayType = this.getFloatArrayType();
|
||||
var floatArray = new floatArrayType([this.data]);
|
||||
var byteArray = new Uint8Array(floatArray.buffer);
|
||||
this.source = byteArray.reverse();
|
||||
};
|
||||
WebmFloat.prototype.getValue = function () {
|
||||
return this.data;
|
||||
};
|
||||
WebmFloat.prototype.setValue = function (value) {
|
||||
this.setData(value);
|
||||
};
|
||||
|
||||
function WebmContainer(name, type) {
|
||||
WebmBase.call(this, name, type || 'Container');
|
||||
}
|
||||
doInherit(WebmContainer, WebmBase);
|
||||
WebmContainer.prototype.readByte = function () {
|
||||
return this.source[this.offset++];
|
||||
};
|
||||
WebmContainer.prototype.readUint = function () {
|
||||
var firstByte = this.readByte();
|
||||
var bytes = 8 - firstByte.toString(2).length;
|
||||
var value = firstByte - (1 << (7 - bytes));
|
||||
for (var i = 0; i < bytes; i++) {
|
||||
// don't use bit operators to support x86
|
||||
value *= 256;
|
||||
value += this.readByte();
|
||||
}
|
||||
return value;
|
||||
};
|
||||
WebmContainer.prototype.updateBySource = function () {
|
||||
this.data = [];
|
||||
for (this.offset = 0; this.offset < this.source.length; this.offset = end) {
|
||||
var id = this.readUint();
|
||||
var len = this.readUint();
|
||||
var end = Math.min(this.offset + len, this.source.length);
|
||||
var data = this.source.slice(this.offset, end);
|
||||
|
||||
var info = sections[id] || { name: 'Unknown', type: 'Unknown' };
|
||||
var ctr = WebmBase;
|
||||
switch (info.type) {
|
||||
case 'Container':
|
||||
ctr = WebmContainer;
|
||||
break;
|
||||
case 'Uint':
|
||||
ctr = WebmUint;
|
||||
break;
|
||||
case 'Float':
|
||||
ctr = WebmFloat;
|
||||
break;
|
||||
}
|
||||
var section = new ctr(info.name, info.type);
|
||||
section.setSource(data);
|
||||
this.data.push({
|
||||
id: id,
|
||||
idHex: id.toString(16),
|
||||
data: section
|
||||
});
|
||||
}
|
||||
};
|
||||
WebmContainer.prototype.writeUint = function (x, draft) {
|
||||
for (var bytes = 1, flag = 0x80; x >= flag && bytes < 8; bytes++, flag *= 0x80) { }
|
||||
|
||||
if (!draft) {
|
||||
var value = flag + x;
|
||||
for (var i = bytes - 1; i >= 0; i--) {
|
||||
// don't use bit operators to support x86
|
||||
var c = value % 256;
|
||||
this.source[this.offset + i] = c;
|
||||
value = (value - c) / 256;
|
||||
}
|
||||
}
|
||||
|
||||
this.offset += bytes;
|
||||
};
|
||||
WebmContainer.prototype.writeSections = function (draft) {
|
||||
this.offset = 0;
|
||||
for (var i = 0; i < this.data.length; i++) {
|
||||
var section = this.data[i],
|
||||
content = section.data.source,
|
||||
contentLength = content.length;
|
||||
this.writeUint(section.id, draft);
|
||||
this.writeUint(contentLength, draft);
|
||||
if (!draft) {
|
||||
this.source.set(content, this.offset);
|
||||
}
|
||||
this.offset += contentLength;
|
||||
}
|
||||
return this.offset;
|
||||
};
|
||||
WebmContainer.prototype.updateByData = function () {
|
||||
// run without accessing this.source to determine total length - need to know it to create Uint8Array
|
||||
var length = this.writeSections('draft');
|
||||
this.source = new Uint8Array(length);
|
||||
// now really write data
|
||||
this.writeSections();
|
||||
};
|
||||
WebmContainer.prototype.getSectionById = function (id) {
|
||||
for (var i = 0; i < this.data.length; i++) {
|
||||
var section = this.data[i];
|
||||
if (section.id === id) {
|
||||
return section.data;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
function WebmFile(source) {
|
||||
WebmContainer.call(this, 'File', 'File');
|
||||
this.setSource(source);
|
||||
}
|
||||
doInherit(WebmFile, WebmContainer);
|
||||
WebmFile.prototype.fixDuration = function (duration, options) {
|
||||
var logger = options && options.logger;
|
||||
if (logger === undefined) {
|
||||
logger = function (message) {
|
||||
console.log(message);
|
||||
};
|
||||
} else if (!logger) {
|
||||
logger = function () { };
|
||||
}
|
||||
|
||||
var segmentSection = this.getSectionById(0x8538067);
|
||||
if (!segmentSection) {
|
||||
logger('[fix-webm-duration] Segment section is missing');
|
||||
return false;
|
||||
}
|
||||
|
||||
var infoSection = segmentSection.getSectionById(0x549a966);
|
||||
if (!infoSection) {
|
||||
logger('[fix-webm-duration] Info section is missing');
|
||||
return false;
|
||||
}
|
||||
|
||||
var timeScaleSection = infoSection.getSectionById(0xad7b1);
|
||||
if (!timeScaleSection) {
|
||||
logger('[fix-webm-duration] TimecodeScale section is missing');
|
||||
return false;
|
||||
}
|
||||
|
||||
var durationSection = infoSection.getSectionById(0x489);
|
||||
if (durationSection) {
|
||||
if (durationSection.getValue() <= 0) {
|
||||
logger('[fix-webm-duration] Duration section is present, but the value is empty. Applying ' + duration.toLocaleString() + ' ms.');
|
||||
durationSection.setValue(duration);
|
||||
} else {
|
||||
logger('[fix-webm-duration] Duration section is present');
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
logger('[fix-webm-duration] Duration section is missing. Applying ' + duration.toLocaleString() + ' ms.');
|
||||
// append Duration section
|
||||
durationSection = new WebmFloat('Duration', 'Float');
|
||||
durationSection.setValue(duration);
|
||||
infoSection.data.push({
|
||||
id: 0x489,
|
||||
data: durationSection
|
||||
});
|
||||
}
|
||||
|
||||
// set default time scale to 1 millisecond (1000000 nanoseconds)
|
||||
timeScaleSection.setValue(1000000);
|
||||
infoSection.updateByData();
|
||||
segmentSection.updateByData();
|
||||
this.updateByData();
|
||||
|
||||
return true;
|
||||
};
|
||||
WebmFile.prototype.toBlob = function (mimeType) {
|
||||
return new Blob([this.source.buffer], { type: mimeType || 'audio/webm' });
|
||||
};
|
||||
|
||||
function fixWebmDuration(blob, duration, callback, options) {
|
||||
// The callback may be omitted - then the third argument is options
|
||||
if (typeof callback === "object") {
|
||||
options = callback;
|
||||
callback = undefined;
|
||||
}
|
||||
|
||||
if (!callback) {
|
||||
return new Promise(function (resolve) {
|
||||
fixWebmDuration(blob, duration, resolve, options);
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
var reader = new FileReader();
|
||||
reader.onloadend = function () {
|
||||
try {
|
||||
var file = new WebmFile(new Uint8Array(reader.result));
|
||||
if (file.fixDuration(duration, options)) {
|
||||
blob = file.toBlob(blob.type);
|
||||
}
|
||||
} catch (ex) {
|
||||
// ignore
|
||||
}
|
||||
callback(blob);
|
||||
};
|
||||
reader.readAsArrayBuffer(blob);
|
||||
} catch (ex) {
|
||||
callback(blob);
|
||||
}
|
||||
}
|
||||
|
||||
// Support AMD import default
|
||||
fixWebmDuration.default = fixWebmDuration;
|
||||
|
||||
return fixWebmDuration;
|
||||
});
|
||||
|
|
@ -0,0 +1,400 @@
|
|||
class RecorderProcessor extends AudioWorkletProcessor {
|
||||
static get parameterDescriptors() {
|
||||
return [
|
||||
{
|
||||
name: 'numChannels',
|
||||
defaultValue: 1,
|
||||
minValue: 1,
|
||||
maxValue: 16
|
||||
},
|
||||
{
|
||||
name: 'sampleRate',
|
||||
defaultValue: 48000,
|
||||
minValue: 8000,
|
||||
maxValue: 96000
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
// Buffer size compromise between size and process call frequency
|
||||
_bufferSize = 4096
|
||||
// The current buffer fill level
|
||||
_bytesWritten = 0
|
||||
// Buffer per channel
|
||||
_buffers = []
|
||||
// Resampler (passthrough, down or up)
|
||||
_resampler = null
|
||||
// Config
|
||||
_numChannels = 1
|
||||
_sampleRate = 48000
|
||||
|
||||
constructor(options) {
|
||||
super(options)
|
||||
|
||||
this._numChannels = options.parameterData.numChannels
|
||||
this._sampleRate = options.parameterData.sampleRate
|
||||
|
||||
// Resampler(current context sample rate, desired sample rate, num channels, buffer size)
|
||||
// num channels is always 1 since we resample after interleaving channels
|
||||
this._resampler = new Resampler(sampleRate, this._sampleRate, 1, this._bufferSize * this._numChannels)
|
||||
|
||||
this.initBuffers()
|
||||
}
|
||||
|
||||
initBuffers() {
|
||||
this._bytesWritten = 0
|
||||
this._buffers = []
|
||||
|
||||
for (let channel = 0; channel < this._numChannels; channel++) {
|
||||
this._buffers[channel] = []
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isBufferEmpty() {
|
||||
return this._bytesWritten === 0
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isBufferFull() {
|
||||
return this._bytesWritten >= this._bufferSize
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Float32Array[][]} inputs
|
||||
* @returns {boolean}
|
||||
*/
|
||||
process(inputs) {
|
||||
if (this.isBufferFull()) {
|
||||
this.flush()
|
||||
}
|
||||
|
||||
const input = inputs[0]
|
||||
|
||||
if (input.length == 0) {
|
||||
// Sometimes, Firefox doesn't give any input. Skip this frame to not fail.
|
||||
return true
|
||||
}
|
||||
|
||||
for (let channel = 0; channel < this._numChannels; channel++) {
|
||||
// Push a copy of the array.
|
||||
// The underlying implementation may reuse it which will break the recording.
|
||||
this._buffers[channel].push([...input[channel]])
|
||||
}
|
||||
|
||||
this._bytesWritten += input[0].length
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
flush() {
|
||||
let channels = []
|
||||
for (let channel = 0; channel < this._numChannels; channel++) {
|
||||
channels.push(this.mergeFloat32Arrays(this._buffers[channel], this._bytesWritten))
|
||||
}
|
||||
|
||||
let interleaved = this.interleave(channels)
|
||||
|
||||
let resampled = this._resampler.resample(interleaved)
|
||||
|
||||
this.port.postMessage(this.floatTo16BitPCM(resampled))
|
||||
|
||||
this.initBuffers()
|
||||
}
|
||||
|
||||
mergeFloat32Arrays(arrays, bytesWritten) {
|
||||
let result = new Float32Array(bytesWritten)
|
||||
var offset = 0
|
||||
|
||||
for (let i = 0; i < arrays.length; i++) {
|
||||
result.set(arrays[i], offset)
|
||||
offset += arrays[i].length
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// Interleave data from channels from LLLLRRRR to LRLRLRLR
|
||||
interleave(channels) {
|
||||
if (channels === 1) {
|
||||
return channels[0]
|
||||
}
|
||||
|
||||
var length = 0
|
||||
for (let i = 0; i < channels.length; i++) {
|
||||
length += channels[i].length
|
||||
}
|
||||
|
||||
let result = new Float32Array(length)
|
||||
|
||||
var index = 0
|
||||
var inputIndex = 0
|
||||
|
||||
while (index < length) {
|
||||
for (let i = 0; i < channels.length; i++) {
|
||||
result[index] = channels[i][inputIndex]
|
||||
index++
|
||||
}
|
||||
|
||||
inputIndex++
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
floatTo16BitPCM(input) {
|
||||
let output = new DataView(new ArrayBuffer(input.length * 2))
|
||||
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
let s = Math.max(-1, Math.min(1, input[i]))
|
||||
let s16 = s < 0 ? s * 0x8000 : s * 0x7FFF
|
||||
output.setInt16(i * 2, s16, true)
|
||||
}
|
||||
|
||||
return new Int16Array(output.buffer)
|
||||
}
|
||||
}
|
||||
|
||||
class Resampler {
|
||||
constructor(fromSampleRate, toSampleRate, channels, inputBufferSize) {
|
||||
|
||||
if (!fromSampleRate || !toSampleRate || !channels) {
|
||||
throw (new Error("Invalid settings specified for the resampler."));
|
||||
}
|
||||
this.resampler = null;
|
||||
this.fromSampleRate = fromSampleRate;
|
||||
this.toSampleRate = toSampleRate;
|
||||
this.channels = channels || 0;
|
||||
this.inputBufferSize = inputBufferSize;
|
||||
this.initialize()
|
||||
}
|
||||
|
||||
initialize() {
|
||||
if (this.fromSampleRate == this.toSampleRate) {
|
||||
|
||||
// Setup resampler bypass - Resampler just returns what was passed through
|
||||
this.resampler = (buffer) => {
|
||||
return buffer
|
||||
};
|
||||
this.ratioWeight = 1;
|
||||
|
||||
} else {
|
||||
if (this.fromSampleRate < this.toSampleRate) {
|
||||
|
||||
// Use generic linear interpolation if upsampling,
|
||||
// as linear interpolation produces a gradient that we want
|
||||
// and works fine with two input sample points per output in this case.
|
||||
this.linearInterpolation();
|
||||
this.lastWeight = 1;
|
||||
|
||||
} else {
|
||||
|
||||
// Custom resampler I wrote that doesn't skip samples
|
||||
// like standard linear interpolation in high downsampling.
|
||||
// This is more accurate than linear interpolation on downsampling.
|
||||
this.multiTap();
|
||||
this.tailExists = false;
|
||||
this.lastWeight = 0;
|
||||
}
|
||||
|
||||
// Initialize the internal buffer:
|
||||
this.initializeBuffers();
|
||||
this.ratioWeight = this.fromSampleRate / this.toSampleRate;
|
||||
}
|
||||
}
|
||||
|
||||
bufferSlice(sliceAmount) {
|
||||
|
||||
//Typed array and normal array buffer section referencing:
|
||||
try {
|
||||
return this.outputBuffer.subarray(0, sliceAmount);
|
||||
}
|
||||
catch (error) {
|
||||
try {
|
||||
//Regular array pass:
|
||||
this.outputBuffer.length = sliceAmount;
|
||||
return this.outputBuffer;
|
||||
}
|
||||
catch (error) {
|
||||
//Nightly Firefox 4 used to have the subarray function named as slice:
|
||||
return this.outputBuffer.slice(0, sliceAmount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
initializeBuffers() {
|
||||
this.outputBufferSize = (Math.ceil(this.inputBufferSize * this.toSampleRate / this.fromSampleRate / this.channels * 1.000000476837158203125) + this.channels) + this.channels;
|
||||
try {
|
||||
this.outputBuffer = new Float32Array(this.outputBufferSize);
|
||||
this.lastOutput = new Float32Array(this.channels);
|
||||
}
|
||||
catch (error) {
|
||||
this.outputBuffer = [];
|
||||
this.lastOutput = [];
|
||||
}
|
||||
}
|
||||
|
||||
linearInterpolation() {
|
||||
this.resampler = (buffer) => {
|
||||
let bufferLength = buffer.length,
|
||||
channels = this.channels,
|
||||
outLength,
|
||||
ratioWeight,
|
||||
weight,
|
||||
firstWeight,
|
||||
secondWeight,
|
||||
sourceOffset,
|
||||
outputOffset,
|
||||
outputBuffer,
|
||||
channel;
|
||||
|
||||
if ((bufferLength % channels) !== 0) {
|
||||
throw (new Error("Buffer was of incorrect sample length."));
|
||||
}
|
||||
if (bufferLength <= 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
outLength = this.outputBufferSize;
|
||||
ratioWeight = this.ratioWeight;
|
||||
weight = this.lastWeight;
|
||||
firstWeight = 0;
|
||||
secondWeight = 0;
|
||||
sourceOffset = 0;
|
||||
outputOffset = 0;
|
||||
outputBuffer = this.outputBuffer;
|
||||
|
||||
for (; weight < 1; weight += ratioWeight) {
|
||||
secondWeight = weight % 1;
|
||||
firstWeight = 1 - secondWeight;
|
||||
this.lastWeight = weight % 1;
|
||||
for (channel = 0; channel < this.channels; ++channel) {
|
||||
outputBuffer[outputOffset++] = (this.lastOutput[channel] * firstWeight) + (buffer[channel] * secondWeight);
|
||||
}
|
||||
}
|
||||
weight -= 1;
|
||||
for (bufferLength -= channels, sourceOffset = Math.floor(weight) * channels; outputOffset < outLength && sourceOffset < bufferLength;) {
|
||||
secondWeight = weight % 1;
|
||||
firstWeight = 1 - secondWeight;
|
||||
for (channel = 0; channel < this.channels; ++channel) {
|
||||
outputBuffer[outputOffset++] = (buffer[sourceOffset + ((channel > 0) ? (channel) : 0)] * firstWeight) + (buffer[sourceOffset + (channels + channel)] * secondWeight);
|
||||
}
|
||||
weight += ratioWeight;
|
||||
sourceOffset = Math.floor(weight) * channels;
|
||||
}
|
||||
for (channel = 0; channel < channels; ++channel) {
|
||||
this.lastOutput[channel] = buffer[sourceOffset++];
|
||||
}
|
||||
return this.bufferSlice(outputOffset);
|
||||
};
|
||||
}
|
||||
|
||||
multiTap() {
|
||||
this.resampler = (buffer) => {
|
||||
let bufferLength = buffer.length,
|
||||
outLength,
|
||||
output_variable_list,
|
||||
channels = this.channels,
|
||||
ratioWeight,
|
||||
weight,
|
||||
channel,
|
||||
actualPosition,
|
||||
amountToNext,
|
||||
alreadyProcessedTail,
|
||||
outputBuffer,
|
||||
outputOffset,
|
||||
currentPosition;
|
||||
|
||||
if ((bufferLength % channels) !== 0) {
|
||||
throw (new Error("Buffer was of incorrect sample length."));
|
||||
}
|
||||
if (bufferLength <= 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
outLength = this.outputBufferSize;
|
||||
output_variable_list = [];
|
||||
ratioWeight = this.ratioWeight;
|
||||
weight = 0;
|
||||
actualPosition = 0;
|
||||
amountToNext = 0;
|
||||
alreadyProcessedTail = !this.tailExists;
|
||||
this.tailExists = false;
|
||||
outputBuffer = this.outputBuffer;
|
||||
outputOffset = 0;
|
||||
currentPosition = 0;
|
||||
|
||||
for (channel = 0; channel < channels; ++channel) {
|
||||
output_variable_list[channel] = 0;
|
||||
}
|
||||
|
||||
do {
|
||||
if (alreadyProcessedTail) {
|
||||
weight = ratioWeight;
|
||||
for (channel = 0; channel < channels; ++channel) {
|
||||
output_variable_list[channel] = 0;
|
||||
}
|
||||
} else {
|
||||
weight = this.lastWeight;
|
||||
for (channel = 0; channel < channels; ++channel) {
|
||||
output_variable_list[channel] = this.lastOutput[channel];
|
||||
}
|
||||
alreadyProcessedTail = true;
|
||||
}
|
||||
while (weight > 0 && actualPosition < bufferLength) {
|
||||
amountToNext = 1 + actualPosition - currentPosition;
|
||||
if (weight >= amountToNext) {
|
||||
for (channel = 0; channel < channels; ++channel) {
|
||||
output_variable_list[channel] += buffer[actualPosition++] * amountToNext;
|
||||
}
|
||||
currentPosition = actualPosition;
|
||||
weight -= amountToNext;
|
||||
} else {
|
||||
for (channel = 0; channel < channels; ++channel) {
|
||||
output_variable_list[channel] += buffer[actualPosition + ((channel > 0) ? channel : 0)] * weight;
|
||||
}
|
||||
currentPosition += weight;
|
||||
weight = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (weight === 0) {
|
||||
for (channel = 0; channel < channels; ++channel) {
|
||||
outputBuffer[outputOffset++] = output_variable_list[channel] / ratioWeight;
|
||||
}
|
||||
} else {
|
||||
this.lastWeight = weight;
|
||||
for (channel = 0; channel < channels; ++channel) {
|
||||
this.lastOutput[channel] = output_variable_list[channel];
|
||||
}
|
||||
this.tailExists = true;
|
||||
break;
|
||||
}
|
||||
} while (actualPosition < bufferLength && outputOffset < outLength);
|
||||
return this.bufferSlice(outputOffset);
|
||||
};
|
||||
}
|
||||
|
||||
resample(buffer) {
|
||||
if (this.fromSampleRate == this.toSampleRate) {
|
||||
this.ratioWeight = 1;
|
||||
} else {
|
||||
if (this.fromSampleRate < this.toSampleRate) {
|
||||
this.lastWeight = 1;
|
||||
} else {
|
||||
this.tailExists = false;
|
||||
this.lastWeight = 0;
|
||||
}
|
||||
this.initializeBuffers();
|
||||
this.ratioWeight = this.fromSampleRate / this.toSampleRate;
|
||||
}
|
||||
return this.resampler(buffer)
|
||||
}
|
||||
}
|
||||
|
||||
registerProcessor("recorder.worklet", RecorderProcessor)
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"app_name":"extera_next","version":"2.0.0","package_name":"extera_next"}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 70.82 81.78">
|
||||
<defs>
|
||||
<linearGradient id="a" x1="0" x2="0" y1="0" y2="1">
|
||||
<stop offset="0%" stop-color="#406FBF" />
|
||||
<stop offset="100%" stop-color="#23509D" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path fill-rule="evenodd"
|
||||
d="M70.82 44.98v16.36l-17.7 10.22-17.71 10.22-2.59-1.5L0 61.34V20.45l17.7-10.23L35.41 0l28.33 16.36 4.49 2.59 2.59 1.5v8.17L35.41 49.07l-7.08-4.09V36.8l21.25-12.27-14.17-8.17-21.25 12.26v24.54l21.25 12.26.03.02.02-.05z"
|
||||
style="fill:url(#a)" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 545 B |
|
|
@ -0,0 +1,9 @@
|
|||
[Desktop Entry]
|
||||
Type=Application
|
||||
Version=1.0
|
||||
Name=Extera Next
|
||||
Comment=Matrix Client. Chat with your friends
|
||||
Exec=AppRun
|
||||
Icon=extera
|
||||
Terminal=false
|
||||
Categories=Network;Chat;InstantMessaging;X-Matrix;
|
||||
|
|
@ -2,6 +2,10 @@
|
|||
"@@locale": "en",
|
||||
"@@last_modified": "2025-06-05 12:38:37.885451",
|
||||
"noSendPermission": "You can't send messages here",
|
||||
"noMessagesYet": "No messages yet",
|
||||
"longPressToRecordVoiceMessage": "Long press to record voice message.",
|
||||
"pause": "Pause",
|
||||
"resume": "Resume",
|
||||
"@noSendPermission": {},
|
||||
"alwaysUse24HourFormat": "false",
|
||||
"@alwaysUse24HourFormat": {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,10 @@
|
|||
"@@last_modified": "2021-08-14 12:41:09.903021",
|
||||
"noSendPermission": "Вы не можете отправлять сообщения",
|
||||
"@noSendPermission": {},
|
||||
"noMessagesYet": "Нет сообщений",
|
||||
"longPressToRecordVoiceMessage": "Зажмите, чтобы записать голосовое сообщение.",
|
||||
"pause": "Пауза",
|
||||
"resume": "Продолжить",
|
||||
"alwaysUse24HourFormat": "нет",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"description": "Set to true to always display time of day in 24 hour format."
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ abstract class FluffyThemes {
|
|||
BuildContext context,
|
||||
Brightness brightness, [
|
||||
Color? seed,
|
||||
bool? pureBlack,
|
||||
bool? pureBlack,
|
||||
]) {
|
||||
final extraDarkColors = (brightness == Brightness.dark && pureBlack == true)
|
||||
? {
|
||||
|
|
@ -79,6 +79,7 @@ abstract class FluffyThemes {
|
|||
useMaterial3: true,
|
||||
brightness: brightness,
|
||||
colorScheme: colorScheme,
|
||||
useSystemColors: true,
|
||||
dividerColor: brightness == Brightness.dark
|
||||
? colorScheme.surfaceContainerHighest
|
||||
: colorScheme.surfaceContainer,
|
||||
|
|
@ -117,6 +118,8 @@ abstract class FluffyThemes {
|
|||
isColumnMode ? colorScheme.surfaceContainer.withAlpha(128) : null,
|
||||
surfaceTintColor: isColumnMode ? colorScheme.surface : null,
|
||||
backgroundColor: isColumnMode ? colorScheme.surface : null,
|
||||
actionsPadding:
|
||||
isColumnMode ? const EdgeInsets.symmetric(horizontal: 16.0) : null,
|
||||
systemOverlayStyle: SystemUiOverlayStyle(
|
||||
statusBarColor: Colors.transparent,
|
||||
statusBarIconBrightness: brightness.reversed,
|
||||
|
|
@ -139,6 +142,7 @@ abstract class FluffyThemes {
|
|||
),
|
||||
snackBarTheme: isColumnMode
|
||||
? const SnackBarThemeData(
|
||||
showCloseIcon: true,
|
||||
behavior: SnackBarBehavior.floating,
|
||||
width: FluffyThemes.columnWidth * 1.5,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -199,6 +199,30 @@ abstract class L10n {
|
|||
/// **'You can\'t send messages here'**
|
||||
String get noSendPermission;
|
||||
|
||||
/// No description provided for @noMessagesYet.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'No messages yet'**
|
||||
String get noMessagesYet;
|
||||
|
||||
/// No description provided for @longPressToRecordVoiceMessage.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Long press to record voice message.'**
|
||||
String get longPressToRecordVoiceMessage;
|
||||
|
||||
/// No description provided for @pause.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Pause'**
|
||||
String get pause;
|
||||
|
||||
/// No description provided for @resume.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Resume'**
|
||||
String get resume;
|
||||
|
||||
/// Set to true to always display time of day in 24 hour format.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nAr extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'false';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nBe extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'false';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nBn extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'false';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nBo extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'false';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nCa extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'true';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nCs extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'Vypnuto';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nDe extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'true';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nEl extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'false';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nEn extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'false';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nEo extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'false';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nEs extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'falso';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nEt extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'false';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nEu extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'false';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nFa extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'false';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nFi extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'false';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nFil extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'false';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nFr extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'true';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nGa extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'bréagach';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nGl extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'falso';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nHe extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'false';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nHi extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'false';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nHr extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'true';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nHu extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'true';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nIa extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'false';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nId extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'tidak';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nIe extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'false';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nIt extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'disattivato';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nJa extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'false';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nKa extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'false';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nKo extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'false';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nLt extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'false';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nLv extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'nē';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nNb extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'false';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nNl extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'true';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nPl extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'false';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nPt extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'false';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nRo extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'false';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nRu extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'Вы не можете отправлять сообщения';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'Нет сообщений';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Зажмите, чтобы записать голосовое сообщение.';
|
||||
|
||||
@override
|
||||
String get pause => 'Пауза';
|
||||
|
||||
@override
|
||||
String get resume => 'Продолжить';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'нет';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nSk extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'false';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nSl extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'false';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nSr extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'false';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ class L10nSv extends L10n {
|
|||
@override
|
||||
String get noSendPermission => 'You can\'t send messages here';
|
||||
|
||||
@override
|
||||
String get noMessagesYet => 'No messages yet';
|
||||
|
||||
@override
|
||||
String get longPressToRecordVoiceMessage =>
|
||||
'Long press to record voice message.';
|
||||
|
||||
@override
|
||||
String get pause => 'Pause';
|
||||
|
||||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get alwaysUse24HourFormat => 'false';
|
||||
|
||||
|
|
|
|||