Commit Graph

4246 Commits

Author SHA1 Message Date
Nik Clayton 0fe84f1611
refactor: Use Date type for scheduled post date / times (#1032)
Previous code accepted the `scheduledAt` value as a String, and kept it
as a String (including when serialising as part of a draft). Then it was
converted to an actual Date for display.

Refactor to keep it as a Date for as long as possible. Moshi decodes
Dates correctly over the network, and the database is configured to
serialise Dates as Longs.

This necessitates two migration steps to preserve any existing
`scheduledAt` values for drafts. The first step adds a new column to
store the date as a Long and copies over existing data. The second step
replaces the old column with the new column.
2024-10-20 16:29:32 +02:00
Nik Clayton a43ebab69b
feat: Add "Don't ask again" option when confirming the posting language (#1027)
For some users this feature has too many false positives, particularly
when emojis are used.

Provide a preference that enables/disables the feature, default to
"enable".

When the user is prompted the dialog has a third "Don't ask again"
option. If chosen the preference is set to prevent future prompts and
the status is sent as-is.

Fixes #893
2024-10-18 17:26:50 +02:00
Nik Clayton c8aa4fd374
fix: Disable "Scheduled post" support on GoToSocial accounts (#1025)
GoToSocial servers don't support scheduled posts; they return the wrong
type, and this can cause a loop of posting.

The GoToSocial bug to implement scheduled posts is
https://github.com/superseriousbusiness/gotosocial/issues/1006.

Fix this by adding a new server capability for scheduled post support,
using it for most servers, and disabling it for GoToSocial.

If scheduled post support is not available for an account:

- The "Scheduled posts" menu option is not shown.
- The scheduling button (clock) when composing a post is hidden, so the
user cannot set scheduling parameters.

Fixes #963
2024-10-18 15:37:10 +02:00
Nik Clayton 8fac5c3d4d
fix: Don't clip buttons when choosing scheduled post time (#1024)
The MaterialTimePicker library has a bug that results in the "Cancel"
and "Ok" buttons on the dialog being cut off.

See
https://github.com/material-components/material-components-android/issues/3584

Work around this by updating their layout params and explicitly setting
the "bottomToBottom" constraint to their parent.
2024-10-18 15:13:17 +02:00
Nik Clayton a5c8bf5e7e
fix: Remove the "Liimt timeline notifications" preference (#1009)
This wasn't acting as a preference.

It presented as a switch. If the user toggled it some notification
settings were changed for all accounts.

It wasn't clear what was changed, and if the user changed some of those
settings back the switch position did not change (it couldn't, you
couldn't meaningfully represent a partial change using a single switch).

Since the user has full control over the notification filters on a
per-account basis remove this "preference" to reduce confusion.

Fixes #935
2024-10-17 22:09:22 +02:00
Nik Clayton 1b3b78a9dd
refactor: Pass pachliAccountId to more functions (#1008)
While this isn't used in many places yet, it pushes the places where the
active account is referenced further up the call stack.
2024-10-17 21:19:17 +02:00
Nik Clayton fd9cc2ea96
refactor: Improve saveVisibleId log message (#1003) 2024-10-14 17:21:04 +02:00
Nik Clayton f7c87dfe73
refactor: Use pachliAccountId in EditProfileActivity (#1002)
Pass the value to EditProfileViewModel. It's not used yet, but this
minimises diffs an upcoming large refactor.
2024-10-14 16:39:45 +02:00
mondstern 2c75be8936 fix(l10n): Update Ukrainian translations
Currently translated at 100.0% (2 of 2 strings)

Translation: Pachli/App : Fdroid
Translate-URL: https://hosted.weblate.org/projects/pachli/app-fdroid/uk/
2024-10-12 20:49:52 +02:00
Weblate (bot) 0cf50524f2
fix(l10n): Translations update from Hosted Weblate (#995)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for [Pachli/Fastlane
Metadata](https://hosted.weblate.org/projects/pachli/fastlane-metadata/).


It also includes following components:

* [Pachli/App :
Main](https://hosted.weblate.org/projects/pachli/app-main/)

* [Pachli/App :
Fdroid](https://hosted.weblate.org/projects/pachli/app-fdroid/)

*
[Pachli/Feature/Login](https://hosted.weblate.org/projects/pachli/featurelogin/)

* [Pachli/Feature/Suggestions :
Main](https://hosted.weblate.org/projects/pachli/featuresuggestions-main/)

* [Pachli/Feature/Lists :
Main](https://hosted.weblate.org/projects/pachli/featurelists-main/)

* [Pachli/Core/Ui :
Main](https://hosted.weblate.org/projects/pachli/coreui-main/)

* [Pachli/App :
Google](https://hosted.weblate.org/projects/pachli/app-google/)

* [Pachli/Core/Designsystem :
Main](https://hosted.weblate.org/projects/pachli/coredesignsystem-main/)

* [Pachli/Core/Data :
Main](https://hosted.weblate.org/projects/pachli/coredata-main/)

* [Pachli/Core/Activity :
Main](https://hosted.weblate.org/projects/pachli/coreactivity-main/)

* [Pachli/Feature/About :
Main](https://hosted.weblate.org/projects/pachli/featureabout-main/)

* [Pachli/Core/Preferences :
Main](https://hosted.weblate.org/projects/pachli/corepreferences-main/)

* [Pachli/Core/Activity :
Orange](https://hosted.weblate.org/projects/pachli/coreactivity-orange/)

* [Pachli/Core/Network :
Main](https://hosted.weblate.org/projects/pachli/corenetwork-main/)



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/pachli/fastlane-metadata/horizontal-auto.svg)

---------

Co-authored-by: Vaclovas Intas <vaclovas1999@gmail.com>
Co-authored-by: Languages add-on <noreply-addon-languages@weblate.org>
Co-authored-by: Weblate Translation Memory <noreply-mt-weblate-translation-memory@weblate.org>
Co-authored-by: LibreTranslate <noreply-mt-libretranslate@weblate.org>
2024-10-10 21:42:59 +02:00
Nik Clayton a4e9c563e9
fix: Prevent crash when ModuleInstall.API is unavailable (#997)
Seen the following crash in user reports:

```
com.google.android.gms.common.api.ApiException: 17:
  API: ModuleInstall.API is not available on this device.
  Connection failed with:
  ConnectionResult{statusCode=SERVICE_INVALID, resolution=null, message=null}
```

Doesn't appear to be properly documented anywhere I can find. To work
around this catch exceptions when checking for MLKit modules or
installing them and return defaults.
2024-10-10 20:44:06 +02:00
Nik Clayton 23121459ab
refactor: Implement SharedPreferencesRepository.showSelfUsername property (#996) 2024-10-10 20:15:46 +02:00
Nik Clayton fd0957d829
fix: Parse and restore poll when editing scheduled statuses (#994)
Previous code didn't deserialise the "poll" attribute so it was never
passed to the composer when editing scheduled statuses.

Fixes #991
2024-10-10 19:43:48 +02:00
Nik Clayton f3b11d0e81
refactor: Lazy load preferences to prevent crash (#993)
Without this the values are loaded from sharedPreferencesRepository
before the variable is initialised.
2024-10-10 15:14:51 +02:00
Nik Clayton e307796251
refactor: Provide properties for more shared preferences (#992)
Continues the work of providing properties with accessors for specific
shared preferences.
2024-10-10 13:12:56 +02:00
Nik Clayton 8587fafaa8
refactor: Expose main navigation preference as an enum (#988) 2024-10-08 15:30:56 +02:00
Nik Clayton 59a0e3087c
refactor: Pass the active account ID to activities, fragments, etc (#982)
Previous code assumed the active account could always be determined from
the account manager.

This causes a few problems.

1. The account manager has to handle the case where there is no active
account (e.g., the user is logging out of the last account). This meant
the `activeAccount` property had to be nullable, so every consumer of
that property either used it with a `let` or `!!` expression.

2. The active account can change over the life of the UI component, for
example, when the user is switching accounts. There's a theoretical race
condition where the UI component has started an operation for one
account, then the account changes and the network authentication code
uses the new account.

3. All operations assume they operate on whatever the active account is,
making it difficult to provide any features that allow the user to
temporarily operate as another account ("Boost as...", etc).

This "ambient account" was effectively global mutable state, with all
the problems that can cause.

Start to fix this. The changes in this commit do not fix the problem
completely, but they are some progress.

Each activity (except LoginActivity) is expected to be launched with an
intent that includes the ID of the Pachli account it defaults to
operating with. This is `pachliAccountId`, and is the *database ID*
(not the server ID) of the account. This is non-null, which removes one
class of bugs.

This account is passed to each fragment and any piece of code that has
to perform an operation on behalf of this account. It's not used in
most of those places yet, that will be done over a number of followup
PRs as part of modernising each module.
2024-10-07 15:56:37 +02:00
Nik Clayton 668c073822
refactor: Assorted code inspection cleanups (#985)
Code inspection found some mechanical code cleanups.
2024-10-07 12:38:35 +02:00
Nik Clayton ea635d654e
refactor: Rename ListActivityIntent to ListsActivityIntent (#984)
Since the activity it launches is called `ListsActivity`.
2024-10-07 12:33:42 +02:00
Kalle Kniivilä aaf88b4ac3 fix(l10n): Update Finnish translations
Currently translated at 100.0% (728 of 728 strings)

Translation: Pachli/App : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/app-main/fi/
2024-10-06 19:08:25 +02:00
--//-- 268b042a95 fix(l10n): Update Burmese translations
Currently translated at 14.1% (103 of 728 strings)

Translation: Pachli/App : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/app-main/my/
2024-10-06 19:08:25 +02:00
--//-- f6370d6385 fix(l10n): Update Burmese translations
Currently translated at 0.4% (3 of 728 strings)

Translation: Pachli/App : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/app-main/my/
2024-10-06 19:08:25 +02:00
--//-- 8d41a03668 fix(l10n): Update Burmese translations
Currently translated at 0.4% (3 of 728 strings)

Translation: Pachli/App : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/app-main/my/
2024-10-06 19:08:25 +02:00
--//-- 4c59a5bace fix(l10n): Update Burmese translations
Currently translated at 0.1% (1 of 728 strings)

Translation: Pachli/App : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/app-main/my/
2024-10-06 19:08:25 +02:00
Languages add-on c966fbd83a feat(l10n): Added Burmese translation 2024-10-06 19:08:25 +02:00
Languages add-on f52fe63272 feat(l10n): Added Burmese translation 2024-10-06 19:08:25 +02:00
--//-- 34db06d980 feat(l10n): Added Burmese translation 2024-10-06 19:08:25 +02:00
Juan M Sevilla 23ac1c04d2 fix(l10n): Update Spanish translations
Currently translated at 100.0% (728 of 728 strings)

Translation: Pachli/App : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/app-main/es/
2024-10-06 19:08:25 +02:00
Nik Clayton 1c861ee906
chore(i18n): Add Burmese ("my") language code (#981) 2024-10-06 18:47:57 +02:00
Nik Clayton 65c73625f6
refactor: Create V2 filters with one API call (#979)
Previous code didn't encode v2 filter keywords, so created v2 filters by
first creating the filter with no keywords (one API call) then making
1-N API calls to add each keyword to the filter.

Fix this by adding a dedicated converter for the `NewContentFilter` type
that encodes it correctly so the filter can be created with a single API
call.

This necessitates moving some types around,
2024-10-05 14:53:23 +02:00
Nik Clayton ec27aa2435
fix: Don't crash if a conversation has no participants (#978)
It's possible for some servers to return a conversation that has an
empty (or possibly missing) `accounts` property. In the previous code
this would crash trying to access an item in an empty list.

Fix this by handling the "no participants" case.

Fixes #971
2024-10-04 11:28:20 +02:00
Nik Clayton 0d5d118267
refactor: Move AccountManager to core.data.repository (#976) 2024-10-03 21:28:01 +02:00
Kalle Kniivilä 0c2cda1a14 fix(l10n): Update Finnish translations
Currently translated at 100.0% (727 of 727 strings)

Translation: Pachli/App : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/app-main/fi/
2024-10-03 15:07:42 +02:00
Nik Clayton fe1c586dae
refactor: Move ServerOperation and related types to core.model (#969) 2024-10-03 13:41:46 +02:00
Nik Clayton ea53b68b3f
refactor: Rename LogoutUseCase, call with invoke. (#968) 2024-10-03 12:53:57 +02:00
Nik Clayton 03cb6c313e
refactor: Start splitting Notification helpers in to use cases (#967)
Move enableNotifications and androidNotificationsAreEnabled to usecases.
2024-10-03 12:11:20 +02:00
Nik Clayton 4b3b275c97
refactor: Rename variables and functions in MainActivity (#966)
Rename some variables and functions in MainActivity to more accurately
or consistently reflect what they do.
2024-10-02 23:48:20 +02:00
Weblate (bot) 33726431e8
fix(l10n): Translations update from Hosted Weblate (#962)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for [Pachli/Fastlane
Metadata](https://hosted.weblate.org/projects/pachli/fastlane-metadata/).


It also includes following components:

* [Pachli/Feature/About :
Main](https://hosted.weblate.org/projects/pachli/featureabout-main/)

* [Pachli/Core/Activity :
Main](https://hosted.weblate.org/projects/pachli/coreactivity-main/)

* [Pachli/Core/Designsystem :
Main](https://hosted.weblate.org/projects/pachli/coredesignsystem-main/)

* [Pachli/Core/Data :
Main](https://hosted.weblate.org/projects/pachli/coredata-main/)

* [Pachli/App :
Main](https://hosted.weblate.org/projects/pachli/app-main/)

*
[Pachli/Feature/Login](https://hosted.weblate.org/projects/pachli/featurelogin/)

* [Pachli/App :
Google](https://hosted.weblate.org/projects/pachli/app-google/)

* [Pachli/App :
Fdroid](https://hosted.weblate.org/projects/pachli/app-fdroid/)

* [Pachli/Core/Activity :
Orange](https://hosted.weblate.org/projects/pachli/coreactivity-orange/)

* [Pachli/Core/Preferences :
Main](https://hosted.weblate.org/projects/pachli/corepreferences-main/)

* [Pachli/Core/Network :
Main](https://hosted.weblate.org/projects/pachli/corenetwork-main/)

* [Pachli/Feature/Suggestions :
Main](https://hosted.weblate.org/projects/pachli/featuresuggestions-main/)

* [Pachli/Feature/Lists :
Main](https://hosted.weblate.org/projects/pachli/featurelists-main/)

* [Pachli/Core/Ui :
Main](https://hosted.weblate.org/projects/pachli/coreui-main/)



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/pachli/fastlane-metadata/horizontal-auto.svg)

---------

Co-authored-by: LibreTranslate <noreply-mt-libretranslate@weblate.org>
Co-authored-by: nichu42 <nroediger@nic-site.de>
Co-authored-by: Nik Clayton <nik@ngo.org.uk>
2024-10-02 23:19:34 +02:00
Nik Clayton 510717d46a
refactor: Rename "Filters" to "Content filters" (#927)
The new anti-harassment features will add several different types of
filtering options through the UI.

To ensure there is no confusion, rename the existing "Filters" UI and
code to "Content filters" to accurately describe what they operate on,
distinct from new filters which will act on account metadata.

Fixes #926.
2024-10-02 22:57:00 +02:00
Nik Clayton f9ca3cd700
chore: Prepare release 2.8.2 (versionCode 22) (#960) 2024-09-30 15:21:52 +02:00
Nik Clayton fd29987cd1
refactor: Move tab-tap preference to labs (#958)
Allows user feedback on this before promoting to a main feature.
2024-09-30 14:57:17 +02:00
Nik Clayton 97558667c8
feat: Allow the user to chose behaviour when tapping a tab (#955)
Previously, tapping a tab would jump to the top of the loaded content,
which might trigger a load of a fresh page.

Provide a preference to control this; the default is the current
behaviour, the user can also choose to discard the current content and
load the newest content.

Fixes #939
2024-09-27 17:38:15 +02:00
Nik Clayton 90537da122
feat: Add option to download media to per-sender directories (#954)
Update `DownloadUrlUseCase` with a parameter to specify the account that
"owns" the media. This is either the account that posted the status, or
the account being viewed (e.g., if downloading an account's header
image).

Add a new `DownloadLocation` enum constant to download to directories
named after that account.

Pass this information through at the call sites.

Fixes #938
2024-09-27 11:29:34 +02:00
Nik Clayton c30a2ea137
refactor: Implement AppTheme with PreferenceEnum (#951)
Provde an `appTheme` property in `SharedPreferenceRepository` to manage
read access, simplifying calling code.

Update `PreferenceEnum.from` to check the `value` property of the enum
first.

Fixes #950
2024-09-26 22:54:42 +02:00
Nik Clayton 85ab714ec1
feat: Add option to save attachments to per-account folders (#945)
The existing code downloaded any attachments to the user's "Downloads"
folder. If the user is logged in with several accounts these downloads
will be mixed up together.

Fix this by adding a new preference that allows the user to specify the
downloads should be placed in a sub-folder per account, named after the
account.

To do this:

- Add an interface for enums that can be used as preferences, with
properties for the string resource to display and the value to store.
- Add `EnumListPreference`, a `ListPreference` that allows the user to
choose between different enum values.
- Add a `DownloadLocation` enum and preference key so the user can
choose the location.
- Add a `core.domain` module, with a use case for downloading URLs that
respect's the user's download preference. Use this use-case everywhere
that files are currently downloaded.

Fixes #938
2024-09-26 13:51:30 +02:00
Nik Clayton 3f9ee1d9c8
fix: Show notification fetch errors instead of JSON (#942)
Previous code showed any JSON-wrapped errors from notification fetches
as the JSON string, instead of the error message.

Fix this by switching to `ApiResult` and using the formatted error
message.

Fixes 937
2024-09-25 13:49:43 +02:00
Nik Clayton 561c26ad4d
fix: Save the reading position if no post is fully visible (#941)
Previous code saved the reading position of a fully visible status. But
there are situations where no status is fully visible.

1. The user is in the middle of viewing a status longer than the screen
height, and the top/bottom of the status are off the top/bottom of the
screen.

2. The user has scrolled between two statuses. Collectively they are
longer than the screen height, and the top of one status is off the top
of the screen and the bottom of the other status is off the bottom of
the screen.

In both cases the user's reading position was not saved.

In these situations use the ID of the status closest to the bottom of
the screen, even if not fully visible. This should ensure the user never
missing anything.

Fixes #936
2024-09-25 11:45:33 +02:00
renovate[bot] 494246097d
fix(deps): update dependency com.github.unifiedpush:android-connector to v2.5.0 (#915)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
|
[com.github.UnifiedPush:android-connector](https://unifiedpush.org/developers/android/)
([source](https://codeberg.org/UnifiedPush/android-connector)) | `2.4.0`
-> `2.5.0` |
[![age](https://developer.mend.io/api/mc/badges/age/maven/com.github.UnifiedPush:android-connector/2.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/com.github.UnifiedPush:android-connector/2.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/com.github.UnifiedPush:android-connector/2.4.0/2.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/com.github.UnifiedPush:android-connector/2.4.0/2.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

> [!WARNING]
> Some dependencies could not be looked up. Check the Dependency
Dashboard for more information.

---

### Release Notes

<details>
<summary>UnifiedPush/android-connector
(com.github.UnifiedPush:android-connector)</summary>

###
[`v2.5.0`](https://codeberg.org/UnifiedPush/android-connector/releases/tag/2.5.0)

[Compare
Source](https://codeberg.org/UnifiedPush/android-connector/compare/2.4.0...2.5.0)

- Avoid possible desynchronization that let the app use the token of a
removed instance
- Deprecate `registerAppWithDialog` in favor of the new lib
`org.unifiedpush.android:connector-ui`
- Drop toolchains in favor of compatibility API, removing requirement of
Java version to build project
-   Bump dependencies

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/pachli/pachli-android).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOC41Ni4wIiwidXBkYXRlZEluVmVyIjoiMzguODAuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Nik Clayton <nik@ngo.org.uk>
2024-09-25 11:20:58 +02:00
Weblate (bot) 5505180868
fix(l10n): Translations update from Hosted Weblate (#933)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for [Pachli/Fastlane
Metadata](https://hosted.weblate.org/projects/pachli/fastlane-metadata/).


It also includes following components:

* [Pachli/Core/Activity :
Main](https://hosted.weblate.org/projects/pachli/coreactivity-main/)

* [Pachli/App :
Google](https://hosted.weblate.org/projects/pachli/app-google/)

* [Pachli/Feature/Suggestions :
Main](https://hosted.weblate.org/projects/pachli/featuresuggestions-main/)

* [Pachli/Core/Designsystem :
Main](https://hosted.weblate.org/projects/pachli/coredesignsystem-main/)

* [Pachli/Core/Network :
Main](https://hosted.weblate.org/projects/pachli/corenetwork-main/)

*
[Pachli/Feature/Login](https://hosted.weblate.org/projects/pachli/featurelogin/)

* [Pachli/Core/Ui :
Main](https://hosted.weblate.org/projects/pachli/coreui-main/)

* [Pachli/Core/Activity :
Orange](https://hosted.weblate.org/projects/pachli/coreactivity-orange/)

* [Pachli/Feature/About :
Main](https://hosted.weblate.org/projects/pachli/featureabout-main/)

* [Pachli/Core/Data :
Main](https://hosted.weblate.org/projects/pachli/coredata-main/)

* [Pachli/App :
Main](https://hosted.weblate.org/projects/pachli/app-main/)

* [Pachli/App :
Fdroid](https://hosted.weblate.org/projects/pachli/app-fdroid/)

* [Pachli/Feature/Lists :
Main](https://hosted.weblate.org/projects/pachli/featurelists-main/)



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/pachli/fastlane-metadata/horizontal-auto.svg)

---------

Co-authored-by: sunniva <schildkroteskoldpadda@gmail.com>
Co-authored-by: LibreTranslate <noreply-mt-libretranslate@weblate.org>
Co-authored-by: ButterflyOfFire <boffire@users.noreply.hosted.weblate.org>
2024-09-20 15:53:28 +02:00
Nik Clayton aec657d49a
refactor: Use ApiResult for requests that return lists of accounts (#932)
Previous code used `Response`. Convert to `ApiResult` as part of the
work to implement anti-harassment controls, which will need to query the
user's list of accounts they are following.

Converting just `accountFollowing` wasn't practical, as all the methods
are called by a single function in `AccountListFragment` which expects
the return type to be the same.
2024-09-09 13:12:26 +02:00