Mini app for Telegram Mini App Contest. Application allow to split bills between users.
How it works:
- User open mini app and can create new "Room" or select existing one. After creation or selecting user see "Room" page.
- On "Room" page user can invite another users to split bills with them.
- On room page user can add "Splits" (Transactions) and split them between selected users
- On room page user see all "Splits" and able to remove them.
- On room page user can click "Summary" button and check how much money users should send to each other.
Mini app created using Vue.js as frontend framework and CakePHP 5 for backend PrimeVue is used as components library.
This documentation contains general information about developing Telegram Mini App using VueJs and PrimeVue. Without diving into application logic. This project show how to interact with some of twa-dev/SDK properties like user information, Telegram client theme colors, saving and accessing data in CloudStorage. For easy testing there are defined some variables that are used if we do not used telegram client to launch mini app!.
To work with telegram api used twa-dev/SDK. It allows to easy access to Telegram properties such as user information, user color palette and to interact with native Telegram application.
twa-dev/SDK gives access to WebApp
object which is stored in Vuex store src/store/store.js
, to easy access to object in components.
src/store/store.js
also implements API communication with backend.
To save data in CloudStorage:
WebApp.CloudStorage.setItem('token', TOKEN);
To access data
WebApp.CloudStorage.getItem('token', (err, token) => { });
!!! FOR SOME REASON ON MACOS I DO NOT RECEIVE CALLBACK HERE
getItem method has callback function as second parameter where we can access data (or got error)
When user open application first time application sends information about user to backend, save user information in database and return token for next user authentication. This token is stored in WebApp.CloudStorage
for latter usage. (This is not the best solution of authentication as token is not refreshed, this should be changed letter).
With each API call we send X-TOKEN
in headers for user authentication.
To get user information WebApp.initDataUnsafe.user
property.
When user open application with room shared link, it contains room_id
in WebApp.initDataUnsafe.start_param
So we cant assign user to that room if such parameter exists. (room_id
is not secure should be used some token for room identification)
const tryToLinkToRoom = () => {
const linkToRoom = WebApp.initDataUnsafe.start_param ?? null;
if (linkToRoom) {
fetch(API_ENDPOINT + '/rooms/link.json', patchHeaders({
method: 'POST',
body: JSON.stringify({room_id: linkToRoom})
})).then(() => store.dispatch('fetchRooms').then(()=>{
router.push('/room/' + linkToRoom);
}));
}
}
src/main.js
entry point of application. Here we initialize VueJs application and used components.
src/Home.vue
is a Main component of application. In this component we use Vue Router to easy navigation between application pages. Also in this component we set app css variable according to user Telegram application colors.
Telegram application colors are fetched from WebApp.themeParams
. This object has properties like bg_color
, secondary_bg_color
, text_color
, hint_color
, link_color
, button_color
, button_text_color
which are saved as css variables and used in this project. Basing on these colors we can easily create new ones in same color palette with adding some opacity to these colors.
PrimeVue allow as to use Tailwind css framework for styling components.
Primary colors should be defined in tailwind.config.js
to use them in project.
In this project used custom styles for some PrimeVue components.
For that src/tailwind-custom.js
was created to separate styles setting from other logic. This configuration is imported in src/main.js
and used as option to PrimeVue initialisation .use(PrimeVue, { pt: CustomTailwind })
More about styling you can find in PrimeVue Tailwind documentation
For navigation between application pages Vue Router is used.
Routes are configured in src/routes.js
this application has simple route for two pages
const routes = [
{ path: '/:catchAll(.*)', component: AllSplitsList },
{ path: '/room/:id', component: Room },
]
Every path that is not room/:id
redirects to main page with selecting or creating "Rooms"
Using VueJs and VuePrime components allow us to easy and fast application developing
npm install
npm run dev
npm run build
Lint with ESLint
npm run lint