commit
d8398a4af6
|
@ -12,8 +12,8 @@ FROM alpine:latest
|
|||
RUN apk add --update --no-cache lighttpd
|
||||
|
||||
ADD lighttpd.conf /etc/lighttpd/lighttpd.conf
|
||||
COPY --from=build /build/dist /app/sengi
|
||||
COPY --from=build /build/assets/docker_init /app
|
||||
COPY --from=build /build/dist /app
|
||||
COPY --from=build /build/assets/docker_init /app/start
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
|
|
24
README.md
24
README.md
|
@ -24,16 +24,21 @@ Sengi already supporting all the basics functionalities, but many minors enhanc
|
|||
|
||||
![https://raw.githubusercontent.com/NicolasConstant/sengi/master/docs/images/presentation_small.gif](https://raw.githubusercontent.com/NicolasConstant/sengi/master/docs/images/presentation_small.gif)
|
||||
|
||||
## Docker
|
||||
|
||||
A docker image is available for auto-hosting your own Sengi webapp!
|
||||
|
||||
```
|
||||
docker run -d -p 80:80 nicolasconstant/sengi
|
||||
```
|
||||
|
||||
The docker image also provide a landing page so that you can open a pop-up really easily. <br />
|
||||
It's available in ```https://your-host/start/index.html```
|
||||
|
||||
## Contact
|
||||
|
||||
* [Official Sengi Account](https://mastodon.social/@sengi_app)
|
||||
|
||||
## What's a sengi?!
|
||||
|
||||
It's a little [elephant shrew](https://en.wikipedia.org/wiki/Elephant_shrew) from Africa:
|
||||
|
||||
![Rhynchocyon petersi](https://upload.wikimedia.org/wikipedia/commons/thumb/8/81/Rhynchocyon_petersi_from_side.jpg/400px-Rhynchocyon_petersi_from_side.jpg)
|
||||
|
||||
## Contribute
|
||||
|
||||
Please see the [contributing guidelines](https://github.com/NicolasConstant/sengi/blob/master/CONTRIBUTING.md)
|
||||
|
@ -53,4 +58,11 @@ See [credits](https://github.com/NicolasConstant/sengi/blob/master/CREDITS.md)
|
|||
* [SASS](https://github.com/sass/dart-sass)
|
||||
* [Electron 8](https://github.com/electron/electron)
|
||||
|
||||
## What's a sengi?!
|
||||
|
||||
It's a little [elephant shrew](https://en.wikipedia.org/wiki/Elephant_shrew) from Africa:
|
||||
|
||||
![Rhynchocyon petersi](https://upload.wikimedia.org/wikipedia/commons/thumb/8/81/Rhynchocyon_petersi_from_side.jpg/400px-Rhynchocyon_petersi_from_side.jpg)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -15,11 +15,11 @@
|
|||
<div class="launcher-wrapper">
|
||||
<div class="launcher">
|
||||
<a href="#" class="button" title="launch sengi in popup"
|
||||
onClick="window.open('/sengi/'+'?qt='+ (new Date()).getTime(),'Sengi','toolbar=no,location=no,status=no,menubar=no,scrollbars=no, resizable=yes,width=377,height=800'); return false;">
|
||||
onClick="window.open('/../'+'?qt='+ (new Date()).getTime(),'Sengi','toolbar=no,location=no,status=no,menubar=no,scrollbars=no, resizable=yes,width=377,height=800'); return false;">
|
||||
<span class="download-button__web--label">Launch Sengi Popup</span>
|
||||
</a><br />
|
||||
|
||||
<a href="/sengi/" class="button" title="launch sengi">
|
||||
<a href="/../" class="button" title="launch sengi">
|
||||
<span class="download-button__web--label">Open Sengi</span>
|
||||
</a><br />
|
||||
</div>
|
||||
|
|
|
@ -11,4 +11,4 @@ include "mime-types.conf"
|
|||
server.pid-file = "/run/lighttpd.pid"
|
||||
index-file.names = ( "index.html", "index.htm" )
|
||||
#url.rewrite-once = ( "^sengi/(.*)" => "/sengi/index.html" )
|
||||
server.error-handler-404 = "/sengi/index.html"
|
||||
server.error-handler-404 = "/index.html"
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "sengi",
|
||||
"version": "0.31.0",
|
||||
"version": "0.31.1",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"main": "main-electron.js",
|
||||
"description": "A multi-account desktop client for Mastodon and Pleroma",
|
||||
|
|
|
@ -164,6 +164,41 @@ describe('CreateStatusComponent', () => {
|
|||
expect(result.length).toBe(1);
|
||||
});
|
||||
|
||||
it('should cound URL correctly', () => {
|
||||
const newLine = String.fromCharCode(13, 10);
|
||||
const status = `qsddq sqd qsd qsdqs dqsd qsd qsd qsd qsd qsd qsd qsd qsd qs dqsd qsd qsd qsd qsd qsddq sqd qsd qsdqs dqsd qsd qsd qsd qsd qsd qsd https://google.com/testqsdqsdqsdqsdqsdqsdqsdqdqsdqsdqsdqsdqs dsqd qsd qsd dsqdqs dqs dqsd qsd qsd qsd qsd qsd qs dqsdsq qsd qsd qs dsqds qqs d dqs dqs dqs dqqsd qsd qsd qsd sqd qsd qsd sqd qds dsqd qsddq sqd qsd qsdqs dqsd qsd qsd qsd qsd qsd qsd qsd qsd qs dqsd qsd qsd qsd qsd qsddq sqd qsd qsdqs dqsd qsd qsd qsd qsd qsd qsd dsqd qsd qsd dsqdqs fqd dsq sq dsq qsd q qsd qsd qs dqs dqs qsd qsd qss sq ss s`;
|
||||
|
||||
(<any>component).maxCharLength = 500;
|
||||
(<any>component).countStatusChar(status);
|
||||
expect((<any>component).charCountLeft).toBe(0);
|
||||
});
|
||||
|
||||
it('should cound URL correctly - new lines', () => {
|
||||
const status = `qsddq sqd qsd qsdqs dqsd qsd qsd qsd qsd qsd qsd qsd qsd qs dqsd qsd qsd qsd qsd qsddq sqd qsd qsdqs dqsd qsd qsd qsd qsd qsd qsd\nhttps://google.com/testqsdqsdqsdqsdqsdqsdqsdqdqsdqsdqsdqsdqs\ndsqd qsd qsd dsqdqs dqs dqsd qsd qsd qsd qsd qsd qs dqsdsq qsd qsd qs dsqds qqs d dqs dqs dqs dqqsd qsd qsd qsd sqd qsd qsd sqd qds dsqd qsddq sqd qsd qsdqs dqsd qsd qsd qsd qsd qsd qsd qsd qsd qs dqsd qsd qsd qsd qsd qsddq sqd qsd qsdqs dqsd qsd qsd qsd qsd qsd qsd dsqd qsd qsd dsqdqs fqd dsq sq dsq qsd q qsd qsd qs dqs dqs qsd qsd qss sq ss s`;
|
||||
|
||||
(<any>component).maxCharLength = 500;
|
||||
(<any>component).countStatusChar(status);
|
||||
expect((<any>component).charCountLeft).toBe(0);
|
||||
});
|
||||
|
||||
it('should cound URL correctly - dual post', () => {
|
||||
const status = `qsddq sqd qsd qsdqs dqsd qsd qsd qsd qsd qsd qsd qsd qsd qs dqsd qsd qsd qsd qsd qsddq sqd qsd qsdqs dqsd qsd qsd qsd qsd qsd qsd https://google.com/testqsdqsdqsdqsdqsdqsdqsdqdqsdqsdqsdqsdqs dsqd qsd qsd dsqdqs dqs dqsd qsd qsd qsd qsd qsd qs dqsdsq qsd qsd qs dsqds qqs d dqs dqs dqs dqqsd qsd qsd qsd sqd qsd qsd sqd qds dsqd qsddq sqd qsd qsdqs dqsd qsd qsd qsd qsd qsd qsd qsd qsd qs dqsd qsd qsd qsd qsd qsddq sqd qsd qsdqs dqsd qsd qsd qsd qsd qsd qsd dsqd qsd qsd dsqdqs fqd dsq sq dsq qsd q qsd qsd qs dqs dqs qsd qsd qss sq ss s dqsd qsd sqd qsqsd qsd qsd qsd qsddq sqd qsd qsdqs dqsd qsd qsd qsd qsd qsd qsd dsqd qsd qsd dsqdqs fqd dsq sq dsq qsd q qsd qsd qs dqs dqs qsd qsd qss sq ss s dqsd qsd sqd qsqsd qsd qsd qsd qsddq sqd qsd qsdqs dqsd qsd qsd qsd qsd qsd qsd dsqd qsd qsd dsqdqs fqd dsq sq dsq qsd q qsd qsd qs dqs dqs qsd qsd qss sq ss s dqsd qsd sqd qsqsd qsd qsd qsd qsddq sqd qsd qsdqs dqsd qsd qsd qsd qsd qsd qsd dsqd qsd qsd dsqdqs fqd dsq sq dsq qsd q qsd qsd qs dqs dqs qsd qsd qss sq ss s dqsd qsd sqd qsqsd qsd qsdd dqsd qs s`;
|
||||
|
||||
(<any>component).maxCharLength = 512;
|
||||
(<any>component).countStatusChar(status);
|
||||
expect((<any>component).charCountLeft).toBe(0);
|
||||
expect((<any>component).postCounts).toBe(2);
|
||||
});
|
||||
|
||||
it('should cound URL correctly - triple post', () => {
|
||||
const status = `qsddq sqd qsd qsdqs dqsd qsd qsd qsd qsd qsd qsd qsd qsd qs dqsd qsd qsd qsd qsd qsddq sqd qsd qsdqs dqsd qsd qsd qsd qsd qsd qsd https://google.com/testqsdqsdqsdqsdqsdqsdqsdqdqsdqsdqsdqsdqs dsqd qsd qsd dsqdqs dqs dqsd qsd qsd qsd qsd qsd qs dqsdsq qsd qsd qs dsqds qqs d dqs dqs dqs dqqsd qsd qsd qsd sqd qsd qsd sqd qds dsqd qsddq sqd qsd qsdqs dqsd qsd qsd qsd qsd qsd qsd qsd qsd qs dqsd qsd qsd qsd qsd qsddq sqd qsd qsdqs dqsd qsd qsd qsd qsd qsd qsd dsqd qsd qsd dsqdqs fqd dsq sq dsq qsd q qsd qsd qs dqs dqs qsd qsd qss sq ss s dqsd qsd sqd qsqsd qsd qsd qsd qsddq sqd qsd qsdqs dqsd qsd qsd qsd qsd qsd qsd dsqd qsd qsd dsqdqs fqd dsq sq dsq qsd q qsd qsd qs dqs dqs qsd qsd qss sq ss s dqsd qsd sqd qsqsd qsd qsd qsd qsddq sqd qsd qsdqs dqsd qsd qsd qsd qsd qsd qsd dsqd qsd qsd dsqdqs fqd dsq sq dsq qsd q qsd qsd qs dqs dqs qsd qsd qss sq ss s dqsd qsd sqd qsqsd qsd qsd qsd qsddq sqd qsd qsdqs dqsd qsd qsd qsd qsd qsd qsd dsqd qsd qsd dsqdqs fqd dsq sq dsq qsd q qsd qsd qs dqs dqs qsd qsd qss sq ss s dqsd qsd sqd qsqsd qsd qsdd dqsd qs s dsqs sd qsd qsd qsd qsd qsd qsd qsd qsd qsd qsd qsd qsd qsqs dqs qsd qsd qss sq ss s dqsd qsd sqd qsqsd qsd qsdd dqsd qs s dsqs sd qsd qsd qsd qsd qsd qsd qsd qsd qsd qsd qsd qsd qsqs dqs qsd qsd qss sq ss s dqsd qsd sqd qsqsd qsd qsdd dqsd qs s dsqs sd qsd qsd qsd qsd qsd qsd qsd qsd qsd qsd qsd qsd qsqs dqs qsd qsd qss sq ss s dqsd qsd sqd qsqsd qsd qsdd dqsd qs s dsqs sd qsd qsd qsd qsd qsd qsd qsd qsd qsd qsd qsd qsd qs qsd qsd qsd qsd sqd qsd qsd sqd qsd qsd qsd qsd qsd qsd qsd qsd qsd qsd sd`;
|
||||
|
||||
(<any>component).maxCharLength = 512;
|
||||
(<any>component).countStatusChar(status);
|
||||
expect((<any>component).charCountLeft).toBe(0);
|
||||
expect((<any>component).postCounts).toBe(3);
|
||||
});
|
||||
|
||||
it('should add alias in multiposting replies', () => {
|
||||
const status = '@Lorem@ipsum.com ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed ante id dolor vulputate pulvinar sit amet a nisl. Duis sagittis nisl sit amet est rhoncus rutrum. Duis aliquet eget erat nec molestie. Fusce bibendum consectetur rhoncus. Aenean vel neque ac diam hendrerit interdum id a nisl. Aenean leo ante, luctus eget erat at, interdum tincidunt turpis. Donec non efficitur magna. Nam placerat convallis tincidunt. Etiam ac scelerisque velit, at vestibulum turpis. In hac habitasse platea dictu0';
|
||||
(<any>component).maxCharLength = 500;
|
||||
|
|
|
@ -474,8 +474,8 @@ export class CreateStatusComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
const currentStatus = parseStatus[parseStatus.length - 1];
|
||||
const statusExtraChars = this.getMentionExtraChars(status);
|
||||
const linksExtraChars = this.getLinksExtraChars(status);
|
||||
const statusExtraChars = this.getMentionExtraChars(currentStatus);
|
||||
const linksExtraChars = this.getLinksExtraChars(currentStatus);
|
||||
|
||||
const statusLength = [...currentStatus].length - statusExtraChars - linksExtraChars;
|
||||
this.charCountLeft = this.maxCharLength - statusLength - this.getCwLength();
|
||||
|
@ -634,7 +634,10 @@ export class CreateStatusComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
private parseStatus(status: string): string[] {
|
||||
//console.error(status.toString());
|
||||
|
||||
let mentionExtraChars = this.getMentionExtraChars(status);
|
||||
let urlExtraChar = this.getLinksExtraChars(status);
|
||||
let trucatedStatus = `${status}`;
|
||||
let results = [];
|
||||
|
||||
|
@ -644,8 +647,8 @@ export class CreateStatusComponent implements OnInit, OnDestroy {
|
|||
aggregateMention += `${x} `;
|
||||
});
|
||||
|
||||
const currentMaxCharLength = this.maxCharLength + mentionExtraChars - this.getCwLength();
|
||||
const maxChars = currentMaxCharLength - 6;
|
||||
let currentMaxCharLength = this.maxCharLength + mentionExtraChars + urlExtraChar - this.getCwLength();
|
||||
let maxChars = currentMaxCharLength - 6;
|
||||
|
||||
while (trucatedStatus.length > currentMaxCharLength) {
|
||||
const nextIndex = trucatedStatus.lastIndexOf(' ', maxChars);
|
||||
|
@ -656,6 +659,12 @@ export class CreateStatusComponent implements OnInit, OnDestroy {
|
|||
|
||||
results.push(trucatedStatus.substr(0, nextIndex) + ' (...)');
|
||||
trucatedStatus = aggregateMention + trucatedStatus.substr(nextIndex + 1);
|
||||
|
||||
// Refresh max
|
||||
let mentionExtraChars = this.getMentionExtraChars(trucatedStatus);
|
||||
let urlExtraChar = this.getLinksExtraChars(trucatedStatus);
|
||||
currentMaxCharLength = this.maxCharLength + mentionExtraChars + urlExtraChar - this.getCwLength();
|
||||
maxChars = currentMaxCharLength - 6;
|
||||
}
|
||||
results.push(trucatedStatus);
|
||||
return results;
|
||||
|
|
|
@ -22,9 +22,9 @@ $expand-color: $column-color;
|
|||
right: 0;
|
||||
padding-top: 60px;
|
||||
padding-left: 15px;
|
||||
background-image: linear-gradient(to bottom, rgba(0,0,0,0), rgba($expand-color ,0.25), rgba($expand-color,0.5), $expand-color, $expand-color);
|
||||
|
||||
&--link{
|
||||
background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba($expand-color, 0.25), rgba($expand-color, 0.5), $expand-color, $expand-color);
|
||||
|
||||
&--link {
|
||||
transition: all .2s;
|
||||
color: #a9b5d8;
|
||||
color: #c0c8e0;
|
||||
|
@ -41,9 +41,9 @@ $expand-color: $column-color;
|
|||
}
|
||||
|
||||
&--selected {
|
||||
background-image: linear-gradient(to bottom, rgba(0,0,0,0), rgba($selected-status ,0.25), rgba($selected-status,0.5), $selected-status, $selected-status);
|
||||
background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba($selected-status, 0.25), rgba($selected-status, 0.5), $selected-status, $selected-status);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -51,20 +51,48 @@ $expand-color: $column-color;
|
|||
:host ::ng-deep .content {
|
||||
// font-size: 14px;
|
||||
color: $status-primary-color;
|
||||
|
||||
& a,
|
||||
.mention,
|
||||
.ellipsis {
|
||||
color: $status-links-color;
|
||||
}
|
||||
|
||||
& .invisible {
|
||||
display: none;
|
||||
}
|
||||
|
||||
& p {
|
||||
margin: 0px;
|
||||
//font-size: .9em;
|
||||
// font-size: 14px;
|
||||
}
|
||||
|
||||
& p:not(:last-child) {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
& code {
|
||||
color: #a0d1ff;
|
||||
}
|
||||
|
||||
& pre {
|
||||
padding: 0 5px 5px 5px;
|
||||
background-color: #000000;
|
||||
|
||||
scrollbar-width: thin;
|
||||
border-radius: 5px 5px 0 0;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: $scroll-bar-width;
|
||||
height: $scroll-bar-width;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
-webkit-border-radius: 0px;
|
||||
border-radius: 0px;
|
||||
background: $scrollbar-color-thumb;
|
||||
background: #384958;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue