implement multi selection for messages

This commit is contained in:
kosyak 2023-05-08 22:00:40 +03:00 committed by Konstantin Aleksashin
parent fae6a12ca1
commit e1161bcb22
413 changed files with 1691 additions and 192 deletions

View file

@ -10,7 +10,7 @@
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="36" width="36"
height="26" height="24"
id="svg2" id="svg2"
version="1.1" version="1.1"
inkscape:version="0.48.5 r10040" inkscape:version="0.48.5 r10040"
@ -90,11 +90,11 @@
opacity="0.03137255" /> opacity="0.03137255" />
<sodipodi:guide <sodipodi:guide
orientation="1,0" orientation="1,0"
position="20,26" position="20,24"
id="guide3060" /> id="guide3060" />
<sodipodi:guide <sodipodi:guide
orientation="1,0" orientation="1,0"
position="24,26" position="24,24"
id="guide3062" /> id="guide3062" />
<sodipodi:guide <sodipodi:guide
orientation="0,1" orientation="0,1"
@ -106,7 +106,7 @@
id="guide3066" /> id="guide3066" />
<sodipodi:guide <sodipodi:guide
orientation="1,0" orientation="1,0"
position="26,0" position="24,0"
id="guide3068" /> id="guide3068" />
<sodipodi:guide <sodipodi:guide
orientation="1,0" orientation="1,0"
@ -151,10 +151,10 @@
<path <path
inkscape:connector-curvature="0" inkscape:connector-curvature="0"
id="path2989" id="path2989"
d="M 4,4 16,16 16,4 z" d="M 4,4 22,16 22,4 z"
sodipodi:nodetypes="cccc" /> sodipodi:nodetypes="cccc" />
<rect <rect
ry="2" ry="16"
y="4" y="4"
x="12" x="12"
height="20" height="20"

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View file

@ -10,7 +10,7 @@
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="36" width="36"
height="26" height="24"
id="svg2" id="svg2"
version="1.1" version="1.1"
inkscape:version="0.48.5 r10040" inkscape:version="0.48.5 r10040"
@ -90,11 +90,11 @@
opacity="0.03137255" /> opacity="0.03137255" />
<sodipodi:guide <sodipodi:guide
orientation="1,0" orientation="1,0"
position="20,26" position="20,24"
id="guide3060" /> id="guide3060" />
<sodipodi:guide <sodipodi:guide
orientation="1,0" orientation="1,0"
position="24,26" position="24,24"
id="guide3062" /> id="guide3062" />
<sodipodi:guide <sodipodi:guide
orientation="0,1" orientation="0,1"
@ -106,7 +106,7 @@
id="guide3066" /> id="guide3066" />
<sodipodi:guide <sodipodi:guide
orientation="1,0" orientation="1,0"
position="26,0" position="24,0"
id="guide3068" /> id="guide3068" />
<sodipodi:guide <sodipodi:guide
orientation="1,0" orientation="1,0"
@ -151,10 +151,10 @@
<path <path
inkscape:connector-curvature="0" inkscape:connector-curvature="0"
id="path2989" id="path2989"
d="M 4,4 16,16 16,4 z" d="M 4,4 22,16 22,4 z"
sodipodi:nodetypes="cccc" /> sodipodi:nodetypes="cccc" />
<rect <rect
ry="2" ry="16"
y="4" y="4"
x="12" x="12"
height="20" height="20"

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View file

@ -0,0 +1,160 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="36"
height="24"
id="svg2"
version="1.1"
inkscape:version="0.48.5 r10040"
sodipodi:docname="message_bubble_received.svg">
<defs
id="defs4">
<filter
x="-0.25"
y="-0.25"
width="1.5"
height="1.5"
inkscape:label="Drop Shadow"
id="filter3811"
color-interpolation-filters="sRGB">
<feFlood
flood-opacity="0.25"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood3813" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite3815" />
<feGaussianBlur
stdDeviation="0.5"
result="blur"
id="feGaussianBlur3817" />
<feOffset
dx="0"
dy="1"
result="offset"
id="feOffset3819" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite3821" />
</filter>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="16"
inkscape:cx="25.745257"
inkscape:cy="9.618802"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:window-width="989"
inkscape:window-height="755"
inkscape:window-x="22"
inkscape:window-y="16"
inkscape:window-maximized="0"
showguides="true"
inkscape:guide-bbox="true"
guidecolor="#000000"
guideopacity="0.49803922">
<inkscape:grid
type="xygrid"
id="grid2985"
empspacing="4"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true"
spacingx="1px"
spacingy="1px"
originx="0px"
originy="0px"
color="#0000ff"
opacity="0.03137255" />
<sodipodi:guide
orientation="1,0"
position="20,24"
id="guide3060" />
<sodipodi:guide
orientation="1,0"
position="24,24"
id="guide3062" />
<sodipodi:guide
orientation="0,1"
position="36,22"
id="guide3064" />
<sodipodi:guide
orientation="0,1"
position="36,6"
id="guide3066" />
<sodipodi:guide
orientation="1,0"
position="24,0"
id="guide3068" />
<sodipodi:guide
orientation="1,0"
position="18,0"
id="guide3070" />
<sodipodi:guide
orientation="0,1"
position="0,10"
id="guide3074" />
<sodipodi:guide
orientation="0,1"
position="0,8"
id="guide3076" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer"
inkscape:groupmode="layer"
id="layer"
transform="translate(0,-2)">
<g
id="g3759"
style="fill:#295e2d;fill-opacity:1;stroke:none;fill-rule:nonzero;filter:url(#filter3811)">
<path
style="display:none"
d="m 8,6 c 2,2 4,6 4,10 L 16,6 z"
id="path3805"
inkscape:connector-curvature="0"
transform="translate(0,2)"
sodipodi:nodetypes="cccc" />
<rect
ry="16"
y="4"
x="12"
height="20"
width="20"
id="rect2987" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4 KiB

View file

@ -10,7 +10,7 @@
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="36" width="36"
height="26" height="24"
id="svg2" id="svg2"
version="1.1" version="1.1"
inkscape:version="0.91 r13725" inkscape:version="0.91 r13725"
@ -90,11 +90,11 @@
opacity="0.03137255" /> opacity="0.03137255" />
<sodipodi:guide <sodipodi:guide
orientation="1,0" orientation="1,0"
position="20,26" position="20,24"
id="guide3060" /> id="guide3060" />
<sodipodi:guide <sodipodi:guide
orientation="1,0" orientation="1,0"
position="24,26" position="24,24"
id="guide3062" /> id="guide3062" />
<sodipodi:guide <sodipodi:guide
orientation="0,1" orientation="0,1"
@ -106,7 +106,7 @@
id="guide3066" /> id="guide3066" />
<sodipodi:guide <sodipodi:guide
orientation="1,0" orientation="1,0"
position="26,0" position="24,0"
id="guide3068" /> id="guide3068" />
<sodipodi:guide <sodipodi:guide
orientation="1,0" orientation="1,0"
@ -151,11 +151,11 @@
<path <path
inkscape:connector-curvature="0" inkscape:connector-curvature="0"
id="path2989" id="path2989"
d="M 4,4 16,16 16,4 z" d="M 4,4 22,16 22,4 z"
sodipodi:nodetypes="cccc" sodipodi:nodetypes="cccc"
style="fill:#424242;fill-opacity:1" /> style="fill:#424242;fill-opacity:1" />
<rect <rect
ry="2" ry="16"
y="4" y="4"
x="12" x="12"
height="20" height="20"

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View file

@ -0,0 +1,161 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="36"
height="24"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="message_bubble_received_grey.svg">
<defs
id="defs4">
<filter
x="-0.25"
y="-0.25"
width="1.5"
height="1.5"
inkscape:label="Drop Shadow"
id="filter3811"
color-interpolation-filters="sRGB">
<feFlood
flood-opacity="0.25"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood3813" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite3815" />
<feGaussianBlur
stdDeviation="0.5"
result="blur"
id="feGaussianBlur3817" />
<feOffset
dx="0"
dy="1"
result="offset"
id="feOffset3819" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite3821" />
</filter>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="16"
inkscape:cx="-9.879743"
inkscape:cy="9.618802"
inkscape:document-units="px"
inkscape:current-layer="layer"
showgrid="true"
inkscape:window-width="2135"
inkscape:window-height="911"
inkscape:window-x="22"
inkscape:window-y="16"
inkscape:window-maximized="0"
showguides="true"
inkscape:guide-bbox="true"
guidecolor="#000000"
guideopacity="0.49803922">
<inkscape:grid
type="xygrid"
id="grid2985"
empspacing="4"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true"
spacingx="1px"
spacingy="1px"
originx="0px"
originy="0px"
color="#0000ff"
opacity="0.03137255" />
<sodipodi:guide
orientation="1,0"
position="20,24"
id="guide3060" />
<sodipodi:guide
orientation="1,0"
position="24,24"
id="guide3062" />
<sodipodi:guide
orientation="0,1"
position="36,22"
id="guide3064" />
<sodipodi:guide
orientation="0,1"
position="36,6"
id="guide3066" />
<sodipodi:guide
orientation="1,0"
position="24,0"
id="guide3068" />
<sodipodi:guide
orientation="1,0"
position="18,0"
id="guide3070" />
<sodipodi:guide
orientation="0,1"
position="0,10"
id="guide3074" />
<sodipodi:guide
orientation="0,1"
position="0,8"
id="guide3076" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer"
inkscape:groupmode="layer"
id="layer"
transform="translate(0,-2)">
<g
id="g3759"
style="fill:#424242;fill-opacity:1;stroke:none;fill-rule:nonzero;filter:url(#filter3811)">
<path
style="display:none;fill:#424242;fill-opacity:1"
d="m 8,6 c 2,2 4,6 4,10 L 16,6 z"
id="path3805"
inkscape:connector-curvature="0"
transform="translate(0,2)"
sodipodi:nodetypes="cccc" />
<rect
ry="16"
y="4"
x="12"
height="20"
width="20"
id="rect2987"
style="fill:#424242;fill-opacity:1" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

