Compare commits
66 commits
ffdf3dbf12
...
36838e0b77
Author | SHA1 | Date | |
---|---|---|---|
|
36838e0b77 | ||
|
87709ad778 | ||
|
23bb5969a6 | ||
|
8250f36d29 | ||
|
73aa5b51be | ||
|
2edec65de0 | ||
|
c8f9e1b568 | ||
|
13ea06f37c | ||
|
0e2841adb6 | ||
|
69f1034570 | ||
|
21c5ed1398 | ||
|
51b07832f6 | ||
|
f1f2a5ec3a | ||
|
f6a3c1aafa | ||
|
29a6086ad2 | ||
|
0372c3736a | ||
|
43ff5e5c78 | ||
|
2d714b22f0 | ||
|
0c47a6738a | ||
|
2115bbeb2a | ||
|
d7259c9f2c | ||
|
6be0d7e1cf | ||
|
7ee8b5a333 | ||
|
123a3b617c | ||
|
7eabc0976b | ||
|
fd9303de4d | ||
|
04d771e39f | ||
|
8607837030 | ||
|
49ded1a775 | ||
|
32bde3b342 | ||
|
4741e7f707 | ||
|
7dfae96394 | ||
|
4c2a37db0e | ||
|
16ec0cc090 | ||
|
cf03e445f4 | ||
|
95d13ab4b0 | ||
|
3f1aaa7b96 | ||
|
7e6874380f | ||
|
839c73706a | ||
|
6cae6953f5 | ||
|
e003fa2b6e | ||
|
abd5912f98 | ||
|
ed48eb0a94 | ||
|
8480c68ce1 | ||
|
bd91ee5611 | ||
|
3bb76d7121 | ||
|
ba5ef7432e | ||
|
5f97137f4b | ||
|
2f88f1da59 | ||
|
cef797efb8 | ||
|
341b225eb8 | ||
|
bb35cd2b6e | ||
|
05b93e1962 | ||
|
c485cedb3d | ||
|
8d8abed078 | ||
|
e46e53da16 | ||
|
7e2d91a106 | ||
|
d64e993ba7 | ||
|
e7eb249334 | ||
|
7dddb40e98 | ||
|
f78c7c57a8 | ||
|
19e1f57cf6 | ||
|
a8ef736d04 | ||
|
a97f8416bc | ||
|
829346b995 | ||
|
b78110ba3f |
46 changed files with 3795 additions and 1954 deletions
2
.github/FUNDING.yml
vendored
Normal file
2
.github/FUNDING.yml
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
|
||||
liberapay: poetaster
|
76
.github/workflows/build.yaml
vendored
Normal file
76
.github/workflows/build.yaml
vendored
Normal file
|
@ -0,0 +1,76 @@
|
|||
name: Build RPMs
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "1.*"
|
||||
|
||||
env:
|
||||
OS_VERSION: 4.4.0.68
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
name: Build App
|
||||
strategy:
|
||||
matrix:
|
||||
arch: ['armv7hl', 'aarch64', 'i486']
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Prepare
|
||||
run: docker pull coderus/sailfishos-platform-sdk:$OS_VERSION && mkdir output
|
||||
|
||||
- name: Build ${{ matrix.arch }}
|
||||
run: docker run --rm --privileged -v $PWD:/share coderus/sailfishos-platform-sdk:$OS_VERSION /bin/bash -c "
|
||||
mkdir -p build ;
|
||||
cd build ;
|
||||
cp -r /share/* . ;
|
||||
mb2 -t SailfishOS-$OS_VERSION-${{ matrix.arch }} build ;
|
||||
sudo cp -r RPMS/*.rpm /share/output"
|
||||
|
||||
- name: Upload RPM (${{ matrix.arch }})
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: rpm-${{ matrix.arch }}
|
||||
path: output
|
||||
release:
|
||||
name: Release
|
||||
if: startsWith(github.ref, 'refs/tags/1.1')
|
||||
needs:
|
||||
- build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Download armv7hl
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: rpm-armv7hl
|
||||
continue-on-error: true
|
||||
- name: Download aarch64
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: rpm-aarch64
|
||||
continue-on-error: true
|
||||
- name: Download i486
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: rpm-i486
|
||||
continue-on-error: true
|
||||
- name: Extract Version Name
|
||||
id: extract_name
|
||||
uses: actions/github-script@v4
|
||||
with:
|
||||
result-encoding: string
|
||||
script: |
|
||||
return context.payload.ref.replace(/refs\/tags\//, '');
|
||||
- name: Create a Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
name: ${{ steps.extract_name.outputs.result }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
body: This release was autogenerated.
|
||||
files: '*.rpm'
|
249
CHANGES
Normal file
249
CHANGES
Normal file
|
@ -0,0 +1,249 @@
|
|||
* Thu Jan 26 2023 Mark Washeim <blueprint@poetaster.de> - 1.1.6-2
|
||||
- [Release] obs fix, broken changes
|
||||
- [Release] changes spacing issues
|
||||
|
||||
* Wed Jan 25 2023 Mark Washeim <blueprint@poetaster.de> - 1.1.6
|
||||
- [Release] This release adds uploads for other filetypes and removes the hardcoded mimetype
|
||||
- [Feature] modified image uploader to serve other mimetypes, added pickers
|
||||
- [Fix] hot fix for a breaks tooting bug
|
||||
|
||||
* Thu Jan 19 2023 Mark Washeim <blueprint@poetaster.de> - 1.1.5
|
||||
- [Release] hot bug fix, broken tooting
|
||||
- [Release] 1.1.5 fixes a bug which stops tooting!
|
||||
- [Fix] hot fix for a breaks tooting bug.
|
||||
|
||||
* Wed Jan 18 2023 Mark Washeim <blueprint@poetaster.de> - 1.1.4
|
||||
- [Fix] Home loading and search deduping release
|
||||
- [Fix] search for tags and persons added header call for max/min and prepend on first call.
|
||||
- [Issue]: # 26. timelines/home on append uses the link header for min/max id
|
||||
|
||||
* Thu Jan 5 2023 Mark Washeim <blueprint@poetaster.de> 1.1.3
|
||||
- Add changes from gitlogs (++) Bump for tag release.
|
||||
- Add conditional append all for search when no knownIds
|
||||
- Add correction to linkprev for bookmarks (and follows, etc)
|
||||
|
||||
* Wed Jan 4 2023 Mark Washeim <blueprint@poetaster.de> 1.1.2
|
||||
- Add conditional append all for search when no knownIds Workers.js
|
||||
- Add linkprev/next for bookmarks (and follows, etc) MyList
|
||||
- getLink method in Mastodon.js HEAD requests for Link
|
||||
|
||||
* Fri Dec 23 2022 Mark Washeim <blueprint@poetaster.de> 1.1.1
|
||||
- This is an interim release that should not have been released
|
||||
|
||||
* Fri Dec 2 2022 Mark Washeim <blueprint@poetaster.de> 1.1.0
|
||||
- Added some more debug flags to stop spewing the console.
|
||||
- Added self to credits.
|
||||
- Added MediaItem display for audio and Integrated MediaItem into MediaBlock/MyMedia elements.
|
||||
- Add additional; media element for audio.
|
||||
- Merge pull request #16 from cintema/patch-2
|
||||
- Merge pull request #15 from cintema/patch-1
|
||||
- Update harbour-tooterb.spec
|
||||
- Update LoginPage.qml
|
||||
- Merge pull request #5 from eson57/patch-2
|
||||
- Update harbour-tooterb-sv.ts
|
||||
|
||||
* Wed Nov 16 2022 Mark Washeim <blueprint@poetaster.de> 1.0.9
|
||||
- Forgot to remove the yaml from spec. duh.
|
||||
- Boost release.
|
||||
- Update translations, partially for new bookmarks view.
|
||||
- Remove yaml since it's just in the way.
|
||||
- Added navigation elements and model for bookmarks.
|
||||
|
||||
* Mon Nov 14 2022 Mark Washeim <blueprint@poetaster.de> 1.0.8-3
|
||||
- Had neglected linguist include which is required for building on obs
|
||||
|
||||
* Wed Nov 9 2022 Mark Washeim <blueprint@poetaster.de> 1.0.8-2
|
||||
- Added minimal info to spec/yaml to include a release in chum.
|
||||
- Merge pull request #100 from poetaster/master
|
||||
- Merge pull request #99 from juanro49/master
|
||||
- Fix reblog content view
|
||||
|
||||
* Wed Nov 9 2022 Mark Washeim <blueprint@poetaster.de> 1.0.8
|
||||
- Add python server for callbacks
|
||||
- Add new WebView to better render callbacks
|
||||
|
||||
* Sun Jul 12 2020 molan <mol_an@sunrise.ch> 1.0.7-0
|
||||
- Fix missing / wrong reblog and favourite counts in Retoots (issue #90)
|
||||
- Added full landscape support
|
||||
- Added new Pulley Menu options
|
||||
- Improved Toot context menu
|
||||
- Improved media page
|
||||
- Improved loading indicators
|
||||
- Small changes for some UI-elements
|
||||
- New Emojis
|
||||
- New translated strings
|
||||
|
||||
* Fri Jun 18 2020 molan <mol_an@sunrise.ch> 1.0.6-3
|
||||
- Fix broken reblog indication
|
||||
|
||||
* Fri Jun 18 2020 molan <mol_an@sunrise.ch> 1.0.6-2
|
||||
- Fix reported small UI issue
|
||||
- Updated translations
|
||||
|
||||
* Thu Jun 18 2020 molan <mol_an@sunrise.ch> 1.0.6-1
|
||||
- Fix app crash when open some Profile pages
|
||||
- Fix sometimes missing favourite / reblog counts
|
||||
- Fix various QML warnings, replace deprecated Silica items
|
||||
- Add save to Bookmarks feature
|
||||
- Add Follows you / Locked / Bot / Group labels to Profile Page header
|
||||
- Add Bot icon to user display name
|
||||
- Add clicking on reblog-avatar opens reblog user profile
|
||||
- Remove Locked icon from user display name
|
||||
- Further improved Notification Page / general UI
|
||||
- Code refactoring & other changes under the hood
|
||||
- Translation updates
|
||||
|
||||
* Fri Jun 12 2020 molan <mol_an@sunrise.ch> 1.0.5-1
|
||||
- [hotfix] fix missing images in mentions on Notification page
|
||||
|
||||
* Thu Jun 11 2020 molan <mol_an@sunrise.ch> 1.0.5-0
|
||||
- fixed: show search results without entering # before term
|
||||
- fixed: non-clickable user mentions in Toots
|
||||
- fixed: Copy link to clipboard in Conversations
|
||||
- Notifications Page: Reworked UI and context menus for notifications
|
||||
- Profile Page: Open fullscreen profile image
|
||||
- Profile Page: Show bot label
|
||||
- Profile Page: New expander for Profile details
|
||||
- Conversation Page: Possibility to hide and reopen Toot text field
|
||||
- Conversation Page: Improved display of uploaded images
|
||||
- Media Page: Adjust size of images to screen width or height
|
||||
- Media Page: Only automatically restart videos if shorter than 30 seconds
|
||||
- new Settings Page
|
||||
- bigger custom emojis in Toots
|
||||
- overall improvement of UI
|
||||
|
||||
* Mon May 25 2020 molan <mol_an@sunrise.ch> 1.0.4-3
|
||||
- Show user profile background image (if available)
|
||||
- New Sailfish 3-styled image/video viewer page (WIP)
|
||||
- Added "Toot sent!" notification banner
|
||||
- Show Pulley Menu for copying Toot-link only if link is provided (WIP)
|
||||
- Distiction between "New Toot" and "Conversation" page
|
||||
- some small fixes
|
||||
|
||||
* Mon May 11 2020 molan <mol_an@sunrise.ch> 1.0.4-2
|
||||
- Beta release by molan
|
||||
- Login / Settings Page: Small changes in text wording
|
||||
- Login Page: Use of correct label coloring and text alignment
|
||||
- Login Page: Highlight login confirmation button + 'accept' icon on Sailfish keyboard
|
||||
- Media Page: Switched play / pause buttons during media playback
|
||||
- Conversation Page: Improved alignment of elements in 'New Toot' (no more overlapping)
|
||||
- Settings Page: Replaced icons in Settings page for consistency and clarity
|
||||
- Settings Page: Added missing language contributor
|
||||
- Translations: Completed and fixed German and French translations
|
||||
- Translations: Added complete Italian translation
|
||||
- Translations: Added missing/lost strings and updates to other translation files
|
||||
- Timeline: Better text formatting in toots (show paragraph breaks)
|
||||
- Timeline: Use shortend username if display_name isn't provided in ProfileHeader and MiniHeader
|
||||
- Timeline: Created new placeholder for profile avatars if instance doesn't provide valid image
|
||||
|
||||
* Thu Apr 16 2020 Dusko Angirevic <dysko@me.com> 1.0.4-1
|
||||
- Merge with molan code
|
||||
|
||||
* Tue Feb 04 2020 molan <mol_an@sunrise.ch> 1.0.3-8
|
||||
- Fix for broken translations
|
||||
- Updated Spanish translation
|
||||
|
||||
* Mon Feb 03 2020 molan <mol_an@sunrise.ch> 1.0.3-7
|
||||
- Updated translations for new language strings
|
||||
|
||||
* Thu Jan 30 2020 molan <mol_an@sunrise.ch> 1.0.3-6
|
||||
- Workaround for opening user profiles in toots
|
||||
- Show profile descriptions (Bio) with option to open them in Browser
|
||||
- Updated and improved UI for Conversation page
|
||||
- Indication for sending toot (move back to previous page)
|
||||
- New arrangement of main pages (like used in Mastodon websites and other apps)
|
||||
- Small UI and text/label changes
|
||||
|
||||
* Thu Jan 16 2020 molan <mol_an@sunrise.ch> 1.0.3-5 [fork of Tooter 1.0.3]
|
||||
- Fix for broken profile pages when clicking on usernames in toots
|
||||
- Fixed navigation icons for inverted ambiences
|
||||
- Updated Chinese translation (thanks to dashinfantry)
|
||||
|
||||
* Wed Jan 15 2020 molan <mol_an@sunrise.ch> 1.0.3-4 [fork of Tooter 1.0.3]
|
||||
- Website links in toots now open directly in browser since the web scraper service which was used before is discontinued
|
||||
- Profile page now shows full display name in title instead of user name
|
||||
- Changed send, content warning and add emoji icon in Conversation page for clarification
|
||||
- Small update to Chinese translation (thanks to dashinfantry)
|
||||
- Completed German and French translations
|
||||
|
||||
* Mon Jan 06 2020 molan <mol_an@sunrise.ch> 1.0.3-3 [fork of Tooter 1.0.3]
|
||||
- Update and rename harbour-tooter-zh.ts to harbour-tooter-zh_CN.ts (thanks to dashinfantry)
|
||||
|
||||
* Sat Dec 28 2019 molan <mol_an@sunrise.ch> 1.0.3-1 [fork of Tooter 1.0.3]
|
||||
- Fixed broken Mastodon login (app built with Sailfish SDK 2.4)
|
||||
- Fixed crash on certain notifications
|
||||
|
||||
* Sun Jan 27 2019 Dusko Angirevic <dysko@me.com> 1.0.3-0
|
||||
- Remorse popup added for account removal
|
||||
- Updated translations
|
||||
|
||||
* Tue Jan 15 2019 Dusko Angirevic <dysko@me.com> 1.0.2-0
|
||||
- SailfishOS 3.0 build
|
||||
- Chinese language translation added
|
||||
|
||||
* Fri Oct 26 2018 Dusko Angirevic <dysko@me.com> 0.2.8-0
|
||||
- Fixed conversation bug
|
||||
|
||||
* Thu Oct 25 2018 Dusko Angirevic <dysko@me.com> 0.2.8-0
|
||||
- Fixed localisation issue
|
||||
- Added character counter
|
||||
|
||||
* Tue Oct 23 2018 Dusko Angirevic <dysko@me.com> 0.2.7-0
|
||||
- Added emoji custom support
|
||||
- Bugfix: missing media on boosted toots
|
||||
|
||||
* Thu May 24 2018 Dusko Angirevic <dysko@me.com> 0.2.6-0
|
||||
- Minor bugfix
|
||||
|
||||
* Thu May 24 2018 Dusko Angirevic <dysko@me.com> 0.2.5-0
|
||||
- Added local timeline
|
||||
|
||||
* Thu Nov 02 2017 Dusko Angirevic <dysko@me.com> 0.2.4-0
|
||||
- Updated translations
|
||||
- Added Russian
|
||||
|
||||
* Fri Oct 27 2017 Dusko Angirevic <dysko@me.com> 0.2.3-0
|
||||
- Added User autocomplete options
|
||||
- Added video player options
|
||||
- Smileys are inserted on the cursor position
|
||||
- Pinch to zoom photos
|
||||
- Support for downloading media to the device
|
||||
- Added cover action for new toot
|
||||
|
||||
* Thu Oct 19 2017 Dusko Angirevic <dysko@me.com> 0.2.2-0
|
||||
- Updated translations
|
||||
- Cover page fix for SailfishX
|
||||
- Added Copy URL option
|
||||
- Privacy option in the conversation is now inherited by toot in the thread
|
||||
|
||||
* Tue Oct 10 2017 Dusko Angirevic <dysko@me.com> 0.2.1-0
|
||||
- Added bugs for later (merging branches and contributions)
|
||||
|
||||
* Thu Jul 20 2017 Dusko Angirevic <dysko@me.com> 0.2.0-0
|
||||
- Better tablet displaying
|
||||
- "boosted" notification bugfix
|
||||
- ES lang update by Caballlero
|
||||
|
||||
* Thu Jul 7 2017 Dusko Angirevic <dysko@me.com> 0.1.9-0
|
||||
- Image Upload added [#9]
|
||||
- Emoji pannel added
|
||||
- ES lang update by Carlos Gonzales
|
||||
|
||||
* Tue Jul 4 2017 Dusko Angirevic <dysko@me.com> 0.1.8-0
|
||||
- Added notifications
|
||||
- App Cover redesigned
|
||||
|
||||
* Tue Jul 4 2017 Dusko Angirevic <dysko@me.com> 0.1.7-0
|
||||
- Added spoiler support for toots
|
||||
- Press and hold for boost and favourite option
|
||||
- Updated harbour-tooter-es.ts by Caballlero
|
||||
- Unable to connect to unixcorn.xyz [#12] [bugfix]
|
||||
|
||||
* Tue Jun 20 2017 Dusko Angirevic <dysko@me.com> 0.1.6-1
|
||||
- Hashtag search added
|
||||
- Conversation with sections
|
||||
|
||||
* Mon Jun 19 2017 Dusko Angirevic <dysko@me.com> 0.1.5-1
|
||||
- Autoload older tweets on the list end
|
||||
- Displaying images on the timeline
|
||||
- NSFW support for images
|
|
@ -3,7 +3,9 @@
|
|||
## About
|
||||
Tooter is Mastodon client for [Sailfish OS](https://sailfishos.org).
|
||||
|
||||
This fork is being used to further develop and maintain the Tooter app by dysko ([harbour-tooter](https://github.com/dysk0/harbour-tooter)).
|
||||
This fork is being used to further develop and maintain the Tooter app by dysko ([harbour-tooter](https://github.com/dysk0/harbour-tooter)) and molan [OpenRepos.net](https://openrepos.net/content/molan/tooter-v).
|
||||
|
||||
This fork continues the work done by molan, thanks! primary distribution is through obs/chum but build actions on github provide a build here on github with every release. As soon as migration code for sailjail paths is implemented, tooter will make it to the harbour!
|
||||
|
||||
* Releases from this repository (Tooter β from release branch *master*) can be found on [OpenRepos.net](https://openrepos.net/content/molan/tooter-v)
|
||||
* Releases by dysko can be found on the Jolla store and on [OpenRepos.net](https://openrepos.net/content/dysko/tooter)
|
||||
|
@ -13,11 +15,9 @@ Clone / download this repository and import it into your SailfishOS IDE using th
|
|||
|
||||
## Repository branches:
|
||||
* master: release branch which includes specifics for harbour-tooterb (Tooter β)
|
||||
* upstream: main development branch which is used to send changes to the upstream repository (harbour-tooter)
|
||||
|
||||
## Contributions
|
||||
Contributions to this project are very welcome, since there are still many things which can be done for Tooter. If you already know what you want to add or fix, please make a Pull Request (PR) with your proposal. Your PR should include an explanation or a change log summary. Merging will not be allowed until the PR has been reviewed.
|
||||
Please fork the [upstream branch](https://github.com/molan-git/harbour-tooter/tree/upstream) if you want to contribute to this project.
|
||||
|
||||
## Screenshots
|
||||
<img width="200" title="Page Home" src="https://telegra.ph/file/710bba46d9f818e0f88ab.png"> <img width="200" title="Page Profile" src="https://telegra.ph/file/c5b504f637c874861eeee.png"> <img width="200" title="Page Conversation" src="https://telegra.ph/file/c9584f8d68c89827c53e5.png">
|
||||
|
|
|
@ -3,4 +3,4 @@ Type=Application
|
|||
X-Nemo-Application-Type=silica-qt5
|
||||
Icon=harbour-tooterb
|
||||
Exec=harbour-tooterb
|
||||
Name=Tooter β
|
||||
Name=Tooter beta
|
||||
|
|
|
@ -68,6 +68,7 @@ DISTFILES += qml/harbour-tooterb.qml \
|
|||
qml/pages/components/MyList.qml \
|
||||
qml/pages/components/ProfileHeader.qml \
|
||||
qml/pages/components/MediaBlock.qml \
|
||||
qml/pages/components/MediaItem.qml \
|
||||
qml/cover/CoverPage.qml \
|
||||
qml/pages/MainPage.qml \
|
||||
qml/pages/LoginPage.qml \
|
||||
|
@ -77,6 +78,7 @@ DISTFILES += qml/harbour-tooterb.qml \
|
|||
qml/lib/index.html \
|
||||
qml/images/icon-s-following \
|
||||
qml/images/icon-s-bookmark \
|
||||
qml/images/icon-m-bookmark \
|
||||
qml/images/icon-m-emoji.svg \
|
||||
qml/images/icon-m-profile.svg \
|
||||
qml/images/icon-l-profile.svg \
|
||||
|
@ -87,7 +89,6 @@ DISTFILES += qml/harbour-tooterb.qml \
|
|||
rpm/harbour-tooterb.changes \
|
||||
rpm/harbour-tooterb.changes.run.in \
|
||||
rpm/harbour-tooterb.spec \
|
||||
rpm/harbour-tooterb.yaml \
|
||||
translations/*.ts \
|
||||
harbour-tooterb.desktop
|
||||
|
||||
|
@ -111,4 +112,3 @@ TRANSLATIONS += translations/harbour-tooterb.ts \
|
|||
translations/harbour-tooterb-sr.ts \
|
||||
translations/harbour-tooterb-sv.ts \
|
||||
translations/harbour-tooterb-zh_CN.ts
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
1269
harbour-tooterb.pro.user.ddbad1f
Normal file
1269
harbour-tooterb.pro.user.ddbad1f
Normal file
File diff suppressed because it is too large
Load diff
|
@ -67,6 +67,8 @@ ApplicationWindow {
|
|||
}
|
||||
})
|
||||
Logic.init()
|
||||
|
||||
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
|
|
10
qml/images/icon-m-bookmark.svg
Normal file
10
qml/images/icon-m-bookmark.svg
Normal file
|
@ -0,0 +1,10 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>icon-m-bookmark</title>
|
||||
<g>
|
||||
<rect width="64" height="64" fill="#fff" fill-opacity="0"/>
|
||||
<path d="M42.75,55.81,33,46.62a1.39,1.39,0,0,0-1.9,0l-9.9,9.15a4.42,4.42,0,0,1-5.21.15,5.18,5.18,0,0,1-2-4.07V12.21A5.24,5.24,0,0,1,19.21,7H44.79A5.24,5.24,0,0,1,50,12.21V51.84a5.18,5.18,0,0,1-2,4.07A4.58,4.58,0,0,1,42.75,55.81ZM19.21,9A3.18,3.18,0,0,0,16,12.15s0,0,0,.06V51.84a3.15,3.15,0,0,0,0,.43,2.65,2.65,0,0,0,4.47,1.39l9-8.65a3.57,3.57,0,0,1,4.94,0l9,8.65a2.65,2.65,0,0,0,4.47-1.39,3.15,3.15,0,0,0,0-.43V12.21A3.18,3.18,0,0,0,44.79,9Z" transform="translate(0 0)" fill="#fff"/>
|
||||
<g opacity="0.6">
|
||||
<path d="M43.45,25.65,38.83,29A2.34,2.34,0,0,0,38,31.43l1.77,5.44a1.6,1.6,0,0,1-.06,1.46.92.92,0,0,1-.71.37,1.94,1.94,0,0,1-1.1-.44L33.27,34.9a2.46,2.46,0,0,0-2.54,0L26.1,38.26c-.8.58-1.49.57-1.85.07a1.6,1.6,0,0,1-.06-1.46L26,31.43A2.38,2.38,0,0,0,25.17,29l-4.63-3.36c-.84-.61-.88-1.15-.77-1.49s.46-.75,1.5-.75H27a2.38,2.38,0,0,0,2.06-1.49l1.77-5.44c.32-1,.82-1.19,1.18-1.19s.86.21,1.18,1.19L35,21.91a2.39,2.39,0,0,0,2,1.5h5.72c1,0,1.39.41,1.5.75S44.29,25,43.45,25.65Z" transform="translate(0 0)" fill="#fff"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
|
@ -72,7 +72,7 @@ function saveData() {
|
|||
}
|
||||
}
|
||||
}
|
||||
console.log("ENF OF SAVING")
|
||||
console.log("END OF SAVING")
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -116,6 +116,8 @@ var modelTLpublic = Qt.createQmlObject('import QtQuick 2.0; ListModel { }', Qt
|
|||
var modelTLlocal = Qt.createQmlObject('import QtQuick 2.0; ListModel { }', Qt.application, 'InternalQmlObject');
|
||||
var modelTLnotifications = Qt.createQmlObject('import QtQuick 2.0; ListModel { }', Qt.application, 'InternalQmlObject');
|
||||
var modelTLsearch = Qt.createQmlObject('import QtQuick 2.0; ListModel { }', Qt.application, 'InternalQmlObject');
|
||||
var modelTLbookmarks = Qt.createQmlObject('import QtQuick 2.0; ListModel { }', Qt.application, 'InternalQmlObject');
|
||||
|
||||
var notificationsList = []
|
||||
|
||||
var notificationGenerator = function(item){
|
||||
|
|
|
@ -16,6 +16,58 @@ var mastodonAPI = function(config) {
|
|||
return config[key];
|
||||
},
|
||||
|
||||
/*
|
||||
* function to retrieve the Link header
|
||||
* using HEAD, so bookmarks has head followed by GET
|
||||
*/
|
||||
|
||||
getLink: function (endpoint) {
|
||||
// variables
|
||||
var queryData, callback,
|
||||
queryStringAppend = "?";
|
||||
|
||||
// check with which arguments we're supplied
|
||||
if (typeof arguments[1] === "function") {
|
||||
queryData = {};
|
||||
callback = arguments[1];
|
||||
} else {
|
||||
queryData = arguments[1];
|
||||
callback = arguments[2];
|
||||
}
|
||||
// build queryData Object into a URL Query String
|
||||
for (var i in queryData) {
|
||||
if (queryData.hasOwnProperty(i)) {
|
||||
if (typeof queryData[i] === "string") {
|
||||
queryStringAppend += queryData[i] + "&";
|
||||
} else if (typeof queryData[i] === "object") {
|
||||
queryStringAppend += queryData[i].name + "="+ queryData[i].data + "&";
|
||||
}
|
||||
}
|
||||
}
|
||||
var http = new XMLHttpRequest()
|
||||
var url = apiBase + endpoint;
|
||||
console.log("HEAD" + apiBase + endpoint + queryStringAppend)
|
||||
|
||||
http.open("HEAD", apiBase + endpoint + queryStringAppend, true);
|
||||
// Send the proper header information along with the request
|
||||
http.setRequestHeader("Authorization", "Bearer " + config.api_user_token);
|
||||
http.setRequestHeader("Content-Type", "application/json");
|
||||
http.setRequestHeader("Connection", "close");
|
||||
|
||||
http.onreadystatechange = function() {
|
||||
if (http.readyState === 4) {
|
||||
if (http.status === 200) {
|
||||
callback( http.getResponseHeader("Link") , http.status)
|
||||
console.log("Successful HEAD API request to " +apiBase+endpoint);
|
||||
} else {
|
||||
console.log("error: " + http.status)
|
||||
}
|
||||
}
|
||||
}
|
||||
http.send();
|
||||
|
||||
},
|
||||
|
||||
get: function (endpoint) {
|
||||
// for GET API calls
|
||||
// can be called with two or three parameters
|
||||
|
@ -46,10 +98,11 @@ var mastodonAPI = function(config) {
|
|||
}
|
||||
}
|
||||
}
|
||||
//queryStringAppend += "limit=20"
|
||||
// ajax function
|
||||
var http = new XMLHttpRequest()
|
||||
var url = apiBase + endpoint;
|
||||
console.log(queryStringAppend)
|
||||
console.log(apiBase + endpoint + queryStringAppend)
|
||||
http.open("GET", apiBase + endpoint + queryStringAppend, true);
|
||||
|
||||
// Send the proper header information along with the request
|
||||
|
@ -60,8 +113,8 @@ var mastodonAPI = function(config) {
|
|||
http.onreadystatechange = function() { // Call a function when the state changes.
|
||||
if (http.readyState === 4) {
|
||||
if (http.status === 200) {
|
||||
console.log("Successful GET API request to " +apiBase+endpoint);
|
||||
callback(JSON.parse(http.response),http.status)
|
||||
console.log("Successful GET API request to " +apiBase+endpoint);
|
||||
} else {
|
||||
console.log("error: " + http.status)
|
||||
}
|
||||
|
@ -219,7 +272,7 @@ var mastodonAPI = function(config) {
|
|||
var http = new XMLHttpRequest()
|
||||
var url = config.instance + "/oauth/token";
|
||||
var params = 'client_id=' + client_id + '&client_secret=' + client_secret + '&redirect_uri=' + redirect_uri + '&grant_type=authorization_code&code=' + code;
|
||||
console.log(params)
|
||||
// console.log(params)
|
||||
http.open("POST", url, true);
|
||||
|
||||
// Send the proper header information along with the request
|
||||
|
|
|
@ -1,14 +1,37 @@
|
|||
Qt.include("Mastodon.js")
|
||||
|
||||
|
||||
var debug = false;
|
||||
var loadImages = true;
|
||||
// used to dedupe on append/insert
|
||||
var knownIds = [];
|
||||
var max_id ;
|
||||
var since_id;
|
||||
|
||||
WorkerScript.onMessage = function(msg) {
|
||||
console.log("Action > " + msg.action)
|
||||
console.log("Model > " + msg.model)
|
||||
console.log("Mode > " + msg.mode)
|
||||
console.log("Conf > " + JSON.stringify(msg.conf))
|
||||
console.log("Params > " + JSON.stringify(msg.params))
|
||||
|
||||
if (debug) console.log("Action > " + msg.action)
|
||||
if (debug) console.log("Mode > " + msg.mode)
|
||||
|
||||
// this is not elegant. it's max_id and ids from MyList
|
||||
// we should always get max_id on append
|
||||
if (msg.mode === "append" && msg.params[0]) {
|
||||
if ( msg.params[0]["name"] === "max_id" ) {
|
||||
max_id = msg.params[0]["data"]
|
||||
}
|
||||
} else if ( msg.mode === "prepend" && msg.params[0]) {
|
||||
|
||||
// prepend could be min_id or since_id
|
||||
since_id = msg.params[0]["data"]
|
||||
|
||||
}
|
||||
// ids are always the last param
|
||||
if (msg.params[2]) {
|
||||
if ( msg.params[2]["name"] === "ids" ) {
|
||||
knownIds = msg.params[2]["data"]
|
||||
msg.params.pop()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** order notifications in ASC order */
|
||||
function orderNotifications(items){
|
||||
|
@ -20,7 +43,7 @@ WorkerScript.onMessage = function(msg) {
|
|||
|
||||
/** Logged-in status */
|
||||
if (!msg.conf || !msg.conf.login) {
|
||||
console.log("Not loggedin")
|
||||
//console.log("Not loggedin")
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -28,12 +51,32 @@ WorkerScript.onMessage = function(msg) {
|
|||
if (typeof msg.conf['loadImages'] !== "undefined")
|
||||
loadImages = msg.conf['loadImages']
|
||||
|
||||
/** POST statuses */
|
||||
|
||||
/* init API statuses */
|
||||
|
||||
var API = mastodonAPI({ instance: msg.conf.instance, api_user_token: msg.conf.api_user_token});
|
||||
|
||||
/*
|
||||
* HEAD call for some actions
|
||||
* we have to retrieve the Link header
|
||||
* this falls through and continues for GET
|
||||
*/
|
||||
|
||||
if (msg.action === "bookmarks" ||
|
||||
//( msg.action === "timelines/home" && msg.mode === "append") ||
|
||||
( msg.action.indexOf("timelines/tag/") !== -1 ) ){
|
||||
API.getLink(msg.action, msg.params, function(data) {
|
||||
if (debug) console.log(JSON.stringify(data))
|
||||
WorkerScript.sendMessage({ 'LinkHeader': data })
|
||||
});
|
||||
}
|
||||
|
||||
/** POST statuses */
|
||||
|
||||
if (msg.method === "POST"){
|
||||
API.post(msg.action, msg.params, function(data) {
|
||||
if (msg.bgAction){
|
||||
console.log(JSON.stringify(data))
|
||||
//console.log(JSON.stringify(data))
|
||||
} else if (msg.action === "statuses") {
|
||||
// status posted
|
||||
if(msg.model){
|
||||
|
@ -45,7 +88,7 @@ WorkerScript.onMessage = function(msg) {
|
|||
} else {
|
||||
for (var i in data) {
|
||||
if (data.hasOwnProperty(i)) {
|
||||
console.log(JSON.stringify(data[i]))
|
||||
//console.log(JSON.stringify(data[i]))
|
||||
WorkerScript.sendMessage({ 'action': msg.action, 'success': true, key: i, "data": data[i]})
|
||||
}
|
||||
}
|
||||
|
@ -55,21 +98,26 @@ WorkerScript.onMessage = function(msg) {
|
|||
}
|
||||
|
||||
API.get(msg.action, msg.params, function(data) {
|
||||
|
||||
var items = [];
|
||||
//console.log(data)
|
||||
|
||||
for (var i in data) {
|
||||
var item;
|
||||
if (data.hasOwnProperty(i)) {
|
||||
if(msg.action === "accounts/search") {
|
||||
item = parseAccounts([], "", data[i]);
|
||||
console.log(JSON.stringify(data[i]))
|
||||
//console.log(JSON.stringify(data[i]))
|
||||
console.log("has own data")
|
||||
|
||||
items.push(item)
|
||||
|
||||
} else if(msg.action === "notifications") {
|
||||
// notification
|
||||
console.log("Get notification list")
|
||||
console.log(JSON.stringify(data[i]))
|
||||
//console.log("Get notification list")
|
||||
//console.log(JSON.stringify(data[i]))
|
||||
item = parseNotification(data[i]);
|
||||
items.push(item)
|
||||
items.push(item);
|
||||
|
||||
} else if(msg.action.indexOf("statuses") >-1 && msg.action.indexOf("context") >-1 && i === "ancestors") {
|
||||
// status ancestors toots - conversation
|
||||
|
@ -79,8 +127,9 @@ WorkerScript.onMessage = function(msg) {
|
|||
item['id'] = item['status_id'];
|
||||
if (typeof item['attachments'] === "undefined")
|
||||
item['attachments'] = [];
|
||||
items.push(item)
|
||||
console.log(JSON.stringify(data[i][j]))
|
||||
// don't permit doubles
|
||||
items.push(item);
|
||||
//console.log(JSON.stringify(data[i][j]))
|
||||
}
|
||||
addDataToModel (msg.model, "prepend", items);
|
||||
items = [];
|
||||
|
@ -94,8 +143,8 @@ WorkerScript.onMessage = function(msg) {
|
|||
item['id'] = item['status_id'];
|
||||
if (typeof item['attachments'] === "undefined")
|
||||
item['attachments'] = [];
|
||||
items.push(item)
|
||||
console.log(JSON.stringify(data[i][j]))
|
||||
items.push(item);
|
||||
//console.log(JSON.stringify(data[i][j]))
|
||||
}
|
||||
addDataToModel (msg.model, "append", items);
|
||||
items = [];
|
||||
|
@ -104,7 +153,8 @@ WorkerScript.onMessage = function(msg) {
|
|||
//console.log("Get Toot")
|
||||
item = parseToot(data[i]);
|
||||
item['id'] = item['status_id']
|
||||
items.push(item)
|
||||
items.push(item);
|
||||
|
||||
|
||||
} else {
|
||||
WorkerScript.sendMessage({ 'action': msg.action, 'success': true, key: i, "data": data[i] })
|
||||
|
@ -112,29 +162,64 @@ WorkerScript.onMessage = function(msg) {
|
|||
}
|
||||
}
|
||||
|
||||
if(msg.model && items.length)
|
||||
if(msg.model && items.length) {
|
||||
addDataToModel(msg.model, msg.mode, items)
|
||||
} else {
|
||||
// for some reason, home chokes.
|
||||
console.log( "items.length = " + items.length)
|
||||
}
|
||||
|
||||
/*if(msg.action === "notifications")
|
||||
orderNotifications(items)*/
|
||||
|
||||
console.log("Get em all?")
|
||||
|
||||
WorkerScript.sendMessage({ 'updatedAll': true})
|
||||
});
|
||||
}
|
||||
|
||||
//WorkerScript.sendMessage({ 'notifyNewItems': length - i })
|
||||
|
||||
function addDataToModel (model, mode, items) {
|
||||
|
||||
var length = items.length;
|
||||
console.log("Fetched > " +length)
|
||||
var i
|
||||
|
||||
if (debug) console.log("Fetched > " +length + " in " + mode)
|
||||
if (debug) console.log("ids > " + knownIds.length )
|
||||
|
||||
if (mode === "append") {
|
||||
model.append(items)
|
||||
for(i = 0; i <= length-1; i++) {
|
||||
if ( knownIds.indexOf( items[i]["id"]) === -1) {
|
||||
model.append(items[i])
|
||||
} else {
|
||||
console.log("nope: " + items[i]["id"] )
|
||||
}
|
||||
}
|
||||
// search does not use ids
|
||||
if ( knownIds.length < 1 ) model.append(items)
|
||||
|
||||
} else if (mode === "prepend") {
|
||||
for(var i = length-1; i >= 0 ; i--) {
|
||||
model.insert(0,items[i])
|
||||
for(i = length-1; i >= 0 ; i--) {
|
||||
//model.insert(0,items[i])
|
||||
if ( knownIds.indexOf( items[i]["id"]) === -1) {
|
||||
model.insert(0,items[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
model.sync()
|
||||
}
|
||||
|
||||
/** Function: Get Account Data */
|
||||
function findDuplicate(arr,val) {
|
||||
for(var i=0; i < arr.length; i++){
|
||||
if( arr.indexOf(val) === -1 ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Function: Get Account Data */
|
||||
function parseAccounts(collection, prefix, data) {
|
||||
|
||||
var res = collection;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import QtQuick 2.0
|
||||
import QtQuick 2.6
|
||||
import Sailfish.Silica 1.0
|
||||
import Sailfish.Pickers 1.0
|
||||
import harbour.tooterb.Uploader 1.0
|
||||
import "../lib/API.js" as Logic
|
||||
import "./components/"
|
||||
|
@ -8,6 +9,7 @@ import "./components/"
|
|||
Page {
|
||||
id: conversationPage
|
||||
|
||||
property bool debug: false
|
||||
property ListModel suggestedModel
|
||||
property ListModel mdl
|
||||
property int tootMaxChar: 500
|
||||
|
@ -25,9 +27,11 @@ Page {
|
|||
property string status_link:
|
||||
if (status_url === "") {
|
||||
var test = status_uri.split("/")
|
||||
console.log(status_uri)
|
||||
console.log(JSON.stringify(test))
|
||||
console.log(JSON.stringify(test.length))
|
||||
if (debug) {
|
||||
console.log(status_uri)
|
||||
console.log(JSON.stringify(test))
|
||||
console.log(JSON.stringify(test.length))
|
||||
}
|
||||
if (test.length === 8 && (test[7] === "activity")) {
|
||||
var urialt = status_uri.replace("activity", "")
|
||||
status_link = urialt
|
||||
|
@ -35,9 +39,20 @@ Page {
|
|||
else status_link = status_uri
|
||||
} else status_link = status_url
|
||||
|
||||
|
||||
|
||||
// This function is used by the upload Pickers
|
||||
function fileUpload(file,mime) {
|
||||
imageUploader.setUploadUrl(Logic.conf.instance + "/api/v1/media")
|
||||
imageUploader.setFile(file)
|
||||
imageUploader.setMime(mime)
|
||||
imageUploader.setAuthorizationHeader(Logic.conf.api_user_token)
|
||||
imageUploader.upload()
|
||||
}
|
||||
|
||||
allowedOrientations: Orientation.All
|
||||
onSuggestedUserChanged: {
|
||||
console.log(suggestedUser)
|
||||
//console.log(suggestedUser)
|
||||
suggestedModel = Qt.createQmlObject( 'import QtQuick 2.0; ListModel { }', Qt.application, 'InternalQmlObject' )
|
||||
predictionList.visible = false
|
||||
if (suggestedUser.length > 0) {
|
||||
|
@ -67,7 +82,9 @@ Page {
|
|||
WorkerScript {
|
||||
id: worker
|
||||
source: "../lib/Worker.js"
|
||||
onMessage: { console.log(JSON.stringify(messageObject)) }
|
||||
onMessage: {
|
||||
//console.log(JSON.stringify(messageObject))
|
||||
}
|
||||
}
|
||||
|
||||
SilicaListView {
|
||||
|
@ -98,7 +115,7 @@ Page {
|
|||
if (mdl)
|
||||
for (var i = 0; i < mdl.count; i++) {
|
||||
if (mdl.get(i).status_id === status_id) {
|
||||
console.log(mdl.get(i).status_id)
|
||||
//console.log(mdl.get(i).status_id)
|
||||
positionViewAtIndex(i, ListView.Center)
|
||||
}
|
||||
}
|
||||
|
@ -266,7 +283,7 @@ Page {
|
|||
textOperations.select(
|
||||
textOperations.selectionStart ? textOperations.selectionStart - 1 : 0,
|
||||
textOperations.selectionEnd)
|
||||
console.log(toot.text.length)
|
||||
//console.log(toot.text.length)
|
||||
suggestedUser = ""
|
||||
if (textOperations.selectedText.charAt(0) === "@") {
|
||||
suggestedUser = textOperations.selectedText.trim().substring(1)
|
||||
|
@ -292,7 +309,9 @@ Page {
|
|||
right: parent.right
|
||||
rightMargin: Theme.paddingSmall
|
||||
}
|
||||
onSelectionChanged: { console.log(selection) }
|
||||
onSelectionChanged: {
|
||||
//console.log(selection)
|
||||
}
|
||||
onClicked: pageStack.push(emojiDialog)
|
||||
}
|
||||
|
||||
|
@ -321,7 +340,7 @@ Page {
|
|||
}
|
||||
onClicked: {
|
||||
var idx = index
|
||||
console.log(idx)
|
||||
//console.log(idx)
|
||||
//mediaModel.remove(idx)
|
||||
remorse.execute(myDelegate, "", function () {
|
||||
mediaModel.remove(idx)
|
||||
|
@ -368,7 +387,7 @@ Page {
|
|||
IconButton {
|
||||
id: btnAddImage
|
||||
enabled: mediaModel.count < 4
|
||||
icon.source: "image://theme/icon-s-attach?" + ( pressed ? Theme.highlightColor : (warningContent.visible ? Theme.secondaryHighlightColor : Theme.primaryColor) )
|
||||
icon.source: "image://theme/icon-m-file-image?" + ( pressed ? Theme.highlightColor : (warningContent.visible ? Theme.secondaryHighlightColor : Theme.primaryColor) )
|
||||
anchors {
|
||||
top: toot.bottom
|
||||
topMargin: -Theme.paddingSmall * 1.5
|
||||
|
@ -378,34 +397,97 @@ Page {
|
|||
onClicked: {
|
||||
btnAddImage.enabled = false
|
||||
var once = true
|
||||
var imagePicker = pageStack.push("Sailfish.Pickers.ImagePickerPage", { "allowedOrientations": Orientation.All })
|
||||
imagePicker.selectedContentChanged.connect(function () {
|
||||
var imagePath = imagePicker.selectedContent
|
||||
console.log(imagePath)
|
||||
imageUploader.setUploadUrl(Logic.conf.instance + "/api/v1/media")
|
||||
imageUploader.setFile(imagePath)
|
||||
imageUploader.setAuthorizationHeader(Logic.conf.api_user_token)
|
||||
imageUploader.upload()
|
||||
})
|
||||
pageStack.push(imagePickerPage)
|
||||
}
|
||||
}
|
||||
|
||||
IconButton {
|
||||
id: btnAddMusic
|
||||
enabled: mediaModel.count < 4
|
||||
icon.source: "image://theme/icon-m-file-audio?" + ( pressed ? Theme.highlightColor : (warningContent.visible ? Theme.secondaryHighlightColor : Theme.primaryColor) )
|
||||
anchors {
|
||||
top: toot.bottom
|
||||
topMargin: -Theme.paddingSmall * 1.5
|
||||
left: btnAddImage.right
|
||||
leftMargin: Theme.paddingSmall
|
||||
}
|
||||
onClicked: {
|
||||
btnAddMusic.enabled = false
|
||||
var once = true
|
||||
pageStack.push(musicPickerPage)
|
||||
}
|
||||
}
|
||||
IconButton {
|
||||
id: btnAddVideo
|
||||
enabled: mediaModel.count < 4
|
||||
icon.source: "image://theme/icon-m-file-video?" + ( pressed ? Theme.highlightColor : (warningContent.visible ? Theme.secondaryHighlightColor : Theme.primaryColor) )
|
||||
anchors {
|
||||
top: toot.bottom
|
||||
topMargin: -Theme.paddingSmall * 1.5
|
||||
left: btnAddMusic.right
|
||||
leftMargin: Theme.paddingSmall
|
||||
}
|
||||
onClicked: {
|
||||
btnAddVideo.enabled = false
|
||||
var once = true
|
||||
pageStack.push(videoPickerPage)
|
||||
}
|
||||
}
|
||||
Component {
|
||||
id: musicPickerPage
|
||||
MusicPickerPage {
|
||||
onSelectedContentPropertiesChanged: {
|
||||
var imagePath = selectedContentProperties.url
|
||||
var mimeType = selectedContentProperties.mimeType
|
||||
fileUpload(imagePath,mimeType)
|
||||
/*
|
||||
imageUploader.setUploadUrl(Logic.conf.instance + "/api/v1/media")
|
||||
imageUploader.setFile(imagePath)
|
||||
imageUploader.setMime(mimeType)
|
||||
imageUploader.setAuthorizationHeader(Logic.conf.api_user_token)
|
||||
imageUploader.upload()
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
Component {
|
||||
id: imagePickerPage
|
||||
ImagePickerPage {
|
||||
onSelectedContentPropertiesChanged: {
|
||||
var imagePath = selectedContentProperties.url
|
||||
var mimeType = selectedContentProperties.mimeType
|
||||
fileUpload(imagePath,mimeType)
|
||||
}
|
||||
}
|
||||
}
|
||||
Component {
|
||||
id: videoPickerPage
|
||||
VideoPickerPage {
|
||||
onSelectedContentPropertiesChanged: {
|
||||
var imagePath = selectedContentProperties.url
|
||||
var mimeType = selectedContentProperties.mimeType
|
||||
fileUpload(imagePath,mimeType)
|
||||
}
|
||||
}
|
||||
}
|
||||
ImageUploader {
|
||||
id: imageUploader
|
||||
onProgressChanged: {
|
||||
console.log("progress " + progress)
|
||||
// console.log("progress " + progress)
|
||||
uploadProgress.width = parent.width * progress
|
||||
}
|
||||
onSuccess: {
|
||||
uploadProgress.width = 0
|
||||
console.log(replyData)
|
||||
//console.log(replyData)
|
||||
mediaModel.append(JSON.parse(replyData))
|
||||
}
|
||||
onFailure: {
|
||||
uploadProgress.width = 0
|
||||
btnAddImage.enabled = true
|
||||
console.log(status)
|
||||
console.log(statusText)
|
||||
btnAddMusic.enabled = true
|
||||
btnAddVideo.enabled = true
|
||||
//console.log(status)
|
||||
//console.log(statusText)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -428,7 +510,7 @@ Page {
|
|||
anchors {
|
||||
top: toot.bottom
|
||||
topMargin: -Theme.paddingSmall * 1.5
|
||||
left: btnAddImage.right
|
||||
left: btnAddVideo.right
|
||||
right: btnSend.left
|
||||
}
|
||||
}
|
||||
|
@ -447,7 +529,7 @@ Page {
|
|||
var visibility = ["public", "unlisted", "private", "direct"]
|
||||
var media_ids = []
|
||||
for (var k = 0; k < mediaModel.count; k++) {
|
||||
console.log(mediaModel.get(k).id)
|
||||
// console.log(mediaModel.get(k).id)
|
||||
media_ids.push(mediaModel.get(k).id)
|
||||
}
|
||||
var msg = {
|
||||
|
@ -511,7 +593,7 @@ Page {
|
|||
privacy.currentIndex = setIndex
|
||||
}
|
||||
|
||||
console.log(JSON.stringify())
|
||||
// console.log(JSON.stringify())
|
||||
|
||||
worker.sendMessage({
|
||||
"action": 'statuses/' + mdl.get(0).status_id + '/context',
|
||||
|
|
|
@ -7,6 +7,7 @@ import "../lib/API.js" as Logic
|
|||
|
||||
|
||||
Page {
|
||||
property bool debug: false
|
||||
|
||||
// Python connections and signals, callable from QML side
|
||||
// This is not ideal but keeps the page from erroring out on redirect
|
||||
|
@ -17,13 +18,13 @@ Page {
|
|||
importModule('server', function () {});
|
||||
|
||||
setHandler('finished', function(newvalue) {
|
||||
console.debug(newvalue)
|
||||
if(debug) console.debug(newvalue)
|
||||
});
|
||||
startDownload();
|
||||
}
|
||||
function startDownload() {
|
||||
call('server.downloader.serve', function() {});
|
||||
console.debug("called")
|
||||
if (debug) console.debug("called")
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -64,10 +65,10 @@ Page {
|
|||
Logic.api.registerApplication("Tooter",
|
||||
'http://localhost:8000/index.html', // redirect uri, we will need this later on
|
||||
["read", "write", "follow"], //scopes
|
||||
"http://grave-design.com/harbour-tooter", //website on the login screen
|
||||
"https://github.com/poetaster/harbour-tooter#readme", //website on the login screen
|
||||
function(data) {
|
||||
|
||||
console.log(data)
|
||||
if (debug) console.log(data)
|
||||
var conf = JSON.parse(data)
|
||||
conf.instance = instance.text;
|
||||
conf.login = false;
|
||||
|
@ -78,8 +79,8 @@ Page {
|
|||
conf['mastodon_client_redirect_uri'] = data['mastodon_client_redirect_uri'];
|
||||
delete Logic.conf;*/
|
||||
Logic.conf = conf;
|
||||
console.log(JSON.stringify(conf))
|
||||
console.log(JSON.stringify(Logic.conf))
|
||||
if(debug) console.log(JSON.stringify(conf))
|
||||
if(debug) console.log(JSON.stringify(Logic.conf))
|
||||
// we got our application
|
||||
|
||||
// our user to it!
|
||||
|
@ -88,7 +89,7 @@ Page {
|
|||
"code", // oauth method
|
||||
["read", "write", "follow"] //scopes
|
||||
);
|
||||
console.log(url)
|
||||
if(debug) console.log(url)
|
||||
webView.url = url
|
||||
webView.visible = true
|
||||
}
|
||||
|
@ -128,32 +129,27 @@ Page {
|
|||
}
|
||||
|
||||
onRecvAsyncMessage: {
|
||||
console.log('async changed: ' + url)
|
||||
console.debug(message)
|
||||
if(debug) console.log('async changed: ' + url)
|
||||
if(debug) console.debug(message)
|
||||
switch (message) {
|
||||
case "embed:contentOrientationChanged":
|
||||
break
|
||||
case "webview:action":
|
||||
if ( data.topic != lon ) {
|
||||
//webview.runJavaScript("return latlon('" + lat + "','" + lon + "')");
|
||||
//if (debug) console.debug(data.topic)
|
||||
//if (debug) console.debug(data.also)
|
||||
//if (debug) console.debug(data.src)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
visible: false
|
||||
//opacity: 0
|
||||
anchors {
|
||||
anchors.fill: parent
|
||||
/*{
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
}*/
|
||||
|
||||
onLoadingChanged: {
|
||||
console.log('loading changed: ' + url)
|
||||
if(debug) console.log('loading changed: ' + url)
|
||||
if (
|
||||
(url+"").substr(0, 38) === 'http://localhost:8000/index.html?code=' ||
|
||||
(url+"").substr(0, 39) === 'https://localhost:8000/index.html?code='
|
||||
|
@ -165,7 +161,7 @@ Page {
|
|||
|
||||
var authCode = vars["code"];
|
||||
|
||||
console.log(authCode)
|
||||
if(debug) console.log(authCode)
|
||||
|
||||
Logic.api.getAccessTokenFromAuthCode(
|
||||
Logic.conf["client_id"],
|
||||
|
@ -174,10 +170,10 @@ Page {
|
|||
authCode,
|
||||
function(data) {
|
||||
// AAAND DATA CONTAINS OUR TOKEN!
|
||||
console.log(data)
|
||||
if(debug) console.log(data)
|
||||
data = JSON.parse(data)
|
||||
console.log(JSON.stringify(data))
|
||||
console.log(JSON.stringify(data.access_token))
|
||||
if(debug) console.log(JSON.stringify(data))
|
||||
if(debug) console.log(JSON.stringify(data.access_token))
|
||||
Logic.conf["api_user_token"] = data.access_token
|
||||
Logic.conf["login"] = true;
|
||||
Logic.api.setConfig("api_user_token", Logic.conf["api_user_token"])
|
||||
|
|
|
@ -6,7 +6,7 @@ import "./components/"
|
|||
|
||||
Page {
|
||||
id: mainPage
|
||||
|
||||
property bool debug: false
|
||||
property bool isFirstPage: true
|
||||
property bool isTablet: true //Screen.sizeCategory >= Screen.Large
|
||||
|
||||
|
@ -24,7 +24,8 @@ Page {
|
|||
id: navigation
|
||||
isPortrait: !mainPage.isPortrait
|
||||
onSlideshowShow: {
|
||||
console.log(vIndex)
|
||||
if (debug) console.log(vIndex)
|
||||
|
||||
slideshow.positionViewAtIndex(vIndex, ListView.SnapToItem)
|
||||
}
|
||||
}
|
||||
|
@ -74,6 +75,15 @@ Page {
|
|||
height: parent.itemHeight
|
||||
onOpenDrawer: isPortrait ? infoPanel.open = setDrawer : infoPanel.open = true
|
||||
}
|
||||
MyList {
|
||||
id: tlBookmarks
|
||||
title: qsTr("Bookmarks")
|
||||
type: "bookmarks"
|
||||
mdl: Logic.modelTLbookmarks
|
||||
width: isPortrait ? parent.itemWidth : parent.itemWidth - Theme.itemSizeLarge
|
||||
height: parent.itemHeight
|
||||
onOpenDrawer: isPortrait ? infoPanel.open = setDrawer : infoPanel.open = true
|
||||
}
|
||||
|
||||
Item {
|
||||
id: tlSearch
|
||||
|
@ -84,7 +94,7 @@ Page {
|
|||
width: isPortrait ? parent.itemWidth : parent.itemWidth - Theme.itemSizeLarge
|
||||
height: parent.itemHeight
|
||||
onSearchChanged: {
|
||||
console.log(search)
|
||||
if (debug) console.log(search)
|
||||
loader.sourceComponent = loading
|
||||
if (search.charAt(0) === "@") {
|
||||
loader.sourceComponent = userListComponent
|
||||
|
@ -114,7 +124,7 @@ Page {
|
|||
EnterKey.onClicked: {
|
||||
tlSearch.search = text.toLowerCase().trim()
|
||||
focus = false
|
||||
console.log(text)
|
||||
if (debug) console.log(text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -148,7 +158,11 @@ Page {
|
|||
delegate: VisualContainer
|
||||
Component.onCompleted: {
|
||||
view.type = "timelines/tag/"+tlSearch.search.substring(1)
|
||||
view.loadData("append")
|
||||
if (mdl.count) {
|
||||
view.loadData("append")
|
||||
} else {
|
||||
view.loadData("prepend")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -220,7 +234,11 @@ Page {
|
|||
delegate: VisualContainer
|
||||
Component.onCompleted: {
|
||||
view3.type = "timelines/tag/"+tlSearch.search
|
||||
view3.loadData("append")
|
||||
if (mdl.count) {
|
||||
view3.loadData("append")
|
||||
} else {
|
||||
view3.loadData("prepend")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -270,17 +288,21 @@ Page {
|
|||
|
||||
function onLinkActivated(href) {
|
||||
var test = href.split("/")
|
||||
console.log(href)
|
||||
console.log(JSON.stringify(test))
|
||||
console.log(JSON.stringify(test.length))
|
||||
debug = true
|
||||
if (debug) {
|
||||
console.log(href)
|
||||
console.log(JSON.stringify(test))
|
||||
console.log(JSON.stringify(test.length))
|
||||
}
|
||||
if (test.length === 5 && (test[3] === "tags" || test[3] === "tag") ) {
|
||||
tlSearch.search = "#"+decodeURIComponent(test[4])
|
||||
slideshow.positionViewAtIndex(4, ListView.SnapToItem)
|
||||
slideshow.positionViewAtIndex(5, ListView.SnapToItem)
|
||||
navigation.navigateTo('search')
|
||||
if (debug) console.log("search tag")
|
||||
|
||||
} else if (test.length === 4 && test[3][0] === "@" ) {
|
||||
tlSearch.search = decodeURIComponent("@"+test[3].substring(1)+"@"+test[2])
|
||||
slideshow.positionViewAtIndex(4, ListView.SnapToItem)
|
||||
slideshow.positionViewAtIndex(5, ListView.SnapToItem)
|
||||
navigation.navigateTo('search')
|
||||
|
||||
} else {
|
||||
|
@ -289,6 +311,6 @@ Page {
|
|||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
console.log("aaa")
|
||||
//console.log("aaa")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,12 +29,13 @@ Page {
|
|||
property bool muting: false
|
||||
property bool domain_blocking: false
|
||||
property date created_at
|
||||
property bool debug: false
|
||||
|
||||
WorkerScript {
|
||||
id: worker
|
||||
source: "../lib/Worker.js"
|
||||
onMessage: {
|
||||
console.log(JSON.stringify(messageObject))
|
||||
if (debug) console.log(JSON.stringify(messageObject))
|
||||
if(messageObject.action.indexOf("accounts/search") > -1 ){
|
||||
user_id = messageObject.data.id
|
||||
followers_count = messageObject.data.followers_count
|
||||
|
@ -54,7 +55,7 @@ Page {
|
|||
}
|
||||
|
||||
if(messageObject.action === "accounts/relationships/"){
|
||||
console.log(JSON.stringify(messageObject))
|
||||
if (debug) console.log(JSON.stringify(messageObject))
|
||||
following = messageObject.data.following
|
||||
requested = messageObject.data.requested
|
||||
followed_by = messageObject.data.followed_by
|
||||
|
@ -190,9 +191,9 @@ Page {
|
|||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
onLinkActivated: {
|
||||
var test = link.split("/")
|
||||
console.log(link)
|
||||
console.log(JSON.stringify(test))
|
||||
console.log(JSON.stringify(test.length))
|
||||
if (debug) console.log(link)
|
||||
if (debug) console.log(JSON.stringify(test))
|
||||
if (debug) console.log(JSON.stringify(test.length))
|
||||
if (test.length === 5 && (test[3] === "tags" || test[3] === "tag") ) {
|
||||
pageStack.pop(pageStack.find(function(page) {
|
||||
var check = page.isFirstPage === true;
|
||||
|
|
|
@ -148,10 +148,17 @@ Page {
|
|||
}
|
||||
|
||||
ListElement {
|
||||
name: "Molan"
|
||||
name: "molan"
|
||||
desc: qsTr("Development and translations")
|
||||
mastodon: "molan@fosstodon.org"
|
||||
mail: ""
|
||||
mail: "mol_an@sunrise.ch"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
name: "poetaster"
|
||||
desc: qsTr("Development")
|
||||
mastodon: "postaster@mastodon.gamedev.place"
|
||||
mail: "blueprint@poetaster.de"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
|
|
|
@ -10,14 +10,18 @@ Item {
|
|||
property double wRatio : 16/9
|
||||
property double hRatio : 9/16
|
||||
|
||||
property bool debug: false
|
||||
width: width
|
||||
height: height
|
||||
Component.onCompleted: {
|
||||
if(debug) console.log("MB: " + JSON.stringify(model.get(0)))
|
||||
|
||||
if (model && model.count && model.get(0).type === "video") {
|
||||
//console.log("Mediablock")
|
||||
//console.log(JSON.stringify(model.get(0).type))
|
||||
while (model.count>1) {
|
||||
model.remove(model.count-1)
|
||||
}
|
||||
//console.log(JSON.stringify(model.get(0)))
|
||||
}
|
||||
var count = 0
|
||||
if (model && model.count)
|
||||
|
@ -89,6 +93,8 @@ Item {
|
|||
type = model.get(0).type
|
||||
previewURL = model.get(0).preview_url
|
||||
mediaURL = model.get(0).url
|
||||
url = model.get(0).url
|
||||
if(debug) console.log( model.get(0).url )
|
||||
height = Theme.itemSizeLarge
|
||||
return true
|
||||
} else {
|
||||
|
@ -108,6 +114,8 @@ Item {
|
|||
type = model.get(1).type
|
||||
previewURL = model.get(1).preview_url
|
||||
mediaURL = model.get(1).url
|
||||
url = model.get(0).url
|
||||
if(debug) console.log( model.get(1).url )
|
||||
height = Theme.itemSizeLarge
|
||||
return true
|
||||
} else {
|
||||
|
@ -127,6 +135,7 @@ Item {
|
|||
type = model.get(2).type
|
||||
previewURL = model.get(2).preview_url
|
||||
mediaURL = model.get(2).url
|
||||
url = model.get(0).url
|
||||
height = Theme.itemSizeLarge
|
||||
return true
|
||||
} else {
|
||||
|
@ -146,6 +155,7 @@ Item {
|
|||
type = model.get(3).type
|
||||
previewURL = model.get(3).preview_url
|
||||
mediaURL = model.get(3).url
|
||||
url = model.get(0).url
|
||||
height = Theme.itemSizeLarge
|
||||
return true
|
||||
} else {
|
||||
|
|
|
@ -9,15 +9,26 @@ FullscreenContentPage {
|
|||
property string type: ""
|
||||
property string previewURL: ""
|
||||
property string mediaURL: ""
|
||||
property string url: ""
|
||||
property bool debug: false
|
||||
|
||||
allowedOrientations: Orientation.All
|
||||
Component.onCompleted: function() {
|
||||
console.log(type)
|
||||
console.log(previewURL)
|
||||
console.log(mediaURL)
|
||||
if (debug) {
|
||||
console.log(type)
|
||||
console.log(previewURL)
|
||||
console.log(mediaURL)
|
||||
}
|
||||
if (type != 'gifv' && type != 'video') {
|
||||
imagePreview.source = mediaURL
|
||||
imageFlickable.visible = true
|
||||
} else if( type == 'audio'){
|
||||
video.source = url
|
||||
videoFlickable.visible = true
|
||||
playerIcon.visible = true
|
||||
playerProgress.visible = true
|
||||
video.play()
|
||||
hideTimer.start()
|
||||
} else {
|
||||
video.source = mediaURL
|
||||
video.fillMode = VideoOutput.PreserveAspectFit
|
||||
|
@ -50,18 +61,18 @@ FullscreenContentPage {
|
|||
videoError.visible = true
|
||||
}
|
||||
onStatusChanged: {
|
||||
console.log(status)
|
||||
if(debug) console.log(status)
|
||||
switch (status) {
|
||||
case MediaPlayer.Loading:
|
||||
console.log("loading")
|
||||
if(debug) console.log("loading")
|
||||
return;
|
||||
case MediaPlayer.EndOfMedia:
|
||||
console.log("EndOfMedia")
|
||||
if (debug) console.log("EndOfMedia")
|
||||
return;
|
||||
}
|
||||
}
|
||||
onPlaybackStateChanged: {
|
||||
console.log(playbackState)
|
||||
if (debug) console.log(playbackState)
|
||||
switch (playbackState) {
|
||||
case MediaPlayer.PlayingState:
|
||||
playerIcon.icon.source = "image://theme/icon-m-pause"
|
||||
|
|
323
qml/pages/components/MediaItem.qml
Normal file
323
qml/pages/components/MediaItem.qml
Normal file
|
@ -0,0 +1,323 @@
|
|||
import QtQuick 2.6
|
||||
import Sailfish.Silica 1.0
|
||||
import QtMultimedia 5.6
|
||||
|
||||
|
||||
|
||||
ListItem {
|
||||
id: item
|
||||
|
||||
property string url
|
||||
property string mediaUrl
|
||||
property string mimeType: 'audio/mp3'
|
||||
property int length
|
||||
|
||||
property bool _isAudio: mimeType.substring(0, 6) === "audio/"
|
||||
property bool _isImage: mimeType.substring(0, 6) === "image/"
|
||||
|
||||
function _toTime(s)
|
||||
{
|
||||
if (s < 0)
|
||||
{
|
||||
return "-";
|
||||
}
|
||||
|
||||
s /= 1000;
|
||||
var seconds = Math.floor(s) % 60;
|
||||
s /= 60;
|
||||
var minutes = Math.floor(s) % 60;
|
||||
s /= 60;
|
||||
var hours = Math.floor(s);
|
||||
|
||||
if (seconds < 10)
|
||||
{
|
||||
seconds = "0" + seconds;
|
||||
}
|
||||
if (minutes < 10)
|
||||
{
|
||||
minutes = "0" + minutes;
|
||||
}
|
||||
|
||||
if (hours > 0)
|
||||
{
|
||||
return hours + ":" + minutes + ":" + seconds;
|
||||
}
|
||||
else
|
||||
{
|
||||
return minutes + ":" + seconds;
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns the filename of the given URL.
|
||||
*/
|
||||
function _urlFilename(url) {
|
||||
var idx = url.lastIndexOf("=");
|
||||
if (idx !== -1) {
|
||||
return url.substring(idx + 1);
|
||||
}
|
||||
|
||||
idx = url.lastIndexOf("/");
|
||||
if (idx === url.length - 1) {
|
||||
idx = url.substring(0, idx).lastIndexOf("/");
|
||||
}
|
||||
|
||||
if (idx !== -1) {
|
||||
return url.substring(idx + 1);
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
/* Returns the icon source for the given media.
|
||||
*/
|
||||
function _mediaIcon(url, type) {
|
||||
if (type.substring(0, 6) === "image/") {
|
||||
return url;
|
||||
} else if (type.substring(0, 6) === "video/") {
|
||||
return "image://theme/icon-l-play";
|
||||
} else {
|
||||
return "image://theme/icon-m-other";
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns a user-friendly media type name for the given MIME type.
|
||||
*/
|
||||
function _mediaTypeName(type) {
|
||||
if (type.substring(0, 6) === "image/") {
|
||||
return qsTr("Image");
|
||||
} else if (type.substring(0, 6) === "video/") {
|
||||
return qsTr("Video");
|
||||
} else if (type === "application/pdf") {
|
||||
return qsTr("PDF document");
|
||||
} else {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
console.log('MediaItem')
|
||||
console.log(url)
|
||||
console.log(mediaUrl)
|
||||
if (_isAudio)
|
||||
{
|
||||
if (audioProxy.playing)
|
||||
{
|
||||
audioProxy.pause();
|
||||
}
|
||||
else
|
||||
{
|
||||
audioProxy.play();
|
||||
}
|
||||
}
|
||||
else if (_isImage)
|
||||
{
|
||||
var props = {
|
||||
"url": item.url,
|
||||
"name": _urlFilename(item.url)
|
||||
}
|
||||
pageStack.push(Qt.resolvedUrl("ImagePage.qml"), props);
|
||||
}
|
||||
else
|
||||
{
|
||||
Qt.openUrlExternally(item.url);
|
||||
}
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: audioProxy
|
||||
|
||||
property bool _active: audioPlayer.source == source
|
||||
property bool playing: _active ? audioPlayer.playing
|
||||
: false
|
||||
property bool paused: _active ? audioPlayer.paused
|
||||
: false
|
||||
property real duration: _active ? audioPlayer.duration
|
||||
: -1
|
||||
property real position: _active ? audioPlayer.position
|
||||
: 0
|
||||
|
||||
property string source: _isAudio ? item.url : ""
|
||||
|
||||
property Timer _seeker: Timer {
|
||||
interval: 50
|
||||
|
||||
onTriggered: {
|
||||
if (audioProxy._active)
|
||||
{
|
||||
if (! audioPlayer.playing)
|
||||
{
|
||||
console.log("Stream is not ready. Deferring seek operation.")
|
||||
_seeker.start();
|
||||
}
|
||||
else
|
||||
{
|
||||
audioPlayer.seek(Math.max(0, database.audioBookmark(audioProxy.source) - 3000));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function play()
|
||||
{
|
||||
if (_active)
|
||||
{
|
||||
audioPlayer.play();
|
||||
}
|
||||
else
|
||||
{
|
||||
// save bookmark before switching to another podcast
|
||||
if (audioPlayer.playing)
|
||||
{
|
||||
database.setAudioBookmark(audioPlayer.source,
|
||||
audioPlayer.position);
|
||||
}
|
||||
|
||||
audioPlayer.stop();
|
||||
audioPlayer.source = source;
|
||||
audioPlayer.play();
|
||||
_seeker.start();
|
||||
}
|
||||
}
|
||||
|
||||
function pause()
|
||||
{
|
||||
if (_active)
|
||||
{
|
||||
//database.setAudioBookmark(source, audioPlayer.position);
|
||||
audioPlayer.pause();
|
||||
}
|
||||
}
|
||||
|
||||
function seek(value)
|
||||
{
|
||||
if (_active) audioPlayer.seek(value);
|
||||
}
|
||||
|
||||
onPositionChanged: {
|
||||
if (_active)
|
||||
{
|
||||
if (! slider.down)
|
||||
{
|
||||
slider.value = position;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onDurationChanged: {
|
||||
if (_active)
|
||||
{
|
||||
slider.maximumValue = duration;
|
||||
}
|
||||
}
|
||||
}
|
||||
Audio {
|
||||
id: audioPlayer
|
||||
property bool playing: playbackState === Audio.PlayingState
|
||||
property bool paused: playbackState === Audio.PausedState
|
||||
autoLoad: false
|
||||
autoPlay: false
|
||||
}
|
||||
Image {
|
||||
id: mediaIcon
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Theme.paddingLarge
|
||||
anchors.rightMargin: Theme.paddingMedium
|
||||
width: height
|
||||
height: parent.height
|
||||
asynchronous: true
|
||||
smooth: true
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
sourceSize.width: width * 2
|
||||
sourceSize.height: height * 2
|
||||
source: ! _isAudio ? _mediaIcon(item.url, item.mimeType)
|
||||
: audioProxy.playing ? "image://theme/icon-l-pause"
|
||||
: "image://theme/icon-l-play"
|
||||
clip: true
|
||||
|
||||
BusyIndicator {
|
||||
running: parent.status === Image.Loading
|
||||
anchors.centerIn: parent
|
||||
size: BusyIndicatorSize.Medium
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
id: mediaNameLabel
|
||||
|
||||
anchors.left: mediaIcon.right
|
||||
anchors.right: parent.right
|
||||
anchors.leftMargin: Theme.paddingLarge
|
||||
anchors.rightMargin: Theme.paddingLarge
|
||||
truncationMode: TruncationMode.Fade
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.primaryColor
|
||||
text: _urlFilename(item.url)
|
||||
}
|
||||
Label {
|
||||
id: label1
|
||||
anchors.top: mediaNameLabel.bottom
|
||||
anchors.left: mediaNameLabel.left
|
||||
font.pixelSize: Theme.fontSizeExtraSmall
|
||||
color: Theme.secondaryColor
|
||||
text: ! slider.visible ? _mediaTypeName(item.mimeType)
|
||||
: audioProxy.playing ? _toTime(slider.sliderValue)
|
||||
: _toTime(database.audioBookmark(audioProxy.source))
|
||||
|
||||
}
|
||||
Label {
|
||||
id: label2
|
||||
anchors.top: mediaNameLabel.bottom
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Theme.paddingLarge
|
||||
font.pixelSize: Theme.fontSizeExtraSmall
|
||||
color: Theme.secondaryColor
|
||||
text: slider.visible ? _toTime(audioProxy.duration)
|
||||
: item.length >= 0 ? Format.formatFileSize(item.length)
|
||||
: ""
|
||||
}
|
||||
|
||||
Slider {
|
||||
id: slider
|
||||
|
||||
visible: _isAudio
|
||||
enabled: audioProxy.playing || audioProxy.paused
|
||||
|
||||
anchors.left: label1.right
|
||||
anchors.right: label2.left
|
||||
anchors.verticalCenter: label1.verticalCenter
|
||||
|
||||
leftMargin: Theme.paddingSmall
|
||||
rightMargin: Theme.paddingSmall
|
||||
height: Theme.itemSizeSmall / 3
|
||||
|
||||
handleVisible: false
|
||||
minimumValue: 0
|
||||
|
||||
onDownChanged: {
|
||||
if (! down)
|
||||
{
|
||||
audioProxy.seek(sliderValue);
|
||||
if (! audioProxy.playing)
|
||||
{
|
||||
audioProxy.play();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}//Slider
|
||||
IconButton {
|
||||
id: mediaDlBtn
|
||||
icon.source: "image://theme/icon-m-cloud-download"
|
||||
anchors {
|
||||
right: parent.right
|
||||
rightMargin: Theme.horizontalPageMargin
|
||||
bottom: parent.bottom
|
||||
bottomMargin: Theme.horizontalPageMargin
|
||||
}
|
||||
onClicked: {
|
||||
var filename = url.split("/")
|
||||
FileDownloader.downloadFile(url, filename[filename.length-1])
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ import "."
|
|||
SilicaListView {
|
||||
id: myList
|
||||
|
||||
property bool debug: false
|
||||
property string type
|
||||
property string title
|
||||
property string description
|
||||
|
@ -17,15 +18,21 @@ SilicaListView {
|
|||
property bool loadStarted: false
|
||||
property int scrollOffset
|
||||
property string action: ""
|
||||
// should consider better names or
|
||||
// using min_ & max_id
|
||||
property string linkprev: ""
|
||||
property string linknext: ""
|
||||
property variant vars
|
||||
property variant conf
|
||||
property bool notifier: false
|
||||
property bool deduping: false
|
||||
property variant uniqueIds: []
|
||||
|
||||
model: mdl
|
||||
|
||||
signal notify (string what, int num)
|
||||
onNotify: {
|
||||
console.log(what + " - " + num)
|
||||
if(debug) console.log(what + " - " + num)
|
||||
}
|
||||
signal openDrawer (bool setDrawer)
|
||||
onOpenDrawer: {
|
||||
|
@ -33,7 +40,7 @@ SilicaListView {
|
|||
}
|
||||
signal send (string notice)
|
||||
onSend: {
|
||||
console.log("LIST send signal emitted with notice: " + notice)
|
||||
if (debug) console.log("LIST send signal emitted with notice: " + notice)
|
||||
}
|
||||
|
||||
header: PageHeader {
|
||||
|
@ -75,7 +82,6 @@ SilicaListView {
|
|||
pageStack.push(Qt.resolvedUrl("../SettingsPage.qml"), {})
|
||||
}
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
text: qsTr("New Toot")
|
||||
visible: !profilePage
|
||||
|
@ -115,7 +121,10 @@ SilicaListView {
|
|||
}
|
||||
|
||||
onCountChanged: {
|
||||
loadStarted = false
|
||||
if (debug) console.log("count changed on: " + title)
|
||||
//deDouble()
|
||||
//loadStarted = false
|
||||
|
||||
/*contentY = scrollOffset
|
||||
console.log("CountChanged!")*/
|
||||
}
|
||||
|
@ -130,7 +139,7 @@ SilicaListView {
|
|||
anchors.bottomMargin: Theme.paddingLarge
|
||||
visible: false
|
||||
onClicked: {
|
||||
loadData("append")
|
||||
if (!loadStarted && !deduping) loadData("append")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -150,9 +159,9 @@ SilicaListView {
|
|||
openDrawer(contentY - scrollOffset > 0 ? false : true )
|
||||
scrollOffset = contentY
|
||||
}
|
||||
if(contentY+height > footerItem.y && !loadStarted && autoLoadMore) {
|
||||
loadData("append")
|
||||
loadStarted = true
|
||||
if(contentY+height > footerItem.y && !deduping && !loadStarted && autoLoadMore) {
|
||||
loadStarted = true
|
||||
loadData("append")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -163,37 +172,198 @@ SilicaListView {
|
|||
source: "../../lib/Worker.js"
|
||||
onMessage: {
|
||||
if (messageObject.error){
|
||||
console.log(JSON.stringify(messageObject))
|
||||
if (debug) console.log(JSON.stringify(messageObject))
|
||||
} else {
|
||||
if (debug) console.log(JSON.stringify(messageObject))
|
||||
// loadStarted = false
|
||||
}
|
||||
|
||||
if (messageObject.fireNotification && notifier){
|
||||
Logic.notifier(messageObject.data)
|
||||
}
|
||||
|
||||
// temporary debugging measure
|
||||
if (messageObject.updatedAll){
|
||||
if (debug) console.log("Got em all.")
|
||||
if (model.count > 20) deDouble()
|
||||
loadStarted = false
|
||||
}
|
||||
|
||||
// the api is stupid
|
||||
if (messageObject.LinkHeader) {
|
||||
// <https://mastodon.gamedev.place/api/v1/bookmarks?max_id=11041>; rel=\"next\",
|
||||
// <https://mastodon.gamedev.place/api/v1/bookmarks?min_id=14158>; rel=\"prev\""
|
||||
|
||||
var matches = /max_id=([0-9]+)/.exec(messageObject.LinkHeader);
|
||||
var maxlink = matches[0].split("=")[1];
|
||||
var matches = /min_id=([0-9]+)/.exec(messageObject.LinkHeader);
|
||||
var minlink = matches[0].split("=")[1];
|
||||
if (debug) console.log("maxlink: " + maxlink)
|
||||
if (debug) console.log("minlink: " + minlink)
|
||||
linkprev = maxlink
|
||||
linknext = minlink
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
loadData("prepend")
|
||||
if (debug) console.log("MyList completed: " + title)
|
||||
}
|
||||
|
||||
Timer {
|
||||
triggeredOnStart: false; interval: 5*60*1000; running: true; repeat: true
|
||||
triggeredOnStart: false;
|
||||
interval: {
|
||||
|
||||
/*
|
||||
* Varied calls so that server isn't hit
|
||||
* simultaenously ... this is hamfisted
|
||||
*/
|
||||
var listInterval = Math.floor(Math.random() * 60)*10*1000
|
||||
if( title === "Home" ) listInterval = 20*60*1000
|
||||
if( title === "Local" ) listInterval = 10*60*1000
|
||||
if( title === "Federated" ) listInterval = 30*60*1000
|
||||
if( title === "Bookmarks" ) listInterval = 40*60*1000
|
||||
if( title === "Notifications" ) listInterval = 12*60*1000
|
||||
|
||||
if(debug) console.log(title + ' interval: ' + listInterval)
|
||||
|
||||
return listInterval
|
||||
}
|
||||
running: true;
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
console.log(title + ' ' +Date().toString())
|
||||
loadData("prepend")
|
||||
if(debug) console.log(title + ' ' + Date().toString())
|
||||
// let's avoid pre and appending at the same time!
|
||||
if ( ! loadStarted && ! deduping ) loadData("prepend")
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* NOT actually doing deduping :)
|
||||
* utility called on updates to model to remove remove Duplicates:
|
||||
* the dupes are probably a result of improper syncing of the models
|
||||
* this is temporary and can probaly be removed because of the
|
||||
* loadData method passing in to the WorkerScript
|
||||
*/
|
||||
function deDouble(){
|
||||
|
||||
deduping = true
|
||||
var ids = []
|
||||
var uniqueItems = []
|
||||
var i
|
||||
var j
|
||||
var seenIt = 0
|
||||
|
||||
if (debug) console.log(model.count)
|
||||
|
||||
for(i = 0 ; i < model.count ; i++) {
|
||||
ids.push(model.get(i).id)
|
||||
uniqueItems = removeDuplicates(ids)
|
||||
|
||||
}
|
||||
//if (debug) console.log(ids)
|
||||
if (debug) console.log(uniqueItems.length)
|
||||
if (debug) console.log( "max-one?:" + model.get(model.count - 2).id )
|
||||
if (debug) console.log( "max:" + model.get(model.count - 1).id )
|
||||
|
||||
if ( uniqueItems.length < model.count) {
|
||||
|
||||
// it seems that only the last one, is an issue
|
||||
/*if (model.get(model.count - 1).id > model.get(model.count - 2).id){
|
||||
model.remove(model.count - 1,1)
|
||||
}*/
|
||||
|
||||
if (debug) console.log(model.count)
|
||||
for(j = 0; j <= uniqueItems.length - 1 ; j++) {
|
||||
seenIt = 0
|
||||
for(i = 0 ; i < model.count - 1 ; i++) {
|
||||
if (model.get(i).id === uniqueItems[j]){
|
||||
seenIt = seenIt+1
|
||||
if (seenIt > 1) {
|
||||
if (debug) console.log(uniqueItems[j] + " - " + seenIt)
|
||||
|
||||
// model.remove(i,1) // (model.get(i))
|
||||
seenIt = seenIt-1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
deduping = false
|
||||
}
|
||||
|
||||
/* utility function because this version of qt doesn't support modern javascript
|
||||
*
|
||||
*/
|
||||
function removeDuplicates(arr) {
|
||||
var unique = [];
|
||||
for(var i=0; i < arr.length; i++){
|
||||
if(unique.indexOf(arr[i]) === -1) {
|
||||
unique.push(arr[i]);
|
||||
}
|
||||
}
|
||||
return unique;
|
||||
}
|
||||
|
||||
|
||||
/* Principle load function, uses websocket's worker.js
|
||||
*
|
||||
*/
|
||||
|
||||
function loadData(mode) {
|
||||
|
||||
if (debug) console.log('loadData called: ' + mode + " in " + title)
|
||||
// since the worker adds Duplicates
|
||||
// we pass in current ids in the model
|
||||
// and skip those on insert append in the worker
|
||||
for(var i = 0 ; i < model.count ; i++) {
|
||||
uniqueIds.push(model.get(i).id)
|
||||
//if (debug) console.log(model.get(i).id)
|
||||
}
|
||||
uniqueIds = removeDuplicates(uniqueIds)
|
||||
|
||||
var p = []
|
||||
if (params.length) {
|
||||
for(var i = 0; i<params.length; i++)
|
||||
p.push(params[i])
|
||||
}
|
||||
|
||||
/*
|
||||
* for some types, min_id, max_id
|
||||
* is obtained from link header
|
||||
*/
|
||||
|
||||
if (mode === "append" && model.count) {
|
||||
p.push({name: 'max_id', data: model.get(model.count-1).id})
|
||||
if ( linkprev === "" ) {
|
||||
p.push({name: 'max_id', data: model.get(model.count-1).id})
|
||||
} else {
|
||||
p.push({name: 'max_id', data: linkprev})
|
||||
}
|
||||
}
|
||||
if (mode === "prepend" && model.count) {
|
||||
p.push({name:'since_id', data: model.get(0).id})
|
||||
if ( linknext === "" ) {
|
||||
p.push({name:'since_id', data: model.get(0).id})
|
||||
} else {
|
||||
p.push({name: 'since_id', data: linknext})
|
||||
}
|
||||
//p.push({name:'since_id', data: model.get(0).id})
|
||||
}
|
||||
|
||||
// to keep the number of params the same for all requests
|
||||
// always set local
|
||||
|
||||
if(title === "Local") {
|
||||
type = "timelines/public"
|
||||
p.push({name:'local', data: "true"})
|
||||
} else {
|
||||
p.push({name:'local', data: "false"})
|
||||
}
|
||||
|
||||
// we push the ids via params which we remove in the WorkerScript
|
||||
if (model.count) {
|
||||
p.push({name:'ids', data: uniqueIds})
|
||||
}
|
||||
|
||||
var msg = {
|
||||
|
@ -204,8 +374,9 @@ SilicaListView {
|
|||
'conf' : Logic.conf
|
||||
}
|
||||
|
||||
console.log(JSON.stringify(msg))
|
||||
//if (debug) console.log(JSON.stringify(msg))
|
||||
if (type !== "")
|
||||
worker.sendMessage(msg)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import QtQuick 2.0
|
||||
import Sailfish.Silica 1.0
|
||||
import QtMultimedia 5.0
|
||||
import QtMultimedia 5.6
|
||||
|
||||
|
||||
Item {
|
||||
|
@ -9,6 +9,7 @@ Item {
|
|||
property string type : ""
|
||||
property string previewURL: ""
|
||||
property string mediaURL: ""
|
||||
property string url: ""
|
||||
|
||||
Rectangle {
|
||||
opacity: 0.4
|
||||
|
@ -32,12 +33,37 @@ Item {
|
|||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
Image {
|
||||
/*Text {
|
||||
anchors{
|
||||
topMargin: 10
|
||||
}
|
||||
id: audioUrl
|
||||
visible: type == 'audio'
|
||||
//opacity: img.status === Image.Ready ? 0.0 : 1.0
|
||||
text: "<a href='" + url + "'>" + 'Audio file' + '</a>'
|
||||
font.pixelSize: Theme.fontSizeLarge
|
||||
}*/
|
||||
|
||||
|
||||
MediaItem {
|
||||
id: audioContent
|
||||
visible: type == 'audio'
|
||||
opacity: img.status === Image.Ready ? 0.0 : 1.0
|
||||
Behavior on opacity { FadeAnimator {} }
|
||||
source: "image://theme/icon-m-file-audio?"
|
||||
mimeType: 'audio/mp3'
|
||||
url: mediaURL
|
||||
mediaUrl: mediaURL
|
||||
//source: "image://theme/icon-m-file-audio?"
|
||||
anchors.centerIn: parent
|
||||
/*MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
pageStack.push(Qt.resolvedUrl("./MediaItem.qml"), {
|
||||
"url": url,
|
||||
"type": type,
|
||||
"mimeType": type
|
||||
})
|
||||
}
|
||||
} */
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
|
@ -67,6 +93,7 @@ Item {
|
|||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
visible: type != 'audio'
|
||||
onClicked: {
|
||||
pageStack.push(Qt.resolvedUrl("./MediaFullScreen.qml"), {
|
||||
"previewURL": previewURL,
|
||||
|
@ -109,5 +136,19 @@ Item {
|
|||
onClicked: parent.visible = false
|
||||
}
|
||||
}
|
||||
/*IconButton {
|
||||
id: mediaDlBtn
|
||||
icon.source: "image://theme/icon-m-cloud-download"
|
||||
anchors {
|
||||
right: parent.right
|
||||
rightMargin: Theme.horizontalPageMargin
|
||||
bottom: parent.bottom
|
||||
bottomMargin: Theme.horizontalPageMargin
|
||||
}
|
||||
onClicked: {
|
||||
var filename = url.split("/")
|
||||
FileDownloader.downloadFile(url, filename[filename.length-1])
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,6 @@ SilicaGridView {
|
|||
active: false
|
||||
unread: false
|
||||
}
|
||||
|
||||
ListElement {
|
||||
icon: "image://theme/icon-m-website?"
|
||||
slug: "federated"
|
||||
|
@ -47,6 +46,14 @@ SilicaGridView {
|
|||
unread: false
|
||||
}
|
||||
|
||||
ListElement {
|
||||
icon: "../../images/icon-m-bookmark.svg?"
|
||||
//icon: "image://theme/icon-m-bookmark"
|
||||
slug: "bookmarks"
|
||||
name: "Bookmarks"
|
||||
active: false
|
||||
unread: false
|
||||
}
|
||||
ListElement {
|
||||
icon: "image://theme/icon-m-search?"
|
||||
slug: "search"
|
||||
|
|
|
@ -6,6 +6,8 @@ import "../../lib/API.js" as Logic
|
|||
BackgroundItem {
|
||||
id: delegate
|
||||
|
||||
property bool debug:false
|
||||
|
||||
signal send (string notice)
|
||||
signal navigateTo(string link)
|
||||
|
||||
|
@ -195,9 +197,11 @@ BackgroundItem {
|
|||
}
|
||||
onLinkActivated: {
|
||||
var test = link.split("/")
|
||||
console.log(link)
|
||||
console.log(JSON.stringify(test))
|
||||
console.log(JSON.stringify(test.length))
|
||||
if (debug) {
|
||||
console.log(link)
|
||||
console.log(JSON.stringify(test))
|
||||
console.log(JSON.stringify(test.length))
|
||||
}
|
||||
if (test.length === 5 && (test[3] === "tags" || test[3] === "tag") ) {
|
||||
pageStack.pop(pageStack.find(function(page) {
|
||||
var check = page.isFirstPage === true;
|
||||
|
@ -447,11 +451,11 @@ BackgroundItem {
|
|||
}
|
||||
|
||||
onPressAndHold: {
|
||||
console.log(JSON.stringify(mdl.get(index)))
|
||||
if (debug) console.log(JSON.stringify(mdl.get(index)))
|
||||
mnu.open(delegate)
|
||||
}
|
||||
|
||||
onDoubleClicked: {
|
||||
console.log("double click")
|
||||
if (debug) console.log("double click")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,185 +0,0 @@
|
|||
*Sun Jul 12 2020 molan <mol_an@sunrise.ch> 1.0.7-0
|
||||
- Fix missing / wrong reblog and favourite counts in Retoots (issue #90)
|
||||
- Added full landscape support
|
||||
- Added new Pulley Menu options
|
||||
- Improved Toot context menu
|
||||
- Improved media page
|
||||
- Improved loading indicators
|
||||
- Small changes for some UI-elements
|
||||
- New Emojis
|
||||
- New translated strings
|
||||
|
||||
*Fri Jun 18 2020 molan <mol_an@sunrise.ch> 1.0.6-3
|
||||
- Fix broken reblog indication
|
||||
|
||||
*Fri Jun 18 2020 molan <mol_an@sunrise.ch> 1.0.6-2
|
||||
- Fix reported small UI issue
|
||||
- Updated translations
|
||||
|
||||
*Thu Jun 18 2020 molan <mol_an@sunrise.ch> 1.0.6-1
|
||||
- Fix app crash when open some Profile pages
|
||||
- Fix sometimes missing favourite / reblog counts
|
||||
- Fix various QML warnings, replace deprecated Silica items
|
||||
- Add save to Bookmarks feature
|
||||
- Add Follows you / Locked / Bot / Group labels to Profile Page header
|
||||
- Add Bot icon to user display name
|
||||
- Add clicking on reblog-avatar opens reblog user profile
|
||||
- Remove Locked icon from user display name
|
||||
- Further improved Notification Page / general UI
|
||||
- Code refactoring & other changes under the hood
|
||||
- Translation updates
|
||||
|
||||
*Fri Jun 12 2020 molan <mol_an@sunrise.ch> 1.0.5-1
|
||||
- [hotfix] fix missing images in mentions on Notification page
|
||||
|
||||
*Thu Jun 11 2020 molan <mol_an@sunrise.ch> 1.0.5-0
|
||||
- fixed: show search results without entering # before term
|
||||
- fixed: non-clickable user mentions in Toots
|
||||
- fixed: Copy link to clipboard in Conversations
|
||||
- Notifications Page: Reworked UI and context menus for notifications
|
||||
- Profile Page: Open fullscreen profile image
|
||||
- Profile Page: Show bot label
|
||||
- Profile Page: New expander for Profile details
|
||||
- Conversation Page: Possibility to hide and reopen Toot text field
|
||||
- Conversation Page: Improved display of uploaded images
|
||||
- Media Page: Adjust size of images to screen width or height
|
||||
- Media Page: Only automatically restart videos if shorter than 30 seconds
|
||||
- new Settings Page
|
||||
- bigger custom emojis in Toots
|
||||
- overall improvement of UI
|
||||
|
||||
*Mon May 25 2020 molan <mol_an@sunrise.ch> 1.0.4-3
|
||||
- Show user profile background image (if available)
|
||||
- New Sailfish 3-styled image/video viewer page (WIP)
|
||||
- Added "Toot sent!" notification banner
|
||||
- Show Pulley Menu for copying Toot-link only if link is provided (WIP)
|
||||
- Distiction between "New Toot" and "Conversation" page
|
||||
- some small fixes
|
||||
|
||||
*Mon May 11 2020 molan <mol_an@sunrise.ch> 1.0.4-2
|
||||
- Beta release by molan
|
||||
- Login / Settings Page: Small changes in text wording
|
||||
- Login Page: Use of correct label coloring and text alignment
|
||||
- Login Page: Highlight login confirmation button + 'accept' icon on Sailfish keyboard
|
||||
- Media Page: Switched play / pause buttons during media playback
|
||||
- Conversation Page: Improved alignment of elements in 'New Toot' (no more overlapping)
|
||||
- Settings Page: Replaced icons in Settings page for consistency and clarity
|
||||
- Settings Page: Added missing language contributor
|
||||
- Translations: Completed and fixed German and French translations
|
||||
- Translations: Added complete Italian translation
|
||||
- Translations: Added missing/lost strings and updates to other translation files
|
||||
- Timeline: Better text formatting in toots (show paragraph breaks)
|
||||
- Timeline: Use shortend username if display_name isn't provided in ProfileHeader and MiniHeader
|
||||
- Timeline: Created new placeholder for profile avatars if instance doesn't provide valid image
|
||||
|
||||
* Thu Apr 16 2020 Dusko Angirevic <dysko@me.com> 1.0.4-1
|
||||
- Merge with molan code
|
||||
|
||||
* Tue Feb 04 2020 molan <mol_an@sunrise.ch> 1.0.3-8
|
||||
- Fix for broken translations
|
||||
- Updated Spanish translation
|
||||
|
||||
* Mon Feb 03 2020 molan <mol_an@sunrise.ch> 1.0.3-7
|
||||
- Updated translations for new language strings
|
||||
|
||||
* Thu Jan 30 2020 molan <mol_an@sunrise.ch> 1.0.3-6
|
||||
- Workaround for opening user profiles in toots
|
||||
- Show profile descriptions (Bio) with option to open them in Browser
|
||||
- Updated and improved UI for Conversation page
|
||||
- Indication for sending toot (move back to previous page)
|
||||
- New arrangement of main pages (like used in Mastodon websites and other apps)
|
||||
- Small UI and text/label changes
|
||||
|
||||
* Thu Jan 16 2020 molan <mol_an@sunrise.ch> 1.0.3-5 [fork of Tooter 1.0.3]
|
||||
- Fix for broken profile pages when clicking on usernames in toots
|
||||
- Fixed navigation icons for inverted ambiences
|
||||
- Updated Chinese translation (thanks to dashinfantry)
|
||||
|
||||
* Wed Jan 15 2020 molan <mol_an@sunrise.ch> 1.0.3-4 [fork of Tooter 1.0.3]
|
||||
- Website links in toots now open directly in browser since the web scraper service which was used before is discontinued
|
||||
- Profile page now shows full display name in title instead of user name
|
||||
- Changed send, content warning and add emoji icon in Conversation page for clarification
|
||||
- Small update to Chinese translation (thanks to dashinfantry)
|
||||
- Completed German and French translations
|
||||
|
||||
* Mon Jan 06 2020 molan <mol_an@sunrise.ch> 1.0.3-3 [fork of Tooter 1.0.3]
|
||||
- Update and rename harbour-tooter-zh.ts to harbour-tooter-zh_CN.ts (thanks to dashinfantry)
|
||||
|
||||
* Sat Dec 28 2019 molan <mol_an@sunrise.ch> 1.0.3-1 [fork of Tooter 1.0.3]
|
||||
- Fixed broken Mastodon login (app built with Sailfish SDK 2.4)
|
||||
- Fixed crash on certain notifications
|
||||
|
||||
* Sun Jan 27 2019 Dusko Angirevic <dysko@me.com> 1.0.3-0
|
||||
- Remorse popup added for account removal
|
||||
- Updated translations
|
||||
|
||||
* Tue Jan 15 2019 Dusko Angirevic <dysko@me.com> 1.0.2-0
|
||||
- SailfishOS 3.0 build
|
||||
- Chinese language translation added
|
||||
|
||||
* Fri Oct 26 2018 Dusko Angirevic <dysko@me.com> 0.2.8-0
|
||||
- Fixed conversation bug
|
||||
|
||||
* Thu Oct 25 2018 Dusko Angirevic <dysko@me.com> 0.2.8-0
|
||||
- Fixed localisation issue
|
||||
- Added character counter
|
||||
|
||||
* Tue Oct 23 2018 Dusko Angirevic <dysko@me.com> 0.2.7-0
|
||||
- Added emoji custom support
|
||||
- Bugfix: missing media on boosted toots
|
||||
|
||||
* Thu May 24 2018 Dusko Angirevic <dysko@me.com> 0.2.6-0
|
||||
- Minor bugfix
|
||||
|
||||
* Thu May 24 2018 Dusko Angirevic <dysko@me.com> 0.2.5-0
|
||||
- Added local timeline
|
||||
|
||||
* Thu Nov 02 2017 Dusko Angirevic <dysko@me.com> 0.2.4-0
|
||||
- Updated translations
|
||||
- Added Russian
|
||||
|
||||
* Fri Oct 27 2017 Dusko Angirevic <dysko@me.com> 0.2.3-0
|
||||
- Added User autocomplete options
|
||||
- Added video player options
|
||||
- Smileys are inserted on the cursor position
|
||||
- Pinch to zoom photos
|
||||
- Support for downloading media to the device
|
||||
- Added cover action for new toot
|
||||
|
||||
* Thu Oct 19 2017 Dusko Angirevic <dysko@me.com> 0.2.2-0
|
||||
- Updated translations
|
||||
- Cover page fix for SailfishX
|
||||
- Added Copy URL option
|
||||
- Privacy option in the conversation is now inherited by toot in the thread
|
||||
|
||||
* Tue Oct 10 2017 Dusko Angirevic <dysko@me.com> 0.2.1-0
|
||||
- Added bugs for later (merging branches and contributions)
|
||||
|
||||
* Thu Jul 20 2017 Dusko Angirevic <dysko@me.com> 0.2.0-0
|
||||
- Better tablet displaying
|
||||
- "boosted" notification bugfix
|
||||
- ES lang update by Caballlero
|
||||
|
||||
* Thu Jul 7 2017 Dusko Angirevic <dysko@me.com> 0.1.9-0
|
||||
- Image Upload added [#9]
|
||||
- Emoji pannel added
|
||||
- ES lang update by Carlos Gonzales
|
||||
|
||||
* Tue Jul 4 2017 Dusko Angirevic <dysko@me.com> 0.1.8-0
|
||||
- Added notifications
|
||||
- App Cover redesigned
|
||||
|
||||
* Tue Jul 4 2017 Dusko Angirevic <dysko@me.com> 0.1.7-0
|
||||
- Added spoiler support for toots
|
||||
- Press and hold for boost and favourite option
|
||||
- Updated harbour-tooter-es.ts by Caballlero
|
||||
- Unable to connect to unixcorn.xyz [#12] [bugfix]
|
||||
|
||||
* Tue Jun 20 2017 Dusko Angirevic <dysko@me.com> 0.1.6-1
|
||||
- Hashtag search added
|
||||
- Conversation with sections
|
||||
|
||||
* Mon Jun 19 2017 Dusko Angirevic <dysko@me.com> 0.1.5-1
|
||||
- Autoload older tweets on the list end
|
||||
- Displaying images on the timeline
|
||||
- NSFW support for images
|
|
@ -13,16 +13,18 @@ Name: harbour-tooterb
|
|||
%{!?qtc_make:%define qtc_make make}
|
||||
%{?qtc_builddir:%define _builddir %qtc_builddir}
|
||||
Summary: Tooter β
|
||||
Version: 1.0.8
|
||||
Release: 2
|
||||
Version: 1.1.7
|
||||
Release: 1
|
||||
Group: Qt/Qt
|
||||
License: GPLv3
|
||||
URL: https://grave-design.com/harbour-tooter/
|
||||
URL: https://github.com/poetaster/harbour-tooter#readme
|
||||
Source0: %{name}-%{version}.tar.bz2
|
||||
Source100: harbour-tooterb.yaml
|
||||
Requires: sailfishsilica-qt5 >= 0.10.9
|
||||
Requires: nemo-qml-plugin-configuration-qt5
|
||||
Requires: nemo-qml-plugin-notifications-qt5
|
||||
Requires: pyotherside-qml-plugin-python3-qt5
|
||||
|
||||
BuildRequires: qt5-qttools-linguist
|
||||
BuildRequires: pkgconfig(sailfishapp) >= 1.0.2
|
||||
BuildRequires: pkgconfig(Qt5Core)
|
||||
BuildRequires: pkgconfig(Qt5Qml)
|
||||
|
@ -37,16 +39,16 @@ BuildRequires: desktop-file-utils
|
|||
Tooter Beta is a native client for Mastodon network instances.
|
||||
|
||||
%if "%{?vendor}" == "chum"
|
||||
PackageName: Tooter Beta
|
||||
PackageName: Tooter β
|
||||
Type: desktop-application
|
||||
Categories:
|
||||
- Network
|
||||
PackagerName: Mark Washeim (poetaster)
|
||||
Custom:
|
||||
- Repo: https://github.com/molan-git/harbour-tooter
|
||||
- Repo: https://github.com/poetaster/harbour-tooter
|
||||
Icon: https://raw.githubusercontent.com/poetaster/harbour-tooter/master/icons/256x256/harbour-tooterb.png
|
||||
Url:
|
||||
Homepage: https://github.com/molan-git/harbour-tooter
|
||||
- Bugtracker: https://github.com/poetaster/harbour-tooter/issues
|
||||
%endif
|
||||
|
||||
%prep
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
Name: harbour-tooterb
|
||||
Summary: Tooter β
|
||||
Version: 1.0.8
|
||||
Release: 2
|
||||
# The contents of the Group field should be one of the groups listed here:
|
||||
# https://github.com/mer-tools/spectacle/blob/master/data/GROUPS
|
||||
Group: Qt/Qt
|
||||
URL: http://example.org/
|
||||
License: LICENSE
|
||||
# This must be generated before uploading a package to a remote build service.
|
||||
# Usually this line does not need to be modified.
|
||||
Sources:
|
||||
- '%{name}-%{version}.tar.bz2'
|
||||
Description: |
|
||||
Tooter Beta is a native client for Mastodon network instances.
|
||||
Configure: none
|
||||
# The qtc5 builder inserts macros to allow QtCreator to have fine
|
||||
# control over qmake/make execution
|
||||
Builder: qtc5
|
||||
|
||||
# This section specifies build dependencies that are resolved using pkgconfig.
|
||||
# This is the preferred way of specifying build dependencies for your package.
|
||||
PkgConfigBR:
|
||||
- sailfishapp >= 1.0.2
|
||||
- Qt5Core
|
||||
- Qt5Qml
|
||||
- Qt5Quick
|
||||
- Qt5DBus
|
||||
- Qt5Multimedia
|
||||
#- nemonotifications-qt5 nemo-qml-plugin-notifications-qt5
|
||||
- nemo-qml-plugin-notifications-qt5-devel
|
||||
- openssl
|
||||
|
||||
# Build dependencies without a pkgconfig setup can be listed here
|
||||
# PkgBR:
|
||||
# - qt5-qtmultimedia-plugin-mediaservice-gstmediaplayer
|
||||
|
||||
# Runtime dependencies which are not automatically detected
|
||||
Requires:
|
||||
- sailfishsilica-qt5 >= 0.10.9
|
||||
|
||||
# All installed files
|
||||
Files:
|
||||
- '%{_bindir}'
|
||||
- '%{_datadir}/%{name}'
|
||||
- '%{_datadir}/applications/%{name}.desktop'
|
||||
- '%{_datadir}/icons/hicolor/*/apps/%{name}.png'
|
||||
|
||||
# For more information about yaml and what's supported in Sailfish OS
|
||||
# build system, please see https://wiki.merproject.org/wiki/Spectacle
|
|
@ -25,6 +25,9 @@ ImageUploader::~ImageUploader() {
|
|||
void ImageUploader::setFile(const QString &fileName) {
|
||||
m_fileName = fileName;
|
||||
}
|
||||
void ImageUploader::setMime(const QString &mimeType) {
|
||||
m_mimeType = mimeType;
|
||||
}
|
||||
|
||||
void ImageUploader::setParameters(const QString &album, const QString &title, const QString &description) {
|
||||
//if (!album.isEmpty()) {
|
||||
|
@ -92,7 +95,8 @@ void ImageUploader::upload() {
|
|||
}*/
|
||||
|
||||
//QByteArray fileData = file.readAll().toBase64();
|
||||
imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg"));
|
||||
//imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg"));
|
||||
imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(m_mimeType));
|
||||
imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant(QString("form-data; name=\"file\"; filename=\"%1\"").arg(fileInfo.fileName()).toLatin1()));
|
||||
imagePart.setBodyDevice(file);
|
||||
file->setParent(multiPart);
|
||||
|
|
|
@ -16,6 +16,7 @@ public:
|
|||
~ImageUploader();
|
||||
|
||||
Q_INVOKABLE void setFile(const QString &fileName);
|
||||
Q_INVOKABLE void setMime(const QString &mimeType);
|
||||
Q_INVOKABLE void setAuthorizationHeader(const QString &authorizationHeader);
|
||||
Q_INVOKABLE void setUploadUrl(const QString &userAgent);
|
||||
Q_INVOKABLE void setParameters(const QString &album, const QString &title, const QString &description);
|
||||
|
@ -37,6 +38,7 @@ private:
|
|||
QNetworkAccessManager *m_networkAccessManager;
|
||||
|
||||
QString m_fileName;
|
||||
QString m_mimeType;
|
||||
QByteArray m_authorizationHeader;
|
||||
QString m_uploadUrl;
|
||||
QByteArray postdata;
|
||||
|
|
|
@ -149,6 +149,10 @@
|
|||
<source>New Toot</source>
|
||||
<translation>Neuer Toot</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bookmarks</source>
|
||||
<translation>Lesezeichen</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaFullScreen</name>
|
||||
|
@ -157,6 +161,21 @@
|
|||
<translation>Ladefehler</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaItem</name>
|
||||
<message>
|
||||
<source>Image</source>
|
||||
<translation>Bild</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Video</source>
|
||||
<translation>Video</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PDF document</source>
|
||||
<translation>PDF Dokument</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MiniStatus</name>
|
||||
<message>
|
||||
|
@ -356,6 +375,10 @@
|
|||
<source>to help with app translation to your language.</source>
|
||||
<translation>um bei den Übersetzungen mitzuhelfen.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Development</source>
|
||||
<translation>Entwicklung</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>VisualContainer</name>
|
||||
|
|
|
@ -149,6 +149,10 @@
|
|||
<source>New Toot</source>
|
||||
<translation>Νέος</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bookmarks</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaFullScreen</name>
|
||||
|
@ -157,6 +161,21 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaItem</name>
|
||||
<message>
|
||||
<source>Image</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Video</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PDF document</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MiniStatus</name>
|
||||
<message>
|
||||
|
@ -356,6 +375,10 @@
|
|||
<source>to help with app translation to your language.</source>
|
||||
<translation>για να βοηθήσετε την μετάφραση της εφαρμογής στην γλώσσα σας.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Development</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>VisualContainer</name>
|
||||
|
|
416
translations/harbour-tooterb-en.ts
Normal file
416
translations/harbour-tooterb-en.ts
Normal file
|
@ -0,0 +1,416 @@
|
|||
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="en">
|
||||
<context>
|
||||
<name>API</name>
|
||||
<message>
|
||||
<source>favourited</source>
|
||||
<translation>favourited</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>followed you</source>
|
||||
<translation>followed you</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>boosted</source>
|
||||
<translation>boosted</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>said</source>
|
||||
<translation>said</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ConversationPage</name>
|
||||
<message>
|
||||
<source>Copy Link to Clipboard</source>
|
||||
<extracomment>Use the translation of "Copy Link" for a shorter PullDownMenu label</extracomment>
|
||||
<translation>Copy Link to Clipboard</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Write your warning here</source>
|
||||
<extracomment>placeholderText in Toot content warning panel</extracomment>
|
||||
<translation>Write your warning here</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>What's on your mind?</source>
|
||||
<extracomment>placeholderText in Toot text panel</extracomment>
|
||||
<translation>What's on your mind?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Public</source>
|
||||
<translation>Public</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unlisted</source>
|
||||
<translation>Unlisted</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Followers-only</source>
|
||||
<translation>Followers-only</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Direct</source>
|
||||
<translation>Direct</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Toot sent!</source>
|
||||
<translation>Toot sent!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Reply</source>
|
||||
<extracomment>"Reply" will show the Toot text entry Panel. "Hide Reply" closes it. Alternative: Use "Close Reply"</extracomment>
|
||||
<translation>Reply</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Hide Reply</source>
|
||||
<translation>Hide Reply</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Open in Browser</source>
|
||||
<translation>Open in Browser</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>CoverPage</name>
|
||||
<message>
|
||||
<source>New Toot</source>
|
||||
<translation>New Toot</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>EmojiSelect</name>
|
||||
<message>
|
||||
<source>Emojis</source>
|
||||
<translation>Emojis</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Tap to insert</source>
|
||||
<translation>Tap to insert</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ImageUploader</name>
|
||||
<message>
|
||||
<source>The file %1 does not exists</source>
|
||||
<translation>The file %1 does not exists</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LoginPage</name>
|
||||
<message>
|
||||
<source>Login</source>
|
||||
<translation>Login</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Instance</source>
|
||||
<translation>Instance</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a valid Mastodon instance URL</source>
|
||||
<translation>Enter a valid Mastodon instance URL</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Mastodon is a free, open-source social network. A decentralized alternative to commercial platforms, it avoids the risks of a single company monopolizing your communication. Pick a server that you trust — whichever you choose, you can interact with everyone else. Anyone can run their own Mastodon instance and participate in the social network seamlessly.</source>
|
||||
<translation>Mastodon is a free, open-source social network. A decentralized alternative to commercial platforms, it avoids the risks of a single company monopolizing your communication. Pick a server that you trust — whichever you choose, you can interact with everyone else. Anyone can run their own Mastodon instance and participate in the social network seamlessly.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Reload</source>
|
||||
<translation>Reload</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainPage</name>
|
||||
<message>
|
||||
<source>Home</source>
|
||||
<translation>Home</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Notifications</source>
|
||||
<translation>Notifications</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Local</source>
|
||||
<translation>Local</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Federated</source>
|
||||
<translation>Federated</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search</source>
|
||||
<translation>Search</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>@user or #term</source>
|
||||
<translation>@user or #term</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>New Toot</source>
|
||||
<translation>New Toot</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bookmarks</source>
|
||||
<translation>Bookmarks</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaFullScreen</name>
|
||||
<message>
|
||||
<source>Error loading</source>
|
||||
<translation>Error loading</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaItem</name>
|
||||
<message>
|
||||
<source>Image</source>
|
||||
<translation>Image</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Video</source>
|
||||
<translation>Video</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PDF document</source>
|
||||
<translation>PDF document</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MiniStatus</name>
|
||||
<message>
|
||||
<source>boosted</source>
|
||||
<translation>boosted</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>favourited</source>
|
||||
<translation>favourited</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>followed you</source>
|
||||
<translation>followed you</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MyList</name>
|
||||
<message>
|
||||
<source>Settings</source>
|
||||
<translation>Settings</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>New Toot</source>
|
||||
<translation>New Toot</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Reload</source>
|
||||
<translation>Reload</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Open in Browser</source>
|
||||
<translation>Open in Browser</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Nothing found</source>
|
||||
<translation>Nothing found</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ProfileHeader</name>
|
||||
<message>
|
||||
<source>Bot</source>
|
||||
<translation>Bot</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Follows you</source>
|
||||
<translation>Follows you</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Group</source>
|
||||
<translation>Group</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ProfilePage</name>
|
||||
<message>
|
||||
<source>About</source>
|
||||
<extracomment>If there's no good translation for "About", use "Details" (in details about profile).</extracomment>
|
||||
<translation>About</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Followers</source>
|
||||
<extracomment>Will show as: "35 Followers"</extracomment>
|
||||
<translation>Followers</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Following</source>
|
||||
<extracomment>Will show as: "23 Following"</extracomment>
|
||||
<translation>Following</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Statuses</source>
|
||||
<extracomment>Will show as: "115 Statuses"</extracomment>
|
||||
<translation>Statuses</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Mention</source>
|
||||
<translation>Mention</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unfollow</source>
|
||||
<extracomment>Is a button. Keep it as short as possible.</extracomment>
|
||||
<translation>Unfollow</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Requested</source>
|
||||
<extracomment>Is a button. Keep it as short as possible.</extracomment>
|
||||
<translation>Requested</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Follow</source>
|
||||
<extracomment>Is a button. Keep it as short as possible.</extracomment>
|
||||
<translation>Follow</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unmute</source>
|
||||
<extracomment>Is a button. Keep it as short as possible.</extracomment>
|
||||
<translation>Unmute</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Mute</source>
|
||||
<extracomment>Is a button. Keep it as short as possible.</extracomment>
|
||||
<translation>Mute</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unblock</source>
|
||||
<extracomment>Is a button. Keep it as short as possible.</extracomment>
|
||||
<translation>Unblock</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Block</source>
|
||||
<extracomment>Is a button. Keep it as short as possible.</extracomment>
|
||||
<translation>Block</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>SettingsPage</name>
|
||||
<message>
|
||||
<source>Settings</source>
|
||||
<translation>Settings</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Options</source>
|
||||
<translation>Options</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Load Images in Toots</source>
|
||||
<translation>Load Images in Toots</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Disable this option if you want to preserve your data connection</source>
|
||||
<translation>Disable this option if you want to preserve your data connection</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Account</source>
|
||||
<translation>Account</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Remove Account</source>
|
||||
<translation>Remove Account</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Add Account</source>
|
||||
<translation>Add Account</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Deauthorize this app from using your account and remove account data from phone</source>
|
||||
<translation>Deauthorize this app from using your account and remove account data from phone</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Authorize this app to access your Mastodon account</source>
|
||||
<translation>Authorize this app to access your Mastodon account</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Translate</source>
|
||||
<translation>Translate</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Credits</source>
|
||||
<extracomment>Translation alternative: "Development"</extracomment>
|
||||
<translation>Credits</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>UI/UX design and development</source>
|
||||
<translation>UI/UX design and development</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Visual identity</source>
|
||||
<translation>Visual identity</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Development and translations</source>
|
||||
<translation>Development and translations</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Occitan & French translation</source>
|
||||
<translation>Occitan & French translation</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Chinese translation</source>
|
||||
<translation>Chinese translation</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Dutch translation</source>
|
||||
<translation>Dutch translation</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Spanish translation</source>
|
||||
<translation>Spanish translation</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use</source>
|
||||
<extracomment>Full sentence for translation: "Use Transifex to help with app translation to your language." - The word Transifex is a link and doesn't need translation.</extracomment>
|
||||
<translation>Use</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>to help with app translation to your language.</source>
|
||||
<translation>to help with app translation to your language.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Development</source>
|
||||
<translation>Development</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>VisualContainer</name>
|
||||
<message>
|
||||
<source>Unboost</source>
|
||||
<translation>Unboost</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Boost</source>
|
||||
<translation>Boost</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unfavorite</source>
|
||||
<translation>Unfavourite</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Favorite</source>
|
||||
<translation>Favourite</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Mention</source>
|
||||
<translation>Mention</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Conversation</source>
|
||||
<translation>Conversation</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Remove Bookmark</source>
|
||||
<translation>Remove Bookmark</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bookmark</source>
|
||||
<translation>Bookmark</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
|
@ -149,6 +149,10 @@
|
|||
<source>New Toot</source>
|
||||
<translation>Nuevo toot</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bookmarks</source>
|
||||
<translation>Marcador</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaFullScreen</name>
|
||||
|
@ -157,6 +161,21 @@
|
|||
<translation>Error al cargar</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaItem</name>
|
||||
<message>
|
||||
<source>Image</source>
|
||||
<translation>imagen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Video</source>
|
||||
<translation>video</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PDF document</source>
|
||||
<translation>documento PDF</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MiniStatus</name>
|
||||
<message>
|
||||
|
@ -356,6 +375,10 @@
|
|||
<source>to help with app translation to your language.</source>
|
||||
<translation>para ayudar con traducciones.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Development</source>
|
||||
<translation>Desarrollo</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>VisualContainer</name>
|
||||
|
|
|
@ -149,6 +149,10 @@
|
|||
<source>New Toot</source>
|
||||
<translation>Nouveau pouet</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bookmarks</source>
|
||||
<translation>Marque-page</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaFullScreen</name>
|
||||
|
@ -157,6 +161,21 @@
|
|||
<translation>Erreur au chargement</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaItem</name>
|
||||
<message>
|
||||
<source>Image</source>
|
||||
<translation>image</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Video</source>
|
||||
<translation>vidéo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PDF document</source>
|
||||
<translation>document PDF</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MiniStatus</name>
|
||||
<message>
|
||||
|
@ -356,6 +375,10 @@
|
|||
<source>to help with app translation to your language.</source>
|
||||
<translation>pour aider à traduire cette application.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Development</source>
|
||||
<translation>Développement</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>VisualContainer</name>
|
||||
|
|
|
@ -149,6 +149,10 @@
|
|||
<source>New Toot</source>
|
||||
<translation>Nuovo Toot</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bookmarks</source>
|
||||
<translation>Segnalibro</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaFullScreen</name>
|
||||
|
@ -157,6 +161,21 @@
|
|||
<translation>Errore durante caricamento</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaItem</name>
|
||||
<message>
|
||||
<source>Image</source>
|
||||
<translation>immagine</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Video</source>
|
||||
<translation>video</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PDF document</source>
|
||||
<translation>documento PDF</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MiniStatus</name>
|
||||
<message>
|
||||
|
@ -356,6 +375,10 @@
|
|||
<source>to help with app translation to your language.</source>
|
||||
<translation>per aiutare nella traduzione dell'app.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Development</source>
|
||||
<translation>Sviluppo</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>VisualContainer</name>
|
||||
|
|
|
@ -149,6 +149,10 @@
|
|||
<source>New Toot</source>
|
||||
<translation>Nieuwe Toot</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bookmarks</source>
|
||||
<translation>Bookmarken</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaFullScreen</name>
|
||||
|
@ -157,6 +161,21 @@
|
|||
<translation>Laadfout</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaItem</name>
|
||||
<message>
|
||||
<source>Image</source>
|
||||
<translation>Afbeelding</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Video</source>
|
||||
<translation>Video</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PDF document</source>
|
||||
<translation>PDF document</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MiniStatus</name>
|
||||
<message>
|
||||
|
@ -356,6 +375,10 @@
|
|||
<source>to help with app translation to your language.</source>
|
||||
<translation>om deze app te helpen vertalen in jouw taal.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Development</source>
|
||||
<translation>Ontwikkeling</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>VisualContainer</name>
|
||||
|
|
|
@ -149,6 +149,10 @@
|
|||
<source>New Toot</source>
|
||||
<translation>Nieuwen toot</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bookmarks</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaFullScreen</name>
|
||||
|
@ -157,6 +161,21 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaItem</name>
|
||||
<message>
|
||||
<source>Image</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Video</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PDF document</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MiniStatus</name>
|
||||
<message>
|
||||
|
@ -356,6 +375,10 @@
|
|||
<source>to help with app translation to your language.</source>
|
||||
<translation>voor te helpen met dezen app in uw taal te vertalen.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Development</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>VisualContainer</name>
|
||||
|
|
|
@ -149,6 +149,10 @@
|
|||
<source>New Toot</source>
|
||||
<translation type="unfinished">Nòu Tut</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bookmarks</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaFullScreen</name>
|
||||
|
@ -157,6 +161,21 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaItem</name>
|
||||
<message>
|
||||
<source>Image</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Video</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PDF document</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MiniStatus</name>
|
||||
<message>
|
||||
|
@ -356,6 +375,10 @@
|
|||
<source>to help with app translation to your language.</source>
|
||||
<translation>per ajudar a traduire l’aplicacion dins vòstra lenga.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Development</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>VisualContainer</name>
|
||||
|
|
|
@ -149,6 +149,10 @@
|
|||
<source>New Toot</source>
|
||||
<translation>Nowy wpis</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bookmarks</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaFullScreen</name>
|
||||
|
@ -157,6 +161,21 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaItem</name>
|
||||
<message>
|
||||
<source>Image</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Video</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PDF document</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MiniStatus</name>
|
||||
<message>
|
||||
|
@ -356,6 +375,10 @@
|
|||
<source>to help with app translation to your language.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Development</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>VisualContainer</name>
|
||||
|
|
|
@ -149,6 +149,10 @@
|
|||
<source>New Toot</source>
|
||||
<translation>Новый</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bookmarks</source>
|
||||
<translation>Закладки</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaFullScreen</name>
|
||||
|
@ -157,6 +161,21 @@
|
|||
<translation>Ошибка при загрузке</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaItem</name>
|
||||
<message>
|
||||
<source>Image</source>
|
||||
<translation>Изображение</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Video</source>
|
||||
<translation>Видео</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PDF document</source>
|
||||
<translation>PDF Документ</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MiniStatus</name>
|
||||
<message>
|
||||
|
@ -356,6 +375,10 @@
|
|||
<source>to help with app translation to your language.</source>
|
||||
<translation>чтобы помочь с переводом приложения на ваш язык.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Development</source>
|
||||
<translation>Разработка</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>VisualContainer</name>
|
||||
|
|
|
@ -149,6 +149,10 @@
|
|||
<source>New Toot</source>
|
||||
<translation>Novi toot</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bookmarks</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaFullScreen</name>
|
||||
|
@ -157,6 +161,21 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaItem</name>
|
||||
<message>
|
||||
<source>Image</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Video</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PDF document</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MiniStatus</name>
|
||||
<message>
|
||||
|
@ -356,6 +375,10 @@
|
|||
<source>to help with app translation to your language.</source>
|
||||
<translation>и помозите у преводу апликације на други језик.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Development</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>VisualContainer</name>
|
||||
|
|
|
@ -25,50 +25,50 @@
|
|||
<message>
|
||||
<source>Copy Link to Clipboard</source>
|
||||
<extracomment>Use the translation of "Copy Link" for a shorter PullDownMenu label</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Kopiera länk till urklipp</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Write your warning here</source>
|
||||
<extracomment>placeholderText in Toot content warning panel</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Skriv din varningstext här</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>What's on your mind?</source>
|
||||
<extracomment>placeholderText in Toot text panel</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Vad tänker du på?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Public</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Allmän</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unlisted</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Olistad</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Followers-only</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Endast följare</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Direct</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Direkt</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Toot sent!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Toot skickad!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Reply</source>
|
||||
<extracomment>"Reply" will show the Toot text entry Panel. "Hide Reply" closes it. Alternative: Use "Close Reply"</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Svara</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Hide Reply</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Dölj svar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Open in Browser</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Öppna i webbläsaren</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -104,19 +104,19 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Instance</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Instans</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a valid Mastodon instance URL</source>
|
||||
<translation>Fyll i URL till Mastodoninstans</translation>
|
||||
<translation>Ange en giltig URL till Mastodoninstans</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Mastodon is a free, open-source social network. A decentralized alternative to commercial platforms, it avoids the risks of a single company monopolizing your communication. Pick a server that you trust — whichever you choose, you can interact with everyone else. Anyone can run their own Mastodon instance and participate in the social network seamlessly.</source>
|
||||
<translation>Mastodon är ett fritt och öppet socialt nätverk byggt på öppen källkod. Ett decentraliserat alternativ till kommersiella plattformar, vilket undviker att ett ensamt företag monopoliserar din kommunikation. Välj en server du litar på --- beroende på vilken du väljer, kan du interagera med alla andra. Vem som helst kan köra deras egen Mastodoninstans och delta i nätverket. Även du!</translation>
|
||||
<translation>Mastodon är ett fritt socialt nätverk byggt på öppen källkod. Ett decentraliserat alternativ till kommersiella plattformar. Det undviker riskerna med att ett enda företag monopoliserar din kommunikation. Välj en server som du litar på, oavsett vad du väljer kan du interagera med alla andra. Vem som helst kan köra sin egen Mastodon-instans och delta i det sociala nätverket sömlöst.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Reload</source>
|
||||
<translation type="unfinished">Ladda mer</translation>
|
||||
<translation>Läs in igen</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -149,12 +149,31 @@
|
|||
<source>New Toot</source>
|
||||
<translation>Ny toot</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bookmarks</source>
|
||||
<translation>Bokmärken</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaFullScreen</name>
|
||||
<message>
|
||||
<source>Error loading</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Fel vid inläsning</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaItem</name>
|
||||
<message>
|
||||
<source>Image</source>
|
||||
<translation>Bild</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Video</source>
|
||||
<translation>Video</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PDF document</source>
|
||||
<translation>PDF-dokument</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -184,15 +203,15 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Reload</source>
|
||||
<translation>Ladda mer</translation>
|
||||
<translation>Läs in igen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Open in Browser</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Öppna i webbläsaren</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Nothing found</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Inget hittades</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -203,11 +222,11 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Follows you</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Följer dig</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Group</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Grupp</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -215,7 +234,7 @@
|
|||
<message>
|
||||
<source>About</source>
|
||||
<extracomment>If there's no good translation for "About", use "Details" (in details about profile).</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Om</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Followers</source>
|
||||
|
@ -230,11 +249,11 @@
|
|||
<message>
|
||||
<source>Statuses</source>
|
||||
<extracomment>Will show as: "115 Statuses"</extracomment>
|
||||
<translation>Statusar</translation>
|
||||
<translation>Status</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Mention</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Omnämnande</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unfollow</source>
|
||||
|
@ -244,7 +263,7 @@
|
|||
<message>
|
||||
<source>Requested</source>
|
||||
<extracomment>Is a button. Keep it as short as possible.</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Efterfrågad</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Follow</source>
|
||||
|
@ -254,7 +273,7 @@
|
|||
<message>
|
||||
<source>Unmute</source>
|
||||
<extracomment>Is a button. Keep it as short as possible.</extracomment>
|
||||
<translation>Avtysta</translation>
|
||||
<translation>Frigör</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Mute</source>
|
||||
|
@ -280,15 +299,15 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Options</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Alternativ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Load Images in Toots</source>
|
||||
<translation>Ladda bilder i toots</translation>
|
||||
<translation>Läs in bilder i tootar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Disable this option if you want to preserve your data connection</source>
|
||||
<translation>Inaktivera det här alternativet om du vill behålla din dataanslutning</translation>
|
||||
<translation>Inaktivera det här alternativet om du vill bevara din dataanslutning</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Account</source>
|
||||
|
@ -296,7 +315,7 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Remove Account</source>
|
||||
<translation>Radera konto</translation>
|
||||
<translation>Ta bort konto</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Add Account</source>
|
||||
|
@ -304,11 +323,11 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Deauthorize this app from using your account and remove account data from phone</source>
|
||||
<translation>Avauktorisera denna app och radera ditt konto</translation>
|
||||
<translation>Avauktorisera denna app och ta bort din kontodata från telefonen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Authorize this app to access your Mastodon account</source>
|
||||
<translation>Godkänn denna app att använda ditt Mastodon-konto på dina vägnar</translation>
|
||||
<translation>Auktorisera denna app att använda ditt Mastodon-konto</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Translate</source>
|
||||
|
@ -325,27 +344,27 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Visual identity</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Visuell identitet</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Development and translations</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Utveckling och översättningar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Occitan & French translation</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Occitan & Fransk översättning</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Chinese translation</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Kinesisk översättning</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Dutch translation</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Nederländsk översättning</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Spanish translation</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Spansk översättning</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use</source>
|
||||
|
@ -354,7 +373,11 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>to help with app translation to your language.</source>
|
||||
<translation>för att hjälpa med app-översättningar till ditt språk.</translation>
|
||||
<translation>för att hjälpa till med app-översättning till ditt språk.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Development</source>
|
||||
<translation>Utveckling</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -377,19 +400,19 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Mention</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Omnämnande</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Conversation</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Konversation</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Remove Bookmark</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Ta bort bokmärke</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bookmark</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Bokmärk</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
|
|
@ -149,6 +149,10 @@
|
|||
<source>New Toot</source>
|
||||
<translation>新嘟嘟</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bookmarks</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaFullScreen</name>
|
||||
|
@ -157,6 +161,21 @@
|
|||
<translation>加载错误</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaItem</name>
|
||||
<message>
|
||||
<source>Image</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Video</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PDF document</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MiniStatus</name>
|
||||
<message>
|
||||
|
@ -356,6 +375,10 @@
|
|||
<source>to help with app translation to your language.</source>
|
||||
<translation>以帮助翻译软件为你使用的语言.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Development</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>VisualContainer</name>
|
||||
|
|
|
@ -149,6 +149,10 @@
|
|||
<source>New Toot</source>
|
||||
<translation>New Toot</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bookmarks</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaFullScreen</name>
|
||||
|
@ -157,6 +161,21 @@
|
|||
<translation>Error loading</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MediaItem</name>
|
||||
<message>
|
||||
<source>Image</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Video</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PDF document</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MiniStatus</name>
|
||||
<message>
|
||||
|
@ -356,6 +375,10 @@
|
|||
<source>to help with app translation to your language.</source>
|
||||
<translation>to help with app translation to your language.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Development</source>
|
||||
<translation>Development</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>VisualContainer</name>
|
||||
|
|
Loading…
Reference in a new issue