View file

@ -0,0 +1,161 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="36"
height="24"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="message_bubble_received_grey.svg">
<defs
id="defs4">
<filter
x="-0.25"
y="-0.25"
width="1.5"
height="1.5"
inkscape:label="Drop Shadow"
id="filter3811"
color-interpolation-filters="sRGB">
<feFlood
flood-opacity="0.25"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood3813" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite3815" />
<feGaussianBlur
stdDeviation="0.5"
result="blur"
id="feGaussianBlur3817" />
<feOffset
dx="0"
dy="1"
result="offset"
id="feOffset3819" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite3821" />
</filter>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="16"
inkscape:cx="-9.879743"
inkscape:cy="9.618802"
inkscape:document-units="px"
inkscape:current-layer="layer"
showgrid="true"
inkscape:window-width="2135"
inkscape:window-height="911"
inkscape:window-x="22"
inkscape:window-y="16"
inkscape:window-maximized="0"
showguides="true"
inkscape:guide-bbox="true"
guidecolor="#000000"
guideopacity="0.49803922">
<inkscape:grid
type="xygrid"
id="grid2985"
empspacing="4"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true"
spacingx="1px"
spacingy="1px"
originx="0px"
originy="0px"
color="#0000ff"
opacity="0.03137255" />
<sodipodi:guide
orientation="1,0"
position="20,24"
id="guide3060" />
<sodipodi:guide
orientation="1,0"
position="24,24"
id="guide3062" />
<sodipodi:guide
orientation="0,1"
position="36,22"
id="guide3064" />
<sodipodi:guide
orientation="0,1"
position="36,6"
id="guide3066" />
<sodipodi:guide
orientation="1,0"
position="24,0"
id="guide3068" />
<sodipodi:guide
orientation="1,0"
position="18,0"
id="guide3070" />
<sodipodi:guide
orientation="0,1"
position="0,10"
id="guide3074" />
<sodipodi:guide
orientation="0,1"
position="0,8"
id="guide3076" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer"
inkscape:groupmode="layer"
id="layer"
transform="translate(0,-2)">
<g
id="g3759"
style="fill:#4d8e50;fill-opacity:1;stroke:none;fill-rule:nonzero;filter:url(#filter3811)">
<path
style="display:none;fill:#424242;fill-opacity:1"
d="m 8,6 c 2,2 4,6 4,10 L 16,6 z"
id="path3805"
inkscape:connector-curvature="0"
transform="translate(0,2)"
sodipodi:nodetypes="cccc" />
<rect
ry="16"
y="4"
x="12"
height="20"
width="20"
id="rect2987"
style="fill:#4d8e50;fill-opacity:1" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View file

@ -10,7 +10,7 @@
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="36" width="36"
height="26" height="24"
id="svg2" id="svg2"
version="1.1" version="1.1"
inkscape:version="0.48.5 r10040" inkscape:version="0.48.5 r10040"
@ -90,11 +90,11 @@
opacity="0.03137255" /> opacity="0.03137255" />
<sodipodi:guide <sodipodi:guide
orientation="1,0" orientation="1,0"
position="20,26" position="20,24"
id="guide3060" /> id="guide3060" />
<sodipodi:guide <sodipodi:guide
orientation="1,0" orientation="1,0"
position="24,26" position="24,24"
id="guide3062" /> id="guide3062" />
<sodipodi:guide <sodipodi:guide
orientation="0,1" orientation="0,1"
@ -106,7 +106,7 @@
id="guide3066" /> id="guide3066" />
<sodipodi:guide <sodipodi:guide
orientation="1,0" orientation="1,0"
position="26,0" position="24,0"
id="guide3068" /> id="guide3068" />
<sodipodi:guide <sodipodi:guide
orientation="1,0" orientation="1,0"
@ -151,10 +151,10 @@
<path <path
inkscape:connector-curvature="0" inkscape:connector-curvature="0"
id="path2989" id="path2989"
d="M 4,4 16,16 16,4 z" d="M 4,4 22,16 22,4 z"
sodipodi:nodetypes="cccc" /> sodipodi:nodetypes="cccc" />
<rect <rect
ry="2" ry="16"
y="4" y="4"
x="12" x="12"
height="20" height="20"

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View file

@ -0,0 +1,160 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="36"
height="24"
id="svg2"
version="1.1"
inkscape:version="0.48.5 r10040"
sodipodi:docname="message_bubble_received.svg">
<defs
id="defs4">
<filter
x="-0.25"
y="-0.25"
width="1.5"
height="1.5"
inkscape:label="Drop Shadow"
id="filter3811"
color-interpolation-filters="sRGB">
<feFlood
flood-opacity="0.25"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood3813" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite3815" />
<feGaussianBlur
stdDeviation="0.5"
result="blur"
id="feGaussianBlur3817" />
<feOffset
dx="0"
dy="1"
result="offset"
id="feOffset3819" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite3821" />
</filter>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="16"
inkscape:cx="25.745257"
inkscape:cy="9.618802"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:window-width="989"
inkscape:window-height="755"
inkscape:window-x="22"
inkscape:window-y="16"
inkscape:window-maximized="0"
showguides="true"
inkscape:guide-bbox="true"
guidecolor="#000000"
guideopacity="0.49803922">
<inkscape:grid
type="xygrid"
id="grid2985"
empspacing="4"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true"
spacingx="1px"
spacingy="1px"
originx="0px"
originy="0px"
color="#0000ff"
opacity="0.03137255" />
<sodipodi:guide
orientation="1,0"
position="20,24"
id="guide3060" />
<sodipodi:guide
orientation="1,0"
position="24,24"
id="guide3062" />
<sodipodi:guide
orientation="0,1"
position="36,22"
id="guide3064" />
<sodipodi:guide
orientation="0,1"
position="36,6"
id="guide3066" />
<sodipodi:guide
orientation="1,0"
position="24,0"
id="guide3068" />
<sodipodi:guide
orientation="1,0"
position="18,0"
id="guide3070" />
<sodipodi:guide
orientation="0,1"
position="0,10"
id="guide3074" />
<sodipodi:guide
orientation="0,1"
position="0,8"
id="guide3076" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer"
inkscape:groupmode="layer"
id="layer"
transform="translate(0,-2)">
<g
id="g3759"
style="fill:#ad4545;fill-opacity:1;stroke:none;fill-rule:nonzero;filter:url(#filter3811)">
<path
style="display:none"
d="m 8,6 c 2,2 4,6 4,10 L 16,6 z"
id="path3805"
inkscape:connector-curvature="0"
transform="translate(0,2)"
sodipodi:nodetypes="cccc" />
<rect
ry="16"
y="4"
x="12"
height="20"
width="20"
id="rect2987" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4 KiB

View file

@ -10,7 +10,7 @@
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="36" width="36"
height="26" height="24"
id="svg2" id="svg2"
version="1.1" version="1.1"
inkscape:version="0.48.5 r10040" inkscape:version="0.48.5 r10040"
@ -90,11 +90,11 @@
opacity="0.03137255" /> opacity="0.03137255" />
<sodipodi:guide <sodipodi:guide
orientation="1,0" orientation="1,0"
position="20,26" position="20,24"
id="guide3060" /> id="guide3060" />
<sodipodi:guide <sodipodi:guide
orientation="1,0" orientation="1,0"
position="24,26" position="24,24"
id="guide3062" /> id="guide3062" />
<sodipodi:guide <sodipodi:guide
orientation="0,1" orientation="0,1"
@ -106,7 +106,7 @@
id="guide3066" /> id="guide3066" />
<sodipodi:guide <sodipodi:guide
orientation="1,0" orientation="1,0"
position="26,0" position="24,0"
id="guide3068" /> id="guide3068" />
<sodipodi:guide <sodipodi:guide
orientation="1,0" orientation="1,0"
@ -151,10 +151,10 @@
<path <path
inkscape:connector-curvature="0" inkscape:connector-curvature="0"
id="path2989" id="path2989"
d="M 4,4 16,16 16,4 z" d="M 4,4 22,16 22,4 z"
sodipodi:nodetypes="cccc" /> sodipodi:nodetypes="cccc" />
<rect <rect
ry="2" ry="16"
y="4" y="4"
x="12" x="12"
height="20" height="20"

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View file

@ -0,0 +1,160 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="36"
height="24"
id="svg2"
version="1.1"
inkscape:version="0.48.5 r10040"
sodipodi:docname="message_bubble_received.svg">
<defs
id="defs4">
<filter
x="-0.25"
y="-0.25"
width="1.5"
height="1.5"
inkscape:label="Drop Shadow"
id="filter3811"
color-interpolation-filters="sRGB">
<feFlood
flood-opacity="0.25"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood3813" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite3815" />
<feGaussianBlur
stdDeviation="0.5"
result="blur"
id="feGaussianBlur3817" />
<feOffset
dx="0"
dy="1"
result="offset"
id="feOffset3819" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite3821" />
</filter>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="16"
inkscape:cx="25.745257"
inkscape:cy="9.618802"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:window-width="989"
inkscape:window-height="755"
inkscape:window-x="22"
inkscape:window-y="16"
inkscape:window-maximized="0"
showguides="true"
inkscape:guide-bbox="true"
guidecolor="#000000"
guideopacity="0.49803922">
<inkscape:grid
type="xygrid"
id="grid2985"
empspacing="4"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true"
spacingx="1px"
spacingy="1px"
originx="0px"
originy="0px"
color="#0000ff"
opacity="0.03137255" />
<sodipodi:guide
orientation="1,0"
position="20,24"
id="guide3060" />
<sodipodi:guide
orientation="1,0"
position="24,24"
id="guide3062" />
<sodipodi:guide
orientation="0,1"
position="36,22"
id="guide3064" />
<sodipodi:guide
orientation="0,1"
position="36,6"
id="guide3066" />
<sodipodi:guide
orientation="1,0"
position="24,0"
id="guide3068" />
<sodipodi:guide
orientation="1,0"
position="18,0"
id="guide3070" />
<sodipodi:guide
orientation="0,1"
position="0,10"
id="guide3074" />
<sodipodi:guide
orientation="0,1"
position="0,8"
id="guide3076" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer"
inkscape:groupmode="layer"
id="layer"
transform="translate(0,-2)">
<g
id="g3759"
style="fill:#fafafa;fill-opacity:1;stroke:none;fill-rule:nonzero;filter:url(#filter3811)">
<path
style="display:none"
d="m 8,6 c 2,2 4,6 4,10 L 16,6 z"
id="path3805"
inkscape:connector-curvature="0"
transform="translate(0,2)"
sodipodi:nodetypes="cccc" />
<rect
ry="16"
y="4"
x="12"
height="20"
width="20"
id="rect2987" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4 KiB

View file

@ -10,7 +10,7 @@
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="36" width="36"
height="26" height="24"
id="svg2" id="svg2"
version="1.1" version="1.1"
inkscape:version="0.48.5 r10040" inkscape:version="0.48.5 r10040"
@ -90,11 +90,11 @@
opacity="0.03137255" /> opacity="0.03137255" />
<sodipodi:guide <sodipodi:guide
orientation="1,0" orientation="1,0"
position="12,26" position="12,24"
id="guide3146" /> id="guide3146" />
<sodipodi:guide <sodipodi:guide
orientation="1,0" orientation="1,0"
position="16,26" position="16,24"
id="guide3148" /> id="guide3148" />
<sodipodi:guide <sodipodi:guide
orientation="0,1" orientation="0,1"
@ -114,12 +114,12 @@
id="guide3160" /> id="guide3160" />
<sodipodi:guide <sodipodi:guide
orientation="0,1" orientation="0,1"
position="0,20" position="0,10"
id="guide3162" /> id="guide3074" />
<sodipodi:guide <sodipodi:guide
orientation="0,1" orientation="0,1"
position="0,18" position="0,8"
id="guide3164" /> id="guide3076" />
</sodipodi:namedview> </sodipodi:namedview>
<metadata <metadata
id="metadata7"> id="metadata7">
@ -151,10 +151,10 @@
<path <path
inkscape:connector-curvature="0" inkscape:connector-curvature="0"
id="path2989" id="path2989"
d="m 20,12 0,12 12,0 z" d="M 32,4 14,16 14,4 z"
sodipodi:nodetypes="cccc" /> sodipodi:nodetypes="cccc" />
<rect <rect
ry="2" ry="16"
y="4" y="4"
x="4" x="4"
height="20" height="20"

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View file

@ -10,7 +10,7 @@
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="36" width="36"
height="26" height="24"
id="svg2" id="svg2"
version="1.1" version="1.1"
inkscape:version="0.91 r13725" inkscape:version="0.91 r13725"
@ -90,11 +90,11 @@
opacity="0.03137255" /> opacity="0.03137255" />
<sodipodi:guide <sodipodi:guide
orientation="1,0" orientation="1,0"
position="12,26" position="12,24"
id="guide3146" /> id="guide3146" />
<sodipodi:guide <sodipodi:guide
orientation="1,0" orientation="1,0"
position="16,26" position="16,24"
id="guide3148" /> id="guide3148" />
<sodipodi:guide <sodipodi:guide
orientation="0,1" orientation="0,1"
@ -114,12 +114,12 @@
id="guide3160" /> id="guide3160" />
<sodipodi:guide <sodipodi:guide
orientation="0,1" orientation="0,1"
position="0,20" position="0,10"
id="guide3162" /> id="guide3074" />
<sodipodi:guide <sodipodi:guide
orientation="0,1" orientation="0,1"
position="0,18" position="0,8"
id="guide3164" /> id="guide3076" />
</sodipodi:namedview> </sodipodi:namedview>
<metadata <metadata
id="metadata7"> id="metadata7">
@ -151,11 +151,11 @@
<path <path
inkscape:connector-curvature="0" inkscape:connector-curvature="0"
id="path2989" id="path2989"
d="m 20,12 0,12 12,0 z" d="M 14,4 32,4 14,16 z"
sodipodi:nodetypes="cccc" sodipodi:nodetypes="cccc"
style="fill:#424242;fill-opacity:1" /> style="fill:#424242;fill-opacity:1" />
<rect <rect
ry="2" ry="16"
y="4" y="4"
x="4" x="4"
height="20" height="20"

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View file

@ -0,0 +1,161 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="36"
height="24"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="message_bubble_sent_grey.svg">
<defs
id="defs4">
<filter
x="-0.25"
y="-0.25"
width="1.5"
height="1.5"
inkscape:label="Drop Shadow"
id="filter3811"
color-interpolation-filters="sRGB">
<feFlood
flood-opacity="0.25"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood3813" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite3815" />
<feGaussianBlur
stdDeviation="0.5"
result="blur"
id="feGaussianBlur3817" />
<feOffset
dx="0"
dy="1"
result="offset"
id="feOffset3819" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite3821" />
</filter>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="16"
inkscape:cx="6.244862"
inkscape:cy="16.118802"
inkscape:document-units="px"
inkscape:current-layer="layer"
showgrid="true"
inkscape:window-width="1554"
inkscape:window-height="900"
inkscape:window-x="878"
inkscape:window-y="369"
inkscape:window-maximized="0"
showguides="true"
inkscape:guide-bbox="true"
guidecolor="#404040"
guideopacity="0.49803922">
<inkscape:grid
type="xygrid"
id="grid2985"
empspacing="4"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true"
spacingx="1px"
spacingy="1px"
originx="0px"
originy="0px"
color="#0000ff"
opacity="0.03137255" />
<sodipodi:guide
orientation="1,0"
position="12,24"
id="guide3146" />
<sodipodi:guide
orientation="1,0"
position="16,24"
id="guide3148" />
<sodipodi:guide
orientation="0,1"
position="36,22"
id="guide3150" />
<sodipodi:guide
orientation="0,1"
position="36,6"
id="guide3152" />
<sodipodi:guide
orientation="1,0"
position="18,0"
id="guide3154" />
<sodipodi:guide
orientation="1,0"
position="10,0"
id="guide3160" />
<sodipodi:guide
orientation="0,1"
position="0,10"
id="guide3074" />
<sodipodi:guide
orientation="0,1"
position="0,8"
id="guide3076" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer"
inkscape:groupmode="layer"
id="layer"
transform="translate(0,-2)">
<g
id="g3759"
style="fill:#424242;fill-opacity:1;stroke:none;fill-rule:nonzero;filter:url(#filter3811)">
<path
style="display:none;fill:#424242;fill-opacity:1"
d="M 28,18 C 26,16 24,12 24,8 l -4,10 z"
id="path3809"
inkscape:connector-curvature="0"
transform="translate(0,2)"
sodipodi:nodetypes="cccc" />
<rect
ry="16"
y="4"
x="4"
height="20"
width="20"
id="rect2987"
style="fill:#424242;fill-opacity:1" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

View file

@ -0,0 +1,161 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="36"
height="24"
id="svg2"
version="1.1"
inkscape:version="0.48.5 r10040"
sodipodi:docname="message_bubble_sent.svg">
<defs
id="defs4">
<filter
x="-0.25"
y="-0.25"
width="1.5"
height="1.5"
inkscape:label="Drop Shadow"
id="filter3811"
color-interpolation-filters="sRGB">
<feFlood
flood-opacity="0.25"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood3813" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite3815" />
<feGaussianBlur
stdDeviation="0.5"
result="blur"
id="feGaussianBlur3817" />
<feOffset
dx="0"
dy="1"
result="offset"
id="feOffset3819" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite3821" />
</filter>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="16"
inkscape:cx="14.269338"
inkscape:cy="16.118802"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:window-width="989"
inkscape:window-height="755"
inkscape:window-x="434"
inkscape:window-y="16"
inkscape:window-maximized="0"
showguides="true"
inkscape:guide-bbox="true"
guidecolor="#404040"
guideopacity="0.49803922">
<inkscape:grid
type="xygrid"
id="grid2985"
empspacing="4"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true"
spacingx="1px"
spacingy="1px"
originx="0px"
originy="0px"
color="#0000ff"
opacity="0.03137255" />
<sodipodi:guide
orientation="1,0"
position="12,24"
id="guide3146" />
<sodipodi:guide
orientation="1,0"
position="16,24"
id="guide3148" />
<sodipodi:guide
orientation="0,1"
position="36,22"
id="guide3150" />
<sodipodi:guide
orientation="0,1"
position="36,6"
id="guide3152" />
<sodipodi:guide
orientation="1,0"
position="18,0"
id="guide3154" />
<sodipodi:guide
orientation="1,0"
position="10,0"
id="guide3160" />
<sodipodi:guide
orientation="0,1"
position="0,10"
id="guide3074" />
<sodipodi:guide
orientation="0,1"
position="0,8"
id="guide3076" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer"
inkscape:groupmode="layer"
id="layer"
transform="translate(0,-2)">
<g
id="g3759"
style="fill:#fafafa;fill-opacity:1;stroke:none;fill-rule:nonzero;filter:url(#filter3811)">
<path
style="display:none"
d="M 28,18 C 26,16 24,12 24,8 l -4,10 z"
id="path3809"
inkscape:connector-curvature="0"
transform="translate(0,2)"
sodipodi:nodetypes="cccc" />
<rect
ry="16"
y="4"
x="4"
height="20"
width="20"
id="rect2987" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4 KiB

View file

@ -71,12 +71,19 @@ images = {
'ic_verified_fingerprint.svg' => ['ic_verified_fingerprint', 36], 'ic_verified_fingerprint.svg' => ['ic_verified_fingerprint', 36],
'qrcode-scan.svg' => ['ic_qr_code_scan_white_24dp', 24], 'qrcode-scan.svg' => ['ic_qr_code_scan_white_24dp', 24],
'message_bubble_received.svg' => ['message_bubble_received.9', 0], 'message_bubble_received.svg' => ['message_bubble_received.9', 0],
'message_bubble_received_non_first.svg' => ['message_bubble_received_non_first.9', 0],
'message_bubble_received_grey.svg' => ['message_bubble_received_grey.9', 0], 'message_bubble_received_grey.svg' => ['message_bubble_received_grey.9', 0],
'message_bubble_received_grey_non_first.svg' => ['message_bubble_received_grey_non_first.9', 0],
'message_bubble_received_dark.svg' => ['message_bubble_received_dark.9', 0], 'message_bubble_received_dark.svg' => ['message_bubble_received_dark.9', 0],
'message_bubble_received_dark_non_first.svg' => ['message_bubble_received_dark_non_first.9', 0],
'message_bubble_received_warning.svg' => ['message_bubble_received_warning.9', 0], 'message_bubble_received_warning.svg' => ['message_bubble_received_warning.9', 0],
'message_bubble_received_warning_non_first.svg' => ['message_bubble_received_warning_non_first.9', 0],
'message_bubble_received_white.svg' => ['message_bubble_received_white.9', 0], 'message_bubble_received_white.svg' => ['message_bubble_received_white.9', 0],
'message_bubble_received_white_non_first.svg' => ['message_bubble_received_white_non_first.9', 0],
'message_bubble_sent.svg' => ['message_bubble_sent.9', 0], 'message_bubble_sent.svg' => ['message_bubble_sent.9', 0],
'message_bubble_sent_non_first.svg' => ['message_bubble_sent_non_first.9', 0],
'message_bubble_sent_grey.svg' => ['message_bubble_sent_grey.9', 0], 'message_bubble_sent_grey.svg' => ['message_bubble_sent_grey.9', 0],
'message_bubble_sent_grey_non_first.svg' => ['message_bubble_send_grey_non_first.9', 0],
'date_bubble_white.svg' => ['date_bubble_white.9', 0], 'date_bubble_white.svg' => ['date_bubble_white.9', 0],
'date_bubble_grey.svg' => ['date_bubble_grey.9', 0], 'date_bubble_grey.svg' => ['date_bubble_grey.9', 0],
'marker.svg' => ['marker', 0] 'marker.svg' => ['marker', 0]
@ -112,9 +119,9 @@ images.each do |source_filename, settings|
output_parts = output_filename.split('/') output_parts = output_filename.split('/')
path = if output_parts.count != 2 path = if output_parts.count != 2
"../src/main/res/drawable-#{resolution}/#{output_filename}.png" "/Users/kaleksashin/Documents/Conversations/src/main/res/drawable-#{resolution}/#{output_filename}.png"
else else
"../src/#{output_parts[0]}/res/drawable-#{resolution}/#{output_parts[1]}.png" "/Users/kaleksashin/Documents/Conversations/src/#{output_parts[0]}/res/drawable-#{resolution}/#{output_parts[1]}.png"
end end
execute_cmd "#{inkscape} #{source_filename} -C -w #{width.to_i} -h #{height.to_i} --export-filename=#{path}" execute_cmd "#{inkscape} #{source_filename} -C -w #{width.to_i} -h #{height.to_i} --export-filename=#{path}"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 798 B

After

Width:  |  Height:  |  Size: 809 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 554 B

After

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 49 KiB

BIN
src/main/.DS_Store vendored Normal file

Binary file not shown.

View file

@ -91,7 +91,7 @@ public final class Config {
public static final Bitmap.CompressFormat IMAGE_FORMAT = Bitmap.CompressFormat.JPEG; public static final Bitmap.CompressFormat IMAGE_FORMAT = Bitmap.CompressFormat.JPEG;
public static final int IMAGE_QUALITY = 75; public static final int IMAGE_QUALITY = 75;
public static final int MESSAGE_MERGE_WINDOW = 20; public static final int MESSAGE_MERGE_WINDOW = 30;
public static final int PAGE_SIZE = 50; public static final int PAGE_SIZE = 50;
public static final int MAX_NUM_PAGES = 3; public static final int MAX_NUM_PAGES = 3;

View file

@ -464,11 +464,6 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
messages.clear(); messages.clear();
messages.addAll(this.messages); messages.addAll(this.messages);
} }
for (Iterator<Message> iterator = messages.iterator(); iterator.hasNext(); ) {
if (iterator.next().wasMergedIntoPrevious()) {
iterator.remove();
}
}
} }
@Override @Override

View file

@ -639,7 +639,7 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
this.getCounterpart() != null && this.getCounterpart() != null &&
this.getCounterpart().equals(message.getCounterpart()) && this.getCounterpart().equals(message.getCounterpart()) &&
this.edited() == message.edited() && this.edited() == message.edited() &&
(message.getTimeSent() - this.getTimeSent()) <= (Config.MESSAGE_MERGE_WINDOW * 1000) && Math.abs(message.getTimeSent() - this.getTimeSent()) <= (Config.MESSAGE_MERGE_WINDOW * 1000) &&
this.getBody().length() + message.getBody().length() <= Config.MAX_DISPLAY_MESSAGE_CHARS && this.getBody().length() + message.getBody().length() <= Config.MAX_DISPLAY_MESSAGE_CHARS &&
!message.isGeoUri() && !message.isGeoUri() &&
!this.isGeoUri() && !this.isGeoUri() &&
@ -703,39 +703,14 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
public static class MergeSeparator { public static class MergeSeparator {
} }
public SpannableStringBuilder getMergedBody() { public SpannableStringBuilder getBodyForDisplaying() {
SpannableStringBuilder body = new SpannableStringBuilder(MessageUtils.filterLtrRtl(this.body).trim()); return new SpannableStringBuilder(MessageUtils.filterLtrRtl(this.body).trim());
Message current = this;
while (current.mergeable(current.next())) {
current = current.next();
if (current == null) {
break;
}
body.append("\n\n");
body.setSpan(new MergeSeparator(), body.length() - 2, body.length(),
SpannableStringBuilder.SPAN_EXCLUSIVE_EXCLUSIVE);
body.append(MessageUtils.filterLtrRtl(current.getBody()).trim());
}
return body;
} }
public boolean hasMeCommand() { public boolean hasMeCommand() {
return this.body.trim().startsWith(ME_COMMAND); return this.body.trim().startsWith(ME_COMMAND);
} }
public int getMergedStatus() {
int status = this.status;
Message current = this;
while (current.mergeable(current.next())) {
current = current.next();
if (current == null) {
break;
}
status = current.status;
}
return status;
}
public long getMergedTimeSent() { public long getMergedTimeSent() {
long time = this.timeSent; long time = this.timeSent;
Message current = this; Message current = this;
@ -749,9 +724,17 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
return time; return time;
} }
public boolean wasMergedIntoPrevious() { public int getMergedStatus() {
Message prev = this.prev(); int status = this.status;
return prev != null && prev.mergeable(this); Message current = this;
while (current.mergeable(current.next())) {
current = current.next();
if (current == null) {
break;
}
status = current.status;
}
return status;
} }
public boolean trusted() { public boolean trusted() {

View file

@ -4609,21 +4609,9 @@ public class XmppConnectionService extends Service {
} }
public void resendFailedMessages(final Message message) { public void resendFailedMessages(final Message message) {
final Collection<Message> messages = new ArrayList<>(); message.setTime(System.currentTimeMillis());
Message current = message; markMessage(message, Message.STATUS_WAITING);
while (current.getStatus() == Message.STATUS_SEND_FAILED) { this.resendMessage(message, false);
messages.add(current);
if (current.mergeable(current.next())) {
current = current.next();
} else {
break;
}
}
for (final Message msg : messages) {
msg.setTime(System.currentTimeMillis());
markMessage(msg, Message.STATUS_WAITING);
this.resendMessage(msg, false);
}
if (message.getConversation() instanceof Conversation) { if (message.getConversation() instanceof Conversation) {
((Conversation) message.getConversation()).sort(); ((Conversation) message.getConversation()).sort();
} }

View file

@ -30,6 +30,7 @@ import android.provider.MediaStore;
import android.text.Editable; import android.text.Editable;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.view.ActionMode;
import android.view.ContextMenu; import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo; import android.view.ContextMenu.ContextMenuInfo;
import android.view.Gravity; import android.view.Gravity;
@ -70,6 +71,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@ -123,7 +125,6 @@ import eu.siacs.conversations.utils.Compatibility;
import eu.siacs.conversations.utils.GeoHelper; import eu.siacs.conversations.utils.GeoHelper;
import eu.siacs.conversations.utils.MessageUtils; import eu.siacs.conversations.utils.MessageUtils;
import eu.siacs.conversations.utils.NickValidityChecker; import eu.siacs.conversations.utils.NickValidityChecker;
import eu.siacs.conversations.utils.Patterns;
import eu.siacs.conversations.utils.PermissionUtils; import eu.siacs.conversations.utils.PermissionUtils;
import eu.siacs.conversations.utils.QuickLoader; import eu.siacs.conversations.utils.QuickLoader;
import eu.siacs.conversations.utils.StylingHelper; import eu.siacs.conversations.utils.StylingHelper;
@ -192,6 +193,8 @@ public class ConversationFragment extends XmppFragment
private Toast messageLoaderToast; private Toast messageLoaderToast;
private ConversationsActivity activity; private ConversationsActivity activity;
private boolean reInitRequiredOnStart = true; private boolean reInitRequiredOnStart = true;
private ActionMode selectionActionMode;
private final OnClickListener clickToMuc = private final OnClickListener clickToMuc =
new OnClickListener() { new OnClickListener() {
@ -412,6 +415,7 @@ public class ConversationFragment extends XmppFragment
} }
}; };
private Message selectedMessage; private Message selectedMessage;
private ArrayList<Message> selectedMessages = new ArrayList<>();
private final OnClickListener mEnableAccountListener = private final OnClickListener mEnableAccountListener =
new OnClickListener() { new OnClickListener() {
@Override @Override
@ -562,6 +566,72 @@ public class ConversationFragment extends XmppFragment
} }
} }
}; };
private ActionMode.Callback actionModeCallback = new ActionMode.Callback() {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.message_select_context, menu);
unregisterForContextMenu(binding.messagesView);
selectionActionMode = mode;
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
Collections.sort(selectedMessages, (o1, o2) -> Long.compare(o1.getTimeSent(), o2.getMergedTimeSent()));
if (item.getItemId() == R.id.copy_message) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < selectedMessages.size(); i++) {
Message m = selectedMessages.get(i);
final boolean encrypted =
m.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED
|| m.getEncryption() == Message.ENCRYPTION_PGP;
final boolean unInitiatedButKnownSize = MessageUtils.unInitiatedButKnownSize(m);
final Transferable t = m.getTransferable();
if (!encrypted
&& !unInitiatedButKnownSize
&& t == null) {
sb.append(m.getBodyForDisplaying());
if (i < selectedMessages.size() - 1) {
sb.append("\n\n");
}
}
}
ShareUtil.copyToClipboard(activity, sb);
} else if (item.getItemId() == R.id.share_message) {
ShareUtil.share(activity, selectedMessages);
}
if (selectionActionMode != null) {
selectionActionMode.finish();
}
return true;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
selectionActionMode = null;
registerForContextMenu(binding.messagesView);
selectedMessages.clear();
messageListAdapter.notifyDataSetChanged();
}
};
private int completionIndex = 0; private int completionIndex = 0;
private int lastCompletionLength = 0; private int lastCompletionLength = 0;
private String incomplete; private String incomplete;
@ -688,14 +758,6 @@ public class ConversationFragment extends XmppFragment
for (int i = 0; i < messages.size(); ++i) { for (int i = 0; i < messages.size(); ++i) {
if (uuid.equals(messages.get(i).getUuid())) { if (uuid.equals(messages.get(i).getUuid())) {
return i; return i;
} else {
Message next = messages.get(i);
while (next != null && next.wasMergedIntoPrevious()) {
if (uuid.equals(next.getUuid())) {
return i;
}
next = next.next();
}
} }
} }
return -1; return -1;
@ -1225,6 +1287,33 @@ public class ConversationFragment extends XmppFragment
messageListAdapter = new MessageAdapter((XmppActivity) getActivity(), this.messageList); messageListAdapter = new MessageAdapter((XmppActivity) getActivity(), this.messageList);
messageListAdapter.setOnContactPictureClicked(this); messageListAdapter.setOnContactPictureClicked(this);
messageListAdapter.setOnContactPictureLongClicked(this); messageListAdapter.setOnContactPictureLongClicked(this);
MessageAdapter.MessageEmptyPartClickListener messageClickListener = new MessageAdapter.MessageEmptyPartClickListener() {
@Override
public void onMessageEmptyPartClick(Message message) {
if (selectionActionMode != null) {
toggleMessageSelection(message);
}
}
@Override
public void onMessageEmptyPartLongClick(Message message) {
toggleMessageSelection(message);
}
};
MessageAdapter.SelectionStatusProvider provider = new MessageAdapter.SelectionStatusProvider() {
@Override
public boolean isSelected(Message message) {
return selectedMessages.contains(message);
}
@Override
public boolean isSomethingSelected() {
return !selectedMessages.isEmpty();
}
};
messageListAdapter.setMessageEmptyPartLongClickListener(messageClickListener);
messageListAdapter.setSelectionStatusProvider(provider);
binding.messagesView.setAdapter(messageListAdapter); binding.messagesView.setAdapter(messageListAdapter);
registerForContextMenu(binding.messagesView); registerForContextMenu(binding.messagesView);
@ -1278,10 +1367,6 @@ public class ConversationFragment extends XmppFragment
private void populateContextMenu(ContextMenu menu) { private void populateContextMenu(ContextMenu menu) {
final Message m = this.selectedMessage; final Message m = this.selectedMessage;
final Transferable t = m.getTransferable(); final Transferable t = m.getTransferable();
Message relevantForCorrection = m;
while (relevantForCorrection.mergeable(relevantForCorrection.next())) {
relevantForCorrection = relevantForCorrection.next();
}
if (m.getType() != Message.TYPE_STATUS && m.getType() != Message.TYPE_RTP_SESSION) { if (m.getType() != Message.TYPE_STATUS && m.getType() != Message.TYPE_RTP_SESSION) {
if (m.getEncryption() == Message.ENCRYPTION_AXOLOTL_NOT_FOR_THIS_DEVICE if (m.getEncryption() == Message.ENCRYPTION_AXOLOTL_NOT_FOR_THIS_DEVICE
@ -1319,6 +1404,7 @@ public class ConversationFragment extends XmppFragment
MenuItem cancelTransmission = menu.findItem(R.id.cancel_transmission); MenuItem cancelTransmission = menu.findItem(R.id.cancel_transmission);
MenuItem deleteFile = menu.findItem(R.id.delete_file); MenuItem deleteFile = menu.findItem(R.id.delete_file);
MenuItem showErrorMessage = menu.findItem(R.id.show_error_message); MenuItem showErrorMessage = menu.findItem(R.id.show_error_message);
MenuItem selectMessage = menu.findItem(R.id.select_message);
final boolean unInitiatedButKnownSize = MessageUtils.unInitiatedButKnownSize(m); final boolean unInitiatedButKnownSize = MessageUtils.unInitiatedButKnownSize(m);
final boolean showError = final boolean showError =
m.getStatus() == Message.STATUS_SEND_FAILED m.getStatus() == Message.STATUS_SEND_FAILED
@ -1332,7 +1418,7 @@ public class ConversationFragment extends XmppFragment
&& t == null) { && t == null) {
copyMessage.setVisible(true); copyMessage.setVisible(true);
quoteMessage.setVisible(!showError && MessageUtils.prepareQuote(m).length() > 0); quoteMessage.setVisible(!showError && MessageUtils.prepareQuote(m).length() > 0);
final String scheme = ShareUtil.getLinkScheme(m.getMergedBody()); final String scheme = ShareUtil.getLinkScheme(m.getBodyForDisplaying());
if ("xmpp".equals(scheme)) { if ("xmpp".equals(scheme)) {
copyLink.setTitle(R.string.copy_jabber_id); copyLink.setTitle(R.string.copy_jabber_id);
copyLink.setVisible(true); copyLink.setVisible(true);
@ -1344,9 +1430,9 @@ public class ConversationFragment extends XmppFragment
retryDecryption.setVisible(true); retryDecryption.setVisible(true);
} }
if (!showError if (!showError
&& relevantForCorrection.getType() == Message.TYPE_TEXT && m.getType() == Message.TYPE_TEXT
&& !m.isGeoUri() && !m.isGeoUri()
&& relevantForCorrection.isLastCorrectableMessage() && m.isLastCorrectableMessage()
&& m.getConversation() instanceof Conversation) { && m.getConversation() instanceof Conversation) {
correctMessage.setVisible(true); correctMessage.setVisible(true);
} }
@ -1402,6 +1488,8 @@ public class ConversationFragment extends XmppFragment
|| (mime != null && mime.startsWith("audio/"))) { || (mime != null && mime.startsWith("audio/"))) {
openWith.setVisible(true); openWith.setVisible(true);
} }
selectMessage.setVisible(true);
} }
} }
@ -1444,6 +1532,9 @@ public class ConversationFragment extends XmppFragment
case R.id.show_error_message: case R.id.show_error_message:
showErrorMessage(selectedMessage); showErrorMessage(selectedMessage);
return true; return true;
case R.id.select_message:
toggleMessageSelection(selectedMessage);
return true;
case R.id.open_with: case R.id.open_with:
openWith(selectedMessage); openWith(selectedMessage);
return true; return true;
@ -2085,9 +2176,6 @@ public class ConversationFragment extends XmppFragment
} }
} }
if (message != null) { if (message != null) {
while (message.next() != null && message.next().wasMergedIntoPrevious()) {
message = message.next();
}
return message.getUuid(); return message.getUuid();
} }
} }
@ -2105,6 +2193,26 @@ public class ConversationFragment extends XmppFragment
} }
} }
private void toggleMessageSelection(final Message message) {
if (selectionActionMode == null) {
activity.startActionMode(actionModeCallback);
}
if (selectedMessages.contains(message)) {
selectedMessages.remove(message);
} else {
selectedMessages.add(message);
}
if (selectedMessages.size() == 0) {
selectionActionMode.finish();
} else {
selectionActionMode.setTitle(selectedMessages.size() + "");
}
this.messageListAdapter.notifyDataSetChanged();
}
private void showErrorMessage(final Message message) { private void showErrorMessage(final Message message) {
AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity()); AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity());
builder.setTitle(R.string.error_message); builder.setTitle(R.string.error_message);
@ -2232,9 +2340,6 @@ public class ConversationFragment extends XmppFragment
} }
private void correctMessage(Message message) { private void correctMessage(Message message) {
while (message.mergeable(message.next())) {
message = message.next();
}
this.conversation.setCorrectingMessage(message); this.conversation.setCorrectingMessage(message);
final Editable editable = binding.textinput.getText(); final Editable editable = binding.textinput.getText();
this.conversation.setDraftMessage(editable.toString()); this.conversation.setDraftMessage(editable.toString());
@ -2790,6 +2895,13 @@ public class ConversationFragment extends XmppFragment
binding.unreadCountCustomView.setUnreadCount( binding.unreadCountCustomView.setUnreadCount(
conversation.getReceivedMessagesCountSinceUuid(lastMessageUuid)); conversation.getReceivedMessagesCountSinceUuid(lastMessageUuid));
} }
for (Message message : selectedMessages) {
if (!messageList.contains(message)) {
selectedMessages.remove(message);
}
}
this.messageListAdapter.notifyDataSetChanged(); this.messageListAdapter.notifyDataSetChanged();
updateChatMsgHint(); updateChatMsgHint();
if (notifyConversationRead && activity != null) { if (notifyConversationRead && activity != null) {
@ -3463,6 +3575,11 @@ public class ConversationFragment extends XmppFragment
@Override @Override
public void onContactPictureLongClicked(View v, final Message message) { public void onContactPictureLongClicked(View v, final Message message) {
if (selectionActionMode != null) {
toggleMessageSelection(message);
return;
}
final String fingerprint; final String fingerprint;
if (message.getEncryption() == Message.ENCRYPTION_PGP if (message.getEncryption() == Message.ENCRYPTION_PGP
|| message.getEncryption() == Message.ENCRYPTION_DECRYPTED) { || message.getEncryption() == Message.ENCRYPTION_DECRYPTED) {
@ -3549,6 +3666,11 @@ public class ConversationFragment extends XmppFragment
@Override @Override
public void onContactPictureClicked(Message message) { public void onContactPictureClicked(Message message) {
if (selectionActionMode != null) {
toggleMessageSelection(message);
return;
}
String fingerprint; String fingerprint;
if (message.getEncryption() == Message.ENCRYPTION_PGP if (message.getEncryption() == Message.ENCRYPTION_PGP
|| message.getEncryption() == Message.ENCRYPTION_DECRYPTED) { || message.getEncryption() == Message.ENCRYPTION_DECRYPTED) {

View file

@ -5,6 +5,8 @@ import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Outline;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.os.Build; import android.os.Build;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
@ -18,6 +20,7 @@ import android.text.style.StyleSpan;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
@ -61,6 +64,7 @@ import eu.siacs.conversations.ui.text.QuoteSpan;
import eu.siacs.conversations.ui.util.AvatarWorkerTask; import eu.siacs.conversations.ui.util.AvatarWorkerTask;
import eu.siacs.conversations.ui.util.MyLinkify; import eu.siacs.conversations.ui.util.MyLinkify;
import eu.siacs.conversations.ui.util.QuoteHelper; import eu.siacs.conversations.ui.util.QuoteHelper;
import eu.siacs.conversations.ui.util.StyledAttributes;
import eu.siacs.conversations.ui.util.ViewUtil; import eu.siacs.conversations.ui.util.ViewUtil;
import eu.siacs.conversations.ui.widget.ClickableMovementMethod; import eu.siacs.conversations.ui.widget.ClickableMovementMethod;
import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.CryptoHelper;
@ -87,9 +91,12 @@ public class MessageAdapter extends ArrayAdapter<Message> {
private final DisplayMetrics metrics; private final DisplayMetrics metrics;
private OnContactPictureClicked mOnContactPictureClickedListener; private OnContactPictureClicked mOnContactPictureClickedListener;
private OnContactPictureLongClicked mOnContactPictureLongClickedListener; private OnContactPictureLongClicked mOnContactPictureLongClickedListener;
private MessageEmptyPartClickListener messageEmptyPartClickListener;
private SelectionStatusProvider selectionStatusProvider;
private boolean mUseGreenBackground = false; private boolean mUseGreenBackground = false;
private final boolean mForceNames; private final boolean mForceNames;
public MessageAdapter(final XmppActivity activity, final List<Message> messages, final boolean forceNames) { public MessageAdapter(final XmppActivity activity, final List<Message> messages, final boolean forceNames) {
super(activity, 0, messages); super(activity, 0, messages);
this.audioPlayer = new AudioPlayer(this); this.audioPlayer = new AudioPlayer(this);
@ -103,6 +110,28 @@ public class MessageAdapter extends ArrayAdapter<Message> {
this(activity, messages, false); this(activity, messages, false);
} }
@Override
public boolean areAllItemsEnabled() {
return false;
}
@Override
public boolean isEnabled(int position) {
boolean enabled;
switch (getItemViewType(position)) {
case SENT:
case RECEIVED:
enabled = true;
break;
default:
enabled = false;
}
return enabled;
}
private static void resetClickListener(View... views) { private static void resetClickListener(View... views) {
for (View view : views) { for (View view : views) {
view.setOnClickListener(null); view.setOnClickListener(null);
@ -134,6 +163,17 @@ public class MessageAdapter extends ArrayAdapter<Message> {
this.mOnContactPictureLongClickedListener = listener; this.mOnContactPictureLongClickedListener = listener;
} }
public void setMessageEmptyPartLongClickListener(
MessageEmptyPartClickListener listener) {
this.messageEmptyPartClickListener = listener;
}
public void setSelectionStatusProvider(
SelectionStatusProvider provider) {
this.selectionStatusProvider = provider;
}
@Override @Override
public int getViewTypeCount() { public int getViewTypeCount() {
return 5; return 5;
@ -431,7 +471,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
if (message.getBody() != null) { if (message.getBody() != null) {
final String nick = UIHelper.getMessageDisplayName(message); final String nick = UIHelper.getMessageDisplayName(message);
SpannableStringBuilder body = message.getMergedBody(); SpannableStringBuilder body = message.getBodyForDisplaying();
boolean hasMeCommand = message.hasMeCommand(); boolean hasMeCommand = message.hasMeCommand();
if (hasMeCommand) { if (hasMeCommand) {
body = body.replace(0, Message.ME_COMMAND.length(), nick + " "); body = body.replace(0, Message.ME_COMMAND.length(), nick + " ");
@ -621,21 +661,26 @@ public class MessageAdapter extends ArrayAdapter<Message> {
ViewHolder viewHolder; ViewHolder viewHolder;
if (view == null) { if (view == null) {
viewHolder = new ViewHolder(); viewHolder = new ViewHolder();
switch (type) { switch (type) {
case DATE_SEPARATOR: case DATE_SEPARATOR:
view = activity.getLayoutInflater().inflate(R.layout.message_date_bubble, parent, false); view = activity.getLayoutInflater().inflate(R.layout.message_date_bubble, parent, false);
viewHolder.root = view;
viewHolder.status_message = view.findViewById(R.id.message_body); viewHolder.status_message = view.findViewById(R.id.message_body);
viewHolder.message_box = view.findViewById(R.id.message_box); viewHolder.message_box = view.findViewById(R.id.message_box);
viewHolder.indicatorReceived = view.findViewById(R.id.indicator_received); viewHolder.indicatorReceived = view.findViewById(R.id.indicator_received);
break; break;
case RTP_SESSION: case RTP_SESSION:
view = activity.getLayoutInflater().inflate(R.layout.message_rtp_session, parent, false); view = activity.getLayoutInflater().inflate(R.layout.message_rtp_session, parent, false);
viewHolder.root = view;
viewHolder.status_message = view.findViewById(R.id.message_body); viewHolder.status_message = view.findViewById(R.id.message_body);
viewHolder.message_box = view.findViewById(R.id.message_box); viewHolder.message_box = view.findViewById(R.id.message_box);
viewHolder.indicatorReceived = view.findViewById(R.id.indicator_received); viewHolder.indicatorReceived = view.findViewById(R.id.indicator_received);
break; break;
case SENT: case SENT:
view = activity.getLayoutInflater().inflate(R.layout.message_sent, parent, false); view = activity.getLayoutInflater().inflate(R.layout.message_sent, parent, false);
viewHolder.clicksInterceptor = view.findViewById(R.id.clicks_interceptor);
viewHolder.root = view;
viewHolder.message_box = view.findViewById(R.id.message_box); viewHolder.message_box = view.findViewById(R.id.message_box);
viewHolder.contact_picture = view.findViewById(R.id.message_photo); viewHolder.contact_picture = view.findViewById(R.id.message_photo);
viewHolder.download_button = view.findViewById(R.id.download_button); viewHolder.download_button = view.findViewById(R.id.download_button);
@ -649,6 +694,8 @@ public class MessageAdapter extends ArrayAdapter<Message> {
break; break;
case RECEIVED: case RECEIVED:
view = activity.getLayoutInflater().inflate(R.layout.message_received, parent, false); view = activity.getLayoutInflater().inflate(R.layout.message_received, parent, false);
viewHolder.clicksInterceptor = view.findViewById(R.id.clicks_interceptor);
viewHolder.root = view;
viewHolder.message_box = view.findViewById(R.id.message_box); viewHolder.message_box = view.findViewById(R.id.message_box);
viewHolder.contact_picture = view.findViewById(R.id.message_photo); viewHolder.contact_picture = view.findViewById(R.id.message_photo);
viewHolder.download_button = view.findViewById(R.id.download_button); viewHolder.download_button = view.findViewById(R.id.download_button);
@ -663,6 +710,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
break; break;
case STATUS: case STATUS:
view = activity.getLayoutInflater().inflate(R.layout.message_status, parent, false); view = activity.getLayoutInflater().inflate(R.layout.message_status, parent, false);
viewHolder.root = view;
viewHolder.contact_picture = view.findViewById(R.id.message_photo); viewHolder.contact_picture = view.findViewById(R.id.message_photo);
viewHolder.status_message = view.findViewById(R.id.status_message); viewHolder.status_message = view.findViewById(R.id.status_message);
viewHolder.load_more_messages = view.findViewById(R.id.load_more_messages); viewHolder.load_more_messages = view.findViewById(R.id.load_more_messages);
@ -748,6 +796,26 @@ public class MessageAdapter extends ArrayAdapter<Message> {
resetClickListener(viewHolder.message_box, viewHolder.messageBody); resetClickListener(viewHolder.message_box, viewHolder.messageBody);
View.OnLongClickListener messageItemLongClickListener = v -> {
if (messageEmptyPartClickListener != null) {
messageEmptyPartClickListener.onMessageEmptyPartLongClick(message);
}
return messageEmptyPartClickListener != null;
};
View.OnClickListener messageItemClickListener = v -> {
if (messageEmptyPartClickListener != null) {
messageEmptyPartClickListener.onMessageEmptyPartClick(message);
}
};
viewHolder.root.setOnLongClickListener(messageItemLongClickListener);
viewHolder.root.setOnClickListener(messageItemClickListener);
viewHolder.clicksInterceptor.setOnClickListener(messageItemClickListener);
viewHolder.clicksInterceptor.setOnLongClickListener(messageItemLongClickListener);
viewHolder.contact_picture.setOnClickListener(v -> { viewHolder.contact_picture.setOnClickListener(v -> {
if (MessageAdapter.this.mOnContactPictureClickedListener != null) { if (MessageAdapter.this.mOnContactPictureClickedListener != null) {
MessageAdapter.this.mOnContactPictureClickedListener MessageAdapter.this.mOnContactPictureClickedListener
@ -765,6 +833,15 @@ public class MessageAdapter extends ArrayAdapter<Message> {
} }
}); });
viewHolder.clicksInterceptor.setVisibility(
(selectionStatusProvider != null && selectionStatusProvider.isSomethingSelected())
? View.VISIBLE : View.GONE);
if (selectionStatusProvider == null || !selectionStatusProvider.isSelected(message)) {
viewHolder.root.setBackground(null);
} else {
viewHolder.root.setBackgroundColor(StyledAttributes.getColor(view.getContext(), R.attr.color_message_selection));
}
final Transferable transferable = message.getTransferable(); final Transferable transferable = message.getTransferable();
final boolean unInitiatedButKnownSize = MessageUtils.unInitiatedButKnownSize(message); final boolean unInitiatedButKnownSize = MessageUtils.unInitiatedButKnownSize(message);
if (unInitiatedButKnownSize || message.isDeleted() || (transferable != null && transferable.getStatus() != Transferable.STATUS_UPLOADING)) { if (unInitiatedButKnownSize || message.isDeleted() || (transferable != null && transferable.getStatus() != Transferable.STATUS_UPLOADING)) {
@ -827,18 +904,33 @@ public class MessageAdapter extends ArrayAdapter<Message> {
} }
} }
boolean mergeableWithPrev = message.mergeable(message.prev());
boolean mergeableWithNext = message.mergeable(message.next());
if (type == RECEIVED) { if (type == RECEIVED) {
if (isInValidSession) { if (isInValidSession) {
int bubble; int bubble;
if (!mUseGreenBackground) { if (!mUseGreenBackground) {
if (mergeableWithPrev) {
bubble = activity.getThemeResource(R.attr.message_bubble_received_monochrome_non_first, R.drawable.message_bubble_received_white_non_first);
} else {
bubble = activity.getThemeResource(R.attr.message_bubble_received_monochrome, R.drawable.message_bubble_received_white); bubble = activity.getThemeResource(R.attr.message_bubble_received_monochrome, R.drawable.message_bubble_received_white);
}
} else {
if (mergeableWithPrev) {
bubble = activity.getThemeResource(R.attr.message_bubble_received_green_non_first, R.drawable.message_bubble_received_white_non_first);
} else { } else {
bubble = activity.getThemeResource(R.attr.message_bubble_received_green, R.drawable.message_bubble_received); bubble = activity.getThemeResource(R.attr.message_bubble_received_green, R.drawable.message_bubble_received);
} }
}
viewHolder.message_box.setBackgroundResource(bubble); viewHolder.message_box.setBackgroundResource(bubble);
viewHolder.encryption.setVisibility(View.GONE); viewHolder.encryption.setVisibility(View.GONE);
} else {
if (mergeableWithPrev) {
viewHolder.message_box.setBackgroundResource(R.drawable.message_bubble_received_warning_non_first);
} else { } else {
viewHolder.message_box.setBackgroundResource(R.drawable.message_bubble_received_warning); viewHolder.message_box.setBackgroundResource(R.drawable.message_bubble_received_warning);
}
viewHolder.encryption.setVisibility(View.VISIBLE); viewHolder.encryption.setVisibility(View.VISIBLE);
if (omemoEncryption && !message.isTrusted()) { if (omemoEncryption && !message.isTrusted()) {
viewHolder.encryption.setText(R.string.not_trusted); viewHolder.encryption.setText(R.string.not_trusted);
@ -848,11 +940,49 @@ public class MessageAdapter extends ArrayAdapter<Message> {
} }
} }
if (type == SENT) {
int bubble;
if (mergeableWithPrev) {
bubble = activity.getThemeResource(R.attr.message_bubble_sent_non_first, R.drawable.message_bubble_sent_non_first);
} else {
bubble = activity.getThemeResource(R.attr.message_bubble_sent, R.drawable.message_bubble_sent);
}
viewHolder.message_box.setBackgroundResource(bubble);
}
displayStatus(viewHolder, message, type, darkBackground); displayStatus(viewHolder, message, type, darkBackground);
if (viewHolder.contact_picture != null)
viewHolder.contact_picture.setVisibility(mergeableWithPrev ? View.INVISIBLE : View.VISIBLE);
if (viewHolder.edit_indicator != null)
viewHolder.edit_indicator.setVisibility(mergeableWithNext ? View.GONE : viewHolder.edit_indicator.getVisibility());
if (viewHolder.encryption != null)
viewHolder.encryption.setVisibility(mergeableWithNext ? View.GONE : viewHolder.encryption.getVisibility());
if (viewHolder.indicator != null)
viewHolder.indicator.setVisibility(mergeableWithNext ? View.GONE : viewHolder.indicator.getVisibility());
// if (viewHolder.time != null)
// viewHolder.time.setVisibility(mergeableWithNext ? View.GONE : View.VISIBLE);
if (viewHolder.indicatorReceived != null)
viewHolder.indicatorReceived.setVisibility(mergeableWithNext ? View.GONE : viewHolder.indicatorReceived.getVisibility());
if (mergeableWithPrev && mergeableWithNext) {
view.setPadding(view.getPaddingLeft(), 0, view.getPaddingRight(), 0);
} else if (mergeableWithPrev) {
view.setPadding(view.getPaddingLeft(), 0, view.getPaddingRight(), dpToPx(4));
} else if (mergeableWithNext) {
view.setPadding(view.getPaddingLeft(), dpToPx(4), view.getPaddingRight(), 0);
} else {
view.setPadding(view.getPaddingLeft(), dpToPx(4), view.getPaddingRight(), dpToPx(4));
}
return view; return view;
} }
private static int dpToPx(int dp) {
return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}
private void promptOpenKeychainInstall(View view) { private void promptOpenKeychainInstall(View view) {
activity.showInstallPgpDialog(); activity.showInstallPgpDialog();
} }
@ -911,7 +1041,18 @@ public class MessageAdapter extends ArrayAdapter<Message> {
void onContactPictureLongClicked(View v, Message message); void onContactPictureLongClicked(View v, Message message);
} }
public interface MessageEmptyPartClickListener {
void onMessageEmptyPartClick(Message message);
void onMessageEmptyPartLongClick(Message message);
}
public interface SelectionStatusProvider {
boolean isSelected(Message message);
boolean isSomethingSelected();
}
private static class ViewHolder { private static class ViewHolder {
public View root;
public Button load_more_messages; public Button load_more_messages;
public ImageView edit_indicator; public ImageView edit_indicator;
@ -926,5 +1067,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
protected ImageView contact_picture; protected ImageView contact_picture;
protected TextView status_message; protected TextView status_message;
protected TextView encryption; protected TextView encryption;
protected View clicksInterceptor;
} }
} }

View file

@ -35,6 +35,10 @@ import android.net.Uri;
import android.text.SpannableStringBuilder; import android.text.SpannableStringBuilder;
import android.widget.Toast; import android.widget.Toast;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import eu.siacs.conversations.R; import eu.siacs.conversations.R;
import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.entities.DownloadableFile;
import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.Message;
@ -53,7 +57,7 @@ public class ShareUtil {
shareIntent.putExtra(Intent.EXTRA_TEXT, message.getBody()); shareIntent.putExtra(Intent.EXTRA_TEXT, message.getBody());
shareIntent.setType("text/plain"); shareIntent.setType("text/plain");
} else if (!message.isFileOrImage()) { } else if (!message.isFileOrImage()) {
shareIntent.putExtra(Intent.EXTRA_TEXT, message.getMergedBody().toString()); shareIntent.putExtra(Intent.EXTRA_TEXT, message.getBodyForDisplaying().toString());
shareIntent.setType("text/plain"); shareIntent.setType("text/plain");
shareIntent.putExtra(ConversationsActivity.EXTRA_AS_QUOTE, message.getStatus() == Message.STATUS_RECEIVED); shareIntent.putExtra(ConversationsActivity.EXTRA_AS_QUOTE, message.getStatus() == Message.STATUS_RECEIVED);
} else { } else {
@ -79,8 +83,78 @@ public class ShareUtil {
} }
} }
public static void share(XmppActivity activity, List<Message> messages) {
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
ArrayList<Uri> files = new ArrayList<>();
File firstFile = null;
String firstFileMimeType = "";
for (Message m : messages) {
if (m.isFileOrImage()) {
final DownloadableFile file = activity.xmppConnectionService.getFileBackend().getFile(m);
if (firstFile == null) {
firstFile = file;
firstFileMimeType = m.getMimeType();
}
files.add(FileBackend.getUriForFile(activity, file));
}
}
try {
shareIntent.putExtra(Intent.EXTRA_STREAM, files);
} catch (SecurityException e) {
String filePath = "";
if (firstFile != null) {
filePath = firstFile.getAbsolutePath();
}
Toast.makeText(activity, activity.getString(R.string.no_permission_to_access_x, filePath), Toast.LENGTH_SHORT).show();
return;
}
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
String mime = firstFileMimeType;
if (mime == null || files.size() > 1) {
mime = "*/*";
}
shareIntent.setType(mime);
StringBuilder sb = new StringBuilder();
for (Message m : messages) {
if (sb.length() != 0) {
sb.append("\n\n");
}
if (m.isGeoUri()) {
sb.append(m.getBody());
} else if (!m.isFileOrImage()) {
sb.append(m.getBodyForDisplaying());
}
}
shareIntent.putExtra(Intent.EXTRA_TEXT, sb.toString());
if (files.isEmpty()) {
shareIntent.setType("text/plain");
}
try {
activity.startActivity(Intent.createChooser(shareIntent, activity.getText(R.string.share_with)));
} catch (ActivityNotFoundException e) {
//This should happen only on faulty androids because normally chooser is always available
Toast.makeText(activity, R.string.no_application_found_to_open_file, Toast.LENGTH_SHORT).show();
}
}
public static void copyToClipboard(XmppActivity activity, Message message) { public static void copyToClipboard(XmppActivity activity, Message message) {
if (activity.copyTextToClipboard(message.getMergedBody().toString(), R.string.message)) { if (activity.copyTextToClipboard(message.getBodyForDisplaying().toString(), R.string.message)) {
Toast.makeText(activity, R.string.message_copied_to_clipboard, Toast.LENGTH_SHORT).show();
}
}
public static void copyToClipboard(XmppActivity activity, StringBuilder sb) {
if (activity.copyTextToClipboard(sb.toString(), R.string.message)) {
Toast.makeText(activity, R.string.message_copied_to_clipboard, Toast.LENGTH_SHORT).show(); Toast.makeText(activity, R.string.message_copied_to_clipboard, Toast.LENGTH_SHORT).show();
} }
} }
@ -105,7 +179,7 @@ public class ShareUtil {
} }
public static void copyLinkToClipboard(final XmppActivity activity, final Message message) { public static void copyLinkToClipboard(final XmppActivity activity, final Message message) {
final SpannableStringBuilder body = message.getMergedBody(); final SpannableStringBuilder body = message.getBodyForDisplaying();
for (final String url : MyLinkify.extractLinks(body)) { for (final String url : MyLinkify.extractLinks(body)) {
final Uri uri = Uri.parse(url); final Uri uri = Uri.parse(url);
if ("xmpp".equals(uri.getScheme())) { if ("xmpp".equals(uri.getScheme())) {

View file

@ -63,7 +63,7 @@ public class MessageUtils {
} }
body = nick + " " + message.getBody().substring(Message.ME_COMMAND.length()); body = nick + " " + message.getBody().substring(Message.ME_COMMAND.length());
} else { } else {
body = message.getMergedBody().toString(); body = message.getBodyForDisplaying().toString();
} }
for (String line : body.split("\n")) { for (String line : body.split("\n")) {
if (!(line.length() <= 0) && QuoteHelper.isNestedTooDeeply(line)) { if (!(line.length() <= 0) && QuoteHelper.isNestedTooDeeply(line)) {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 657 B

After

Width:  |  Height:  |  Size: 693 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 689 B

After

Width:  |  Height:  |  Size: 725 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 717 B

After

Width:  |  Height:  |  Size: 770 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 574 B

After

Width:  |  Height:  |  Size: 541 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 762 B

After

Width:  |  Height:  |  Size: 709 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 610 B

After

Width:  |  Height:  |  Size: 567 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 471 B

After

Width:  |  Height:  |  Size: 447 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 461 B

After

Width:  |  Height:  |  Size: 444 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4 KiB

After

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 971 B

After

Width:  |  Height:  |  Size: 1,019 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,010 B

After

Width:  |  Height:  |  Size: 948 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 987 B

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 967 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 790 B

After

Width:  |  Height:  |  Size: 793 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 884 B

After

Width:  |  Height:  |  Size: 884 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 657 B

After

Width:  |  Height:  |  Size: 676 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 675 B

After

Width:  |  Height:  |  Size: 657 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 887 B

After

Width:  |  Height:  |  Size: 888 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 982 B

After

Width:  |  Height:  |  Size: 993 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 800 B

After

Width:  |  Height:  |  Size: 849 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 844 B

After

Width:  |  Height:  |  Size: 799 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 487 B

After

Width:  |  Height:  |  Size: 511 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 540 B

After

Width:  |  Height:  |  Size: 566 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 435 B

After

Width:  |  Height:  |  Size: 469 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 447 B

After

Width:  |  Height:  |  Size: 448 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 540 B

After

Width:  |  Height:  |  Size: 572 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,017 B

After

Width:  |  Height:  |  Size: 1,010 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 844 B

After

Width:  |  Height:  |  Size: 883 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 878 B

After

Width:  |  Height:  |  Size: 824 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 772 B

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 773 B

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 750 B

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 776 B

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 779 B

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 687 B

After

Width:  |  Height:  |  Size: 1.3 KiB

Some files were not shown because too many files have changed in this diff Show